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