00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00026 #ifndef __LinkedList_h
00027 #define __LinkedList_h
00028
00029 #ifdef __GNUC__
00030 #pragma interface
00031 #endif
00032
00033 #ifdef NON_ANSI
00034 #include <iostream.h>
00035 #else
00036 #include <iostream>
00037 using namespace std;
00038 #endif
00039
00040 #ifndef ANSI_HDRS
00041 #include <stdlib.h>
00042 #include <stddef.h>
00043 #else
00044 #include <cstdlib>
00045 #include <cstddef>
00046 #endif
00047
00048 #include "errmsg.h"
00049
00050 #include "_generic.h"
00051
00052 template <class T>
00053 class UTILIB_API LinkedList;
00054
00055
00056
00066 template <class T>
00067 class UTILIB_API ListItem {
00068
00069 friend class LinkedList<T>;
00070
00071 public:
00072
00074 ListItem( T& Data_)
00075 : Data(Data_) {next = prev = 0;}
00076
00078 T& data()
00079 {return Data;}
00081 int operator==(const ListItem<T>& item)
00082 {return (Data == item.Data);}
00083
00085 static void delete_unused();
00086
00087 protected:
00088
00090 T Data;
00092 ListItem *next;
00094 ListItem *prev;
00095
00097 static ListItem* unused;
00098
00100 void *operator new(size_t);
00102 void operator delete(void*, size_t);
00103
00104 };
00105
00106
00107
00108 template <class T>
00109 class UTILIB_API LinkedList
00110 {
00111 protected:
00112
00114 enum {
00115 stackLL = 0,
00116 queueLL = 1
00117 };
00118
00119 public:
00120
00122 LinkedList()
00123 { mode=queueLL; counter++; first = last = 0; Len=0; }
00124
00130 virtual ~LinkedList();
00131
00137 ListItem<T>* find( T& data);
00139 ListItem<T>* head() const
00140 {return first;}
00142 ListItem<T>* tail() const
00143 {return last;}
00145 ListItem<T>* next(ListItem<T>* item) const
00146 {return item->next;}
00147
00149 T& top()
00150 {
00151 if (Len <= 0) {
00152 ErrAbort("LinkedList::top -- Empty list");
00153 exit(0);
00154 }
00155 if (mode == queueLL) return first->data();
00156 return last->data();
00157 }
00159 void add( T& data)
00160 { insert(data); }
00162 void add( T& data, ListItem<T>*& item)
00163 { item = insert(data); }
00169 ListItem<T>* insert( T& data, ListItem<T>* item = (ListItem<T>*)0);
00170
00172 void remove( T& data)
00173 {
00174 if (mode==queueLL)
00175 extract(first,data);
00176 else
00177 extract(last,data);
00178 }
00180 void remove( ListItem<T>* item)
00181 {extract(item);}
00183 void remove(ListItem<T>* item, T& data)
00184 {extract(item,data);}
00185
00187 int empty() const;
00189 operator int() const
00190 {return (first == 0 ? FALSE : TRUE);}
00192 int size() const
00193 {return Len;}
00195 int len() const
00196 {return Len;}
00198 void stack_mode()
00199 {mode = stackLL;}
00201 void queue_mode()
00202 {mode = queueLL;}
00203
00204 protected:
00205
00207 int mode;
00209 void extract(ListItem<T>* item);
00211 void extract(ListItem<T>* item, T& data)
00212 {data = item->Data; extract(item);}
00213
00215 ListItem<T> *first;
00217 ListItem<T> *last;
00219 int Len;
00220
00222 static int counter;
00223
00224 };
00225
00226
00227 template <class T>
00228 inline UTILIB_API LinkedList<T>& operator>>(LinkedList<T>& list, T& data)
00229 {list.remove(data); return list;}
00230
00231 template <class T>
00232 inline UTILIB_API LinkedList<T>& operator<<(LinkedList<T>& list, T& data)
00233 {list.add(data); return list;}
00234
00235
00236
00237
00238
00239
00240
00241 template <class T>
00242 ListItem<T> *ListItem<T>::unused = NULL;
00243
00244
00245 template <class T>
00246 void ListItem<T>::delete_unused()
00247 {
00248 ListItem<T> *curr = unused;
00249 ListItem<T> *next;
00250
00251 while (curr) {
00252 next = curr->next;
00253 char* tmp = (char*) curr;
00254 delete [] tmp;
00255 curr = next;
00256 }
00257
00258 unused=NULL;
00259 }
00260
00261
00262 template <class T>
00263 void* ListItem<T>::operator new(size_t size)
00264 {
00265 if (!unused)
00266 return new char[size];
00267 else {
00268 ListItem<T> *ptr = unused;
00269 unused = unused->next;
00270 return ptr;
00271 }
00272 }
00273
00274
00275 template <class T>
00276 void ListItem<T>::operator delete(void *p, size_t)
00277 {
00278 ((ListItem<T>*)p)->next = unused;
00279 unused = (ListItem<T>*)p;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288 template <class T>
00289 int LinkedList<T>::counter=0;
00290
00291
00292 template <class T>
00293 LinkedList<T>::~LinkedList()
00294 {
00295 while (!empty())
00296 extract(first);
00297 counter--;
00298
00299 if (!counter)
00300 ListItem<T>::delete_unused();
00301 }
00302
00303
00304 template <class T>
00305 int LinkedList<T>::empty() const
00306 {
00307 return (first == NULL ? TRUE : FALSE) ;
00308 }
00309
00310
00311 template <class T>
00312 void LinkedList<T>::extract(ListItem<T>* item)
00313 {
00314 if (empty())
00315 ErrAbort("LinkedList<T>::extract : empty list");
00316
00317 if (item->prev)
00318 item->prev->next = item->next;
00319 else
00320 first = item->next;
00321
00322 if (item->next)
00323 item->next->prev = item->prev;
00324 else
00325 last = item->prev;
00326
00327 delete item;
00328 Len--;
00329 }
00330
00331
00332 template <class T>
00333 ListItem<T>* LinkedList<T>::insert( T& data, ListItem<T>* next)
00334 {
00335 ListItem<T>* item = new ListItem<T>(data);
00336
00337 if (next) {
00338 if (next->prev)
00339 next->prev->next = item;
00340 else
00341 first = item;
00342 item->next = next;
00343 item->prev = next->prev;
00344 next->prev = item;
00345 }
00346 else {
00347 if (last) {
00348 last->next = item;
00349 item->prev = last;
00350 last = item;
00351 }
00352 else
00353 first = last = item;
00354 }
00355
00356 Len++;
00357 return item;
00358 }
00359
00360
00361 template <class T>
00362 ListItem<T>* LinkedList<T>::find( T& data)
00363 {
00364 ListItem<T>* curr = first;
00365
00366 while (curr) {
00367 if (data == curr->data()) break;
00368 curr = curr->next;
00369 }
00370
00371 return curr;
00372 }
00373 #endif