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