Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

List.h

Go to the documentation of this file.
00001 /*
00002     File:           List.h
00003     
00004     Function:       Provides linked list primitives.
00005 
00006     Author(s):      Andrew Willmott
00007 
00008     Copyright:      (c) 1995-2000, Andrew Willmott
00009  */
00010 
00011 #ifndef __List__
00012 #define __List__
00013 
00014 #include "cl/Basics.h"
00015 
00016 
00017 // --- Simple Linked List ---------------------------------------------------
00018 
00019 
00020 //  A node in the list.
00021 
00022 class Node
00023 {
00024 public:
00025     Node    *next;          // Next item in the list
00026     
00027     Node() : next(0) {};
00028 
00029     Void            InsertAfter(Node *node) { node->next = next; next = node;};
00030 
00031     Void            FreeAfter();
00032     
00033     virtual Node    *Clone();
00034     Node            *CloneList();
00035 };
00036 
00037 
00038 // A list : essentially a (Node *) with associated methods. Imitates 
00039 // Lisp/Prolog lists, in that it has head & tail methods. Has pointer
00040 // semantics: you must call Clone() to copy it, and Free() to delete it. 
00041 
00042 class List
00043 {
00044 public:
00045     Node        *first;     // Pointer to the first node in the list.
00046     
00047                 List() : first(0) {};
00048     
00049     Bool        IsEmpty()   { return first == 0; };
00050     Node        &Head()     { return *first; };
00051     List        &Tail()     { return (List &) first->next; };
00052     
00053     Void        Prepend(Node *node)
00054                 { node->next = first; first = node; };
00055     Void        Prepend(List list);
00056     Void        Append(Node *node);
00057     Void        Append(List list);
00058     
00059     Void        Free();
00060     List        Clone();
00061 
00062     Void        DeleteFirst()
00063                 { Node *t = first; first = first->next; delete t; }; 
00064     Node        *DisconnectFirst()
00065                 { Node *t = first; first = first->next; return(t); }; 
00066 
00067     Int         NumItems();
00068 };
00069 
00070 template <class T> 
00071     class TypedList : public List
00072 {
00073 public:
00074     T               &Head()     { return (T &) *first; };
00075     TypedList<T>    &Tail()     { return (TypedList<T> &) first->next; };
00076 };
00077 
00078 template <class T> ostream &operator << (ostream &s, TypedList<T> list);
00079 
00080 //  Associated iterator. 
00081 
00082 template <class T> class Iter
00083 {
00084 public:
00085     List    *cursor;
00086     
00087     Void    Begin(List &list)
00088             { cursor = &list; };
00089     Void    Inc()                   
00090             { Assert(!cursor->IsEmpty(), "Moved past end of list");
00091             cursor = (List *) cursor->first; };
00092                                             
00093     Bool    AtEnd()
00094             { return cursor->first == 0; };
00095     T       &Data()
00096             { return (T &) cursor->Head(); };
00097     
00098     Void    Delete()
00099             { cursor->DeleteFirst();};
00100     Void    InsertBefore(Node *node)
00101             { cursor->Prepend(node); cursor = (List *) cursor->first;};
00102     Void    InsertAfter(Node *node)
00103             { cursor->Tail().Prepend(node);};
00104 };
00105 
00106 
00107 // --- Doubly-linked list -----------------------------------------------------
00108 
00109 
00110 class DblNode
00111 {
00112 public:
00113     DblNode *prev;          // Previous item in the list
00114     DblNode *next;          // Next item in the list
00115     
00116     DblNode() : prev(0), next(0) {};
00117 
00118     Void            InsertAfter(DblNode *node)
00119                     { 
00120                         node->next = next; 
00121                         node->prev = this; 
00122                         if (next) next->prev = node; 
00123                         next = node; 
00124                     };
00125     Void            InsertBefore(DblNode *node)
00126                     { 
00127                         node->next = this; 
00128                         node->prev = prev;
00129                         if (prev) prev->next = node; 
00130                         prev = node;
00131                     };
00132     Void            Delete()
00133                     { delete Disconnect(); };
00134     DblNode         *Disconnect()
00135                     { 
00136                         if (prev) prev->next = next; 
00137                         if (next) next->prev = prev; 
00138                         return(this);
00139                     };
00140     
00141     Bool            AtStart()       { return(prev == 0); };
00142     Bool            AtEnd()         { return(next == 0); };
00143 
00144     Void            FreeAfter();
00145     Void            FreeBefore();
00146     Void            FreeList()      { FreeAfter(); FreeBefore(); delete this; }
00147     
00148     virtual DblNode *Clone()        { return new DblNode(SELF); };
00149     
00150     DblNode         *CloneAfter();
00151     DblNode         *CloneBefore();
00152     DblNode         *CloneList();
00153 };
00154 
00155 // Associated iterator
00156 
00157 template <class T> class DblIter
00158 {
00159 public:
00160     DblNode *cursor;
00161     
00162     Void    Begin(DblNode *list)    { cursor = list; };
00163     Void    Inc()
00164             { Assert(!cursor->AtEnd(), "Moved past end of list");
00165             cursor = cursor->next; };
00166     Void    Dec()
00167             { Assert(!cursor->AtStart(), "Moved past end of list");
00168             cursor = cursor->prev; };
00169                                             
00170     Bool    AtEnd()                 { return cursor == 0; };
00171     
00172     T       &Data()                 { return (T &) *cursor; };
00173     
00174     Void    Delete()
00175             { DblNode *t = cursor; cursor->Delete(); cursor = t;};
00176     Void    InsertBefore(DblNode *node)
00177             { cursor->InsertBefore(node); };
00178     Void    InsertAfter(DblNode *node)
00179             { cursor->InsertAfter(node); };
00180 };
00181 
00182 
00183 // --- Templated functions ----------------------------------------------------
00184 
00185 template <class T> 
00186     ostream &operator << (ostream &s, TypedList<T> list)
00187 {
00188     s << "(";
00189     
00190     if (!list.IsEmpty())
00191     {
00192         s << list.Head();
00193         list = list.Tail();
00194 
00195         while (!list.IsEmpty())
00196         {
00197             s << " " << list.Head();
00198             list = list.Tail();
00199         }
00200     }
00201         
00202     s << ")";
00203     return(s);
00204 };
00205 
00206 
00207 #endif

Generated at Sat Aug 5 00:16:32 2000 for Class Library by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000