// File: genlist2.h
//
// A generic list class using templates

#ifndef _genlist_h
#define _genlist_h


// TYPE must support
//    assignment operator
//    copy constructor
//    comparison operators: < <= == >= > !=
//    I/O operator: <<

template <class TYPE>
class ListCell{

public:
   ListCell *next ;                     // next cell on the list
   TYPE data ;                          // data stored in this cell 

   ListCell() : next(NULL) {}           // constructors
   ListCell(const TYPE& t)
      : next(NULL), data(t) {}
} ;


template <class TYPE>
class GenList {

public:
   GenList() ;                          // constructor
   ~GenList() ;                         // destructor

   GenList(GenList&) ;
   GenList& operator=(const GenList&) ;

   void append(const TYPE&) ;           // Add item to end of list
   void prepend(const TYPE&) ;          // Add item to front of list

   TYPE chop() ;                        // Remove & return first item
   void print() const ;                 // Print the entire list
   void remove(const TYPE&) ;           // Remove every item with given key

   inline TYPE begin() const ;          // Return item at the front
   inline TYPE end() const ;            // Return item at the end
   inline int length() const ;          // Return number of items in list

protected:
   ListCell<TYPE> dummy ;               // dummy ListCell (not pointer!)
   ListCell<TYPE> *last ;               // last item in the list
   int len ;                            // number of items in the list

   enum {clean = 0, dirty} ;
   int cache_status ;                   // clean or dirty
} ;


//========================================================================
// GenList inline functions
//

template <class TYPE>
inline TYPE GenList<TYPE>::begin() const {
   TYPE t ; // default value

   if (dummy.next == NULL) return t ;
   return dummy.next->data ;
}

template <class TYPE>
inline TYPE GenList<TYPE>::end() const {
   TYPE t ; // default value

   if (last == &dummy) return t ;
   return last->data ;
}

template <class TYPE>
inline int GenList<TYPE>::length() const {
   return len ;
}

#endif
