// This may look like C code, but it is really -*- C++ -*-

//<copyright>
// 
// Copyright (c) 1993-1995
// Institute for Information Processing and Computer Supported New Media (IICM),
// Graz University of Technology, Austria.
// 
//</copyright>

//<file>
//
// Name:       list.h
//
// Purpose:    Double linked list
//
// Created:     1 Oct 91    Gerald Pani
//
// Description:
//
// Double linked list and macros for generic double linked list
//
//</file>
//
// $Id: list.h,v 1.5 1996/03/20 14:51:39 tvollmer Exp $
//
// $Log: list.h,v $
// Revision 1.5  1996/03/20 14:51:39  tvollmer
// *** empty log message ***
//
// Revision 1.4  1996/03/20 14:17:57  tvollmer
// *** empty log message ***
//
// Revision 1.3  1996/03/20 12:49:21  tvollmer
// *** empty log message ***
//
// Revision 1.2  1995/12/19 10:14:45  gpani
// + copy constructor and assigment operator (DLListNode, DLList)
//

#ifndef hg_utils_list_h
#define hg_utils_list_h

#include <generic.h>
#include "types.h"
// version control (tvollmer)
extern int class_list_version_1_2;
static int class_list_version = class_list_version_1_2;


//<class>
//
// Name:       DLListNode
//
// Purpose:    Base class for all DLListNodes
//
//
// Public Interface:
//
// - DLListNode()
//   Default constructor. Sets up a DLListNode with no next and no previous.
//
// - virtual ~DLListNode()
//   Destructor. Deletes ALL storage used by the DLListNode.
//
// - virtual boolean operator <( DLListNode& n)
//   Returns false by default.
//
//
// Description:
//
// 
//</class>

class DLListNode {
public:
   DLListNode();     
   virtual ~DLListNode() {};
   
   virtual boolean operator <( DLListNode&) { return false; };
   DLListNode* getNextNode() { return next_; };
   DLListNode* getPrevNode() { return prev_; };
   
private:
   DLListNode( const DLListNode&);
   DLListNode& operator=( const DLListNode&);
private:
   DLListNode* next_;
   DLListNode* prev_;
   friend class DLList;
};

inline DLListNode::DLListNode() { 
     next_ = nil;
     prev_ = nil;

}

//<class>
//
// Name:       DLList
//
// Purpose:    Base class for all DLLists
//
//
// Public Interface:
//
// - DLList()
//   Default constructor. Sets up an empty list.
//
// - ~DLList()
//   Destructor. Deletes ALL storage used by the DLList and calls 
//   ~DLListNode for all nodes in the list.
//
// - void free()
//   Removes all nodes of the list and calls ~DLListNode for each of them.
//
// - void addHead( DLListNode* node)
//   Inserts node at the head of the list.
//
// - void addTail( DLListNode* node)
//   Inserts node at the tail of the list.
//
// - void insertBefore( DLListNode* ins, DLListNode* bef)
//   Inserts ins before bef.
//
// - void insertAfter( DLListNode* ins, DLListNode* aft)
//   Inserts ins after aft.
//
// - void insertAt( DLListNode* ins, int pos)
//   Inserts ins at position pos.
//
// - DLListNode* removeHead()
//   Removes the first node of the list and returns a pointer to it.
//   If the list is empty, the returned value is nil.
//
// - DLListNode* removeTail()
//   Removes the last node of the list and returns a pointer to it.
//   If the list is empty, the returned value is nil.
//
// - void remove( DLListNode* n)
//   Removes the node n from the list.
//
// - DLListNode* getFirst()
//   Returns a pointer to the first node or nil if the list is empty.
//
// - DLListNode* getLast()
//   Returns a pointer to the last node or nil if the list is empty.
//
// - DLListNode* getNext( DLListNode* n)
//   Returns a pointer to the successor of n or nil if there isn't any.
//
// - DLListNode* getPrev( DLListNode* n)
//   Returns a pointer to the predecessor of n or nil if there isn't
//   any.
//
// - DLListNode* operator []( int i)
//   Returns a pointer to the node at position i or nil if position
//   isn't valid. 
//
// - int count() const
//   Returns the number of nodes in the list.
//
// - void sort()
//   Heapsort of the list, using DLListNode::operator<().
//
// - const DLListNode* first() const
//   Returns a constant pointer to the first node or nil if the list
//   is empty. 
//
// - const DLListNode* next( const DLListNode* n) const
//   Returns a constant pointer to the successor of n or nil if there
//   isn't any. 
//
//
// Description:
//
// 
//</class>

class DLList {
   DLListNode head_;
   DLListNode tail_;
   int count_;
public:
   DLList();
   ~DLList();
   void free();
   void addHead( DLListNode*); 
   void addTail( DLListNode*);
   void insertBefore( DLListNode* ins, DLListNode* bef);
   void insertAfter( DLListNode* ins, DLListNode* aft);
   void insertAt( DLListNode* ins, int pos);
   DLListNode* removeHead();
   DLListNode* removeTail();
   void remove( DLListNode* n);
   DLListNode* getFirst();
   DLListNode* getLast();
   DLListNode* getNext( DLListNode* n);
   DLListNode* getPrev( DLListNode* n);
   DLListNode* operator []( int i);
   int count() const;
   void sort();
   const DLListNode* first() const;
   const DLListNode* last() const;
   const DLListNode* next( const DLListNode* n) const;
   const DLListNode* prev( const DLListNode* n) const;        
private:
   DLList( const DLList&);
   DLList& operator=( const DLList&);
};

inline int DLList::count() const {
     return count_;
}

inline DLListNode* DLList::getFirst() {
     return (head_.next_->next_) ? (head_.next_) : (nil);
}

inline const DLListNode* DLList::first() const {
     return (head_.next_->next_) ? (head_.next_) : (nil);
}

inline const DLListNode* DLList::last() const {
     return (tail_.prev_->prev_) ? (tail_.prev_) : nil;
}


inline DLListNode* DLList::getPrev(DLListNode* n) {
     return (n->prev_->prev_) ? (n->prev_) : nil;
}

inline DLListNode* DLList::getLast() {
     return (tail_.prev_->prev_) ? (tail_.prev_) : nil;
}

inline DLListNode* DLList::getNext(DLListNode* n) {
     return (n->next_->next_) ? (n->next_) : nil;
}

inline const DLListNode* DLList::prev(const DLListNode* n) const {
     return (n->prev_->prev_) ? (n->prev_) : nil;
}


inline const DLListNode* DLList::next(const DLListNode* n) const {
     return (n->next_->next_) ? (n->next_) : nil;
}

inline DLList::~DLList() {
     free();
}

//<class>
//
// Name:       GenDLList
//
// Purpose:    Generic DLList
//
//
// Public Interface:
//
// - GenDLListNode* removeHead()
//   Removes the first node of the list and returns a pointer to it.
//   If the list is empty, the returned value is nil.
//
// - GenDLListNode* removeTail()
//   Removes the last node of the list and returns a pointer to it.
//   If the list is empty, the returned value is nil.
//
// - GenDLListNode* getFirst()
//   Returns a pointer to the first node or nil if the list is empty.
//
// - GenDLListNode* getLast()
//   Returns a pointer to the last node or nil if the list is empty.
//
// - GenDLListNode* getNext( DLListNode* n)
//   Returns a pointer to the successor of n or nil if there isn't any.
//
// - GenDLListNode* getPrev( DLListNode* n)
//   Returns a pointer to the predecessor of n or nil if there isn't
//   any.
//
// - GenDLListNode* operator []( int i)
//   Returns a pointer to the node at position i or nil if position
//   isn't valid. 
//
// - const GenDLListNode* first() const
//   Returns a constant pointer to the first node or nil if the list
//   is empty. 
//
// - const GenDLListNode* next( const DLListNode* n) const
//   Returns a constant pointer to the successor of n or nil if there
//   isn't any. 
//
//
// Description:
// No casting of returned pointers is necessary.
//
// 
//</class>

#define DLListdeclare(GenDLList,GenDLListNode)				      \
class GenDLList : public DLList {					      \
  public:								      \
     GenDLListNode* removeHead();					      \
     GenDLListNode* removeTail();					      \
     GenDLListNode* getFirst();					      \
     GenDLListNode* getLast();						      \
     GenDLListNode* getNext( DLListNode* n);				      \
     GenDLListNode* getPrev( DLListNode* n);				      \
     GenDLListNode* operator [](int i);				      \
     const GenDLListNode* first() const;				      \
     const GenDLListNode* last()  const;                              \
     const GenDLListNode* next( const DLListNode* n) const;		      \
     const GenDLListNode* prev( const DLListNode* n)  const;                  \
};									      \
									      \
inline GenDLListNode* GenDLList::getFirst() {				      \
     return (GenDLListNode*)(DLList::getFirst());			      \
}									      \
									      \
inline const GenDLListNode* GenDLList::first() const {			      \
     return (const GenDLListNode*)(DLList::first());			      \
}									      \
                                                                              \
inline const GenDLListNode* GenDLList::last() const {                         \
     return (GenDLListNode*)(DLList::last());                                 \
}                                                                             \
									      \
inline GenDLListNode* GenDLList::getPrev( DLListNode* n) {		      \
     return (GenDLListNode*)(DLList::getPrev( n));			      \
}									      \
									      \
inline GenDLListNode* GenDLList::getLast() {				      \
     return (GenDLListNode*)(DLList::getLast());			      \
}									      \
									      \
inline GenDLListNode* GenDLList::getNext( DLListNode* n) {		      \
     return (GenDLListNode*)(DLList::getNext( n));			      \
}									      \
									      \
inline const GenDLListNode* GenDLList::next( const DLListNode* n) const {     \
     return (const GenDLListNode*)(DLList::next( n));			      \
}									      \
                                                                              \
inline const GenDLListNode* GenDLList::prev(const DLListNode* n) const {      \
     return (const GenDLListNode*)(DLList::prev(n));                          \
}                                                                             \
									      \
inline GenDLListNode* GenDLList::removeHead() {			              \
     return (GenDLListNode*)(DLList::removeHead());			      \
}									      \
									      \
inline GenDLListNode* GenDLList::removeTail() {				      \
     return (GenDLListNode*)(DLList::removeTail());			      \
}									      \
									      \
inline GenDLListNode* GenDLList::operator []( int i) {			      \
     return (GenDLListNode*)(DLList::operator[]( i));			      \
}

#endif





