//-----------------------------------------------------------------------------
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//
//-----------------------------------------------------------------------------
// 
// Description:
//	 Single Linked List for pointers void *
//
//       Note: remove and clean operations on the list
//             will only remove link nodes without removal of
//             the content inside the nodes. It is callers' 
//             responsiblity to clean up those contents
//
//       This is unsafe C++ practice, use this list at you own risk
//       
//       Reason for this list: It is very difficult to instantiate
//       a template class in a stand alone shared library
//	
// Author:  Jie Chen
//       CEBAF Data Acquisition Group
//
// Revision History:
//   cdevSlist.h,v
// Revision 1.2  1996/11/21  17:03:09  akers
// Ongoing Developement of CDEV 1.5
//
// Revision 1.1  1995/06/30  15:08:00  chen
// single linked list for void *
//
//
#ifndef _CDEV_SLIST_H
#define _CDEV_SLIST_H

#include <cdevSpec.h>
#include <assert.h>

typedef void*  cdevSlistItem;

//======================================================================
//	class cdevGenSlist
//        Single Linked List for void* pointer
//======================================================================
class cdevSlistLink;
class cdevSlistIterator;
class cdevSlistCursor;

class CDEV_CLASS_SPEC cdevSlist
{
public:
  // constructors
  cdevSlist (void);
  cdevSlist (const cdevSlist & source);
  virtual                  ~cdevSlist (void);

  // operations

  // add list item to the beginning of the list
  virtual void             add(cdevSlistItem value);

  // remove a list item from the list
  // return 0: nothing to remove
  // return 1: remove success
  virtual int              remove (cdevSlistItem value);

  // clean up the list. 
  virtual void             deleteAllValues();

  // return first element of the list
  virtual cdevSlistItem    firstElement() const;

  // return last element of the list
  virtual cdevSlistItem    lastElement() const;

  // duplicate ths whole list
  virtual cdevSlist*       duplicate() const;
  
  // check whether this list contains a particular item
  // return 1: yes. return 0: no
  virtual int              includes(cdevSlistItem value) const;

  // Is list empty
  // return 1: yes. return 0: no
  virtual int              isEmpty() const;

  // remove first element of the list
  virtual void             removeFirst();

  // return number of elements inside the list
  virtual int              count() const;

 protected:
  // data field
  cdevSlistLink*           ptrToFirstLink;

  // friends
  friend class  cdevSlistIterator;
  // cannot modify list in anyways
  friend class  cdevSlistCursor;
};

//======================================================================
//	class cdevSlistLink
//        Single linked list link node
//======================================================================
class CDEV_CLASS_SPEC cdevSlistLink
{
 public:
  // insert a new element following the current value
  cdevSlistLink*     insert (cdevSlistItem val);

 private:
  // constructor
  cdevSlistLink (cdevSlistItem linkValue, cdevSlistLink * nextPtr);

  // duplicate
  cdevSlistLink*     duplicate (void);

  // data areas
  cdevSlistItem      value;
  cdevSlistLink*     ptrToNextLink;

  // friends
  friend class       cdevSlist;
  friend class       cdevSlistIterator;
  friend class       cdevSlistCursor;
};

//===================================================================
//	class cdevSlistIterator
//		implements iterator protocol for linked lists
//		also permits removal and addition of elements
//===================================================================
class CDEV_CLASS_SPEC cdevSlistIterator
{
public:
  // constructor
  cdevSlistIterator        (cdevSlist& aList);

  // iterator protocol
  virtual int              init (void);
  virtual cdevSlistItem    operator () (void);
  virtual int              operator !  (void);
  virtual int              operator ++ (void);
  virtual void             operator =  (cdevSlistItem value);

  // new methods specific to list iterators

  // remove current item pointed by the iterator from the list
  void                     removeCurrent(void);
  
  // add an item to the list before the position pointed by the iterator
  void                     addBefore(cdevSlistItem  newValue);

  // add an item to the list after the position pointed by the iterator
  void                     addAfter(cdevSlistItem   newValue);

  // search an item and move the iterator to that position
  int                      searchSame(cdevSlistItem &value);

protected:
  // data areas
  cdevSlistLink *    currentLink;
  cdevSlistLink *    previousLink;
  cdevSlist&         theList;
};

//===================================================================
//	class cdevSlistCursor
//		implements cursor protocol for linked lists
//===================================================================
class CDEV_CLASS_SPEC cdevSlistCursor
{
public:
  // constructor
  cdevSlistCursor           (const cdevSlist& aList);

  // iterator protocol
  virtual int               init        (void);
  virtual cdevSlistItem     operator () (void);
  virtual int               operator !  (void);
  virtual int               operator ++ (void);
  virtual void              operator =  (cdevSlistItem value);

  int                       searchSame  (cdevSlistItem &value);

 protected:
  // data areas
  cdevSlistLink *           currentLink;
  cdevSlistLink *           previousLink;
  const cdevSlist&          theList;
};

//======================================================================
//      class doubleEndedList
//           Not only keeps a pointer to first node
//           but also keeps a pointer to last node
//======================================================================
class CDEV_CLASS_SPEC cdevDoubleEndedSlist: public cdevSlist{
 public:
  //constructor
  cdevDoubleEndedSlist   (void);
  cdevDoubleEndedSlist   (const cdevDoubleEndedSlist &v);
  
  // override the following methods from the cdevSlist
  virtual void      add             (cdevSlistItem value);
  virtual void      deleteAllValues (void);
  virtual void      removeFirst     (void);

  // add new element to the end of the list
  virtual void      addToEnd        (cdevSlistItem value);

 protected:
  cdevSlistLink    *ptrToLastLink;
};
#endif






