00001 /*
00002 File: List.cc
00003
00004 Function: See header file
00005
00006 Author(s): Andrew Willmott
00007
00008 Copyright: (c) 1995-2000, A. Willmott
00009
00010 Notes:
00011 */
00012
00013 #include "cl/List.h"
00014 #include <iostream.h>
00015
00016
00017 // --- Simple linked list methods ---------------------------------------------
00018
00019 Void List::Prepend(List list)
00020 {
00021 list.Append(SELF);
00022 first = list.first;
00023 }
00024
00025 Void List::Append(List list)
00026 {
00027 if (list.first != 0)
00028 {
00029 // this is just an unrolled version of:
00030 // if (isEmpty) SELF = list; else tail.Append(list);
00031 if (IsEmpty())
00032 SELF = list;
00033 else
00034 {
00035 List t;
00036 for(t = SELF; !t.Tail().IsEmpty(); t = t.Tail())
00037 ;
00038 t.Tail() = list;
00039 }
00040 }
00041 }
00042
00043 Void List::Append(Node *node)
00044 {
00045 List t;
00046 t.first = node;
00047 node->next = 0;
00048 Append(t);
00049 }
00050
00051 Void List::Free()
00052 {
00053 if (first)
00054 {
00055 first->FreeAfter();
00056 delete first;
00057 first = 0;
00058 }
00059 }
00060
00061 List List::Clone()
00062 {
00063 List result;
00064
00065 result.first = first->CloneList();
00066
00067 return(result);
00068 }
00069
00070 Int List::NumItems()
00071 // ain't recursion wonderful
00072 {
00073 if (IsEmpty())
00074 return(0);
00075 else
00076 return(1 + Tail().NumItems());
00077 }
00078
00079 // --- single-link Node methods -----------------------------------------------
00080
00081
00082 Node *Node::Clone()
00083 {
00084 return(new Node(SELF));
00085 }
00086
00087 Node *Node::CloneList()
00088 {
00089 Node *t = Clone();
00090
00091 if (next)
00092 t->next = next->CloneList();
00093 else
00094 t->next = 0;
00095
00096 return(t);
00097 };
00098
00099 Void Node::FreeAfter()
00100 {
00101 if (next)
00102 {
00103 next->FreeAfter();
00104 delete next;
00105 next = 0;
00106 }
00107 }
00108
00109
00110 // --- Double-link node methods -----------------------------------------------
00111
00112
00113 DblNode *DblNode::CloneAfter()
00114 {
00115 if (!next) return(next);
00116
00117 DblNode *result = next->Clone();
00118
00119 result->next = next->CloneAfter();
00120 result->next->prev = result;
00121
00122 return(result);
00123 }
00124
00125 DblNode *DblNode::CloneBefore()
00126 {
00127 if (!prev) return(prev);
00128
00129 DblNode *result = prev->Clone();
00130
00131 result->prev = prev->CloneBefore();
00132 result->prev->next = result;
00133
00134 return(result);
00135 }
00136
00137 DblNode *DblNode::CloneList()
00138 {
00139 DblNode *result = Clone();
00140
00141 result->next = CloneAfter();
00142 result->prev = CloneBefore();
00143
00144 return(result);
00145 }
00146
00147 Void DblNode::FreeAfter()
00148 {
00149 next->FreeAfter();
00150 delete next;
00151 }
00152
00153 Void DblNode::FreeBefore()
00154 {
00155 prev->FreeBefore();
00156 delete prev;
00157 }
00158
00159
00160 // --- Test code --------------------------------------------------------------
00161
00162
00163 #ifdef TEST
00164
00165 class iNode : public Node
00166 {
00167 public:
00168 iNode(int i) : data(i), Node() {};
00169 iNode() : Node() {};
00170 int data;
00171 Node *Clone() {return(new iNode(data));};
00172 };
00173
00174 class iDNode : public DblNode
00175 {
00176 public:
00177 iDNode(int i) : data(i), DblNode() {};
00178 iDNode() : DblNode() {};
00179 int data;
00180 DblNode *Clone() {return(new iDNode(data));};
00181 };
00182
00183 ostream &operator << (ostream &s, iNode &i)
00184 {
00185 s << i.data;
00186 return(s);
00187 }
00188
00189 class fNode : public Node
00190 {
00191 public:
00192 fNode(float i) : data(i), Node() {};
00193 fNode() : Node() {};
00194 float data;
00195 Node *Clone() {return(new fNode(data));};
00196 };
00197
00198 ostream &operator << (ostream &s, fNode &i)
00199 {
00200 s << i.data;
00201 return(s);
00202 }
00203
00204 Void ListTest()
00205 {
00206 TypedList<iNode> myList;
00207 TypedList<iNode> t;
00208 TypedList<fNode> myFList;
00209 Iter<iNode> iter;
00210 Iter<fNode> fIter;
00211
00212 myList.Prepend(new iNode(1));
00213 myList.Prepend(new iNode(2));
00214 myList.Prepend(new iNode(3));
00215 myList.Prepend(new iNode(4));
00216 myList.Prepend(new iNode(5));
00217
00218 cout << myList << endl;
00219
00220 myList.DeleteFirst();
00221 myList.Tail().Tail().DeleteFirst();
00222
00223 cout << "0: " << myList << endl;
00224
00225 iter.Begin(myList);
00226 iter.Inc();
00227 iter.InsertAfter(new iNode(33));
00228
00229 cout << "1: " << myList << endl;
00230
00231 iter.Inc();
00232 iter.Delete();
00233
00234 cout << "2: " << myList << endl;
00235
00236 iter.InsertBefore(new iNode(-3));
00237
00238 cout << "3: " << myList << endl;
00239
00240 // cloning etc.
00241
00242 TypedList<iNode> list2;
00243
00244 list2.Prepend(myList.Clone());
00245 cout << "b: " << list2 << endl;
00246 list2.Append(myList.DisconnectFirst());
00247
00248 cout << "a: " << myList << endl;
00249 cout << "b: " << list2 << endl;
00250
00251 // polymorphic list
00252
00253 myFList.Prepend((TypedList<fNode> &) myList);
00254 myFList.Append(new fNode(1));
00255 myFList.Append(new fNode(2));
00256 myFList.Append(new fNode(3));
00257 myFList.Append(new fNode(4));
00258 myFList.Append(new fNode(5));
00259
00260 int i = 0;
00261
00262 for (fIter.Begin(myFList); !fIter.AtEnd(); fIter.Inc(), i++)
00263 if (i < 3)
00264 cout << ((iNode &) fIter.Data()).data << endl;
00265 else
00266 cout << fIter.Data() << endl;
00267 }
00268
00269 Void DblListTest()
00270 {
00271 iDNode *list, *list2;
00272 DblIter<iDNode> i;
00273
00274 list = new iDNode(20);
00275 i.Begin(list);
00276 list->InsertAfter(new iDNode(24));
00277 list->InsertAfter(new iDNode(23));
00278 list->InsertAfter(new iDNode(22));
00279 list->InsertAfter(new iDNode(21));
00280 i.Inc();
00281 i.Inc();
00282 i.Inc();
00283 i.Inc();
00284 i.Data().InsertAfter(new iDNode(30));
00285 i.Inc();
00286 i.Data().InsertAfter(new iDNode(31));
00287 i.Inc();
00288 i.Data().InsertAfter(new iDNode(32));
00289 i.Inc();
00290 list2 = (iDNode *) &i.Data();
00291
00292 for (i.Begin(list); !i.AtEnd(); i.Inc())
00293 cout << i.Data().data << endl;
00294
00295 cout << "--------------" << endl;
00296
00297 for (i.Begin(list2); !i.AtEnd(); i.Dec())
00298 cout << i.Data().data << endl;
00299
00300 list2 = (iDNode *) list->next->next->CloneList();
00301
00302 for (i.Begin(list); !i.AtEnd(); i.Inc())
00303 i.Data().data += 10;
00304
00305 cout << "--------------" << endl;
00306
00307 for (i.Begin(list2); !i.AtEnd(); i.Inc())
00308 cout << i.Data().data << endl;
00309
00310 cout << "--------------" << endl;
00311
00312 for (i.Begin(list2); !i.AtEnd(); i.Dec())
00313 cout << i.Data().data << endl;
00314
00315
00316 }
00317
00318 int main(int argc, char **argv)
00319 {
00320 ListTest();
00321 return(0);
00322 }
00323 #endif
00324