00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00024 #ifndef __OrderedList_h
00025 #define __OrderedList_h
00026
00027 #ifdef __GNUC__
00028 #pragma interface
00029 #endif
00030
00031 #ifdef NON_ANSI
00032 #include <iostream.h>
00033 #else
00034 #include <iostream>
00035 using namespace std;
00036 #endif
00037 #ifndef ANSI_HDRS
00038 #include <stdlib.h>
00039 #include <stddef.h>
00040 #else
00041 #include <cstdlib>
00042 #include <cstddef>
00043 #endif
00044
00045 #include "errmsg.h"
00046 #include "utilib_dll.h"
00047 #include "_generic.h"
00048 #include "errmsg.h"
00049
00050
00051 template <class T,class V>
00052 class UTILIB_API OrderedList;
00053
00054
00064 template <class T, class V>
00065 class UTILIB_API OrderedListItem {
00066
00067 friend class OrderedList<T,V>;
00068
00069 public:
00070
00072 OrderedListItem( T Data_, V Key_)
00073 : Data(Data_), Key(Key_) {next = prev = 0;}
00074
00076 T& data() {return Data;}
00078 V key() {return Key;}
00080 int operator==(const OrderedListItem<T,V>& item)
00081 {return (Key == item.Key);}
00082
00083 protected:
00084
00086 T Data;
00088 V Key;
00089
00091 OrderedListItem *next;
00093 OrderedListItem *prev;
00094
00096 static OrderedListItem* unused;
00098 static void delete_unused();
00099
00101 void *operator new(size_t);
00103 void operator delete(void*, size_t);
00104 };
00105
00106
00107
00108 template <class T,class V>
00109 class UTILIB_API OrderedList
00110 {
00111 public:
00112
00114 OrderedList()
00115 { counter++; first = last = 0; Len=0; }
00117 OrderedList(const OrderedList<T,V>& list)
00118 { counter++; first = last = 0; Len=0; *this = list;}
00124 virtual ~OrderedList();
00125
00127 OrderedList<T,V>& operator=(const OrderedList<T,V>& list);
00128
00134 OrderedListItem<T,V>* find( V& key);
00136 OrderedListItem<T,V>* head() const
00137 {return first;}
00139 OrderedListItem<T,V>* tail() const
00140 {return last;}
00142 OrderedListItem<T,V>* next(OrderedListItem<T,V>* item) const
00143 {return item->next;}
00144
00146 T& top()
00147 {
00148 if (Len == 0) {
00149 ErrAbort("OrderedList::top -- Empty list");
00150 exit(0);
00151 }
00152 return first->data();
00153 }
00155 void add( T& data, V& key)
00156 {insert(data,key);}
00158 void add( T& data, V& key, OrderedListItem<T,V>*& item )
00159 {item = insert(data,key);}
00161 void remove( T& data, V& key)
00162 {extract(first,data,key);}
00164 void remove(OrderedListItem<T,V>*& item)
00165 {extract(item);}
00167 void remove(OrderedListItem<T,V>*& item, T& data, V& key)
00168 {extract(item,data,key);}
00169
00171 void update(OrderedListItem<T,V>* item, V& key);
00172
00174 int empty() const;
00176 operator int() const
00177 {return (first == 0 ? FALSE : TRUE);}
00179 int len() const
00180 {return Len;}
00181
00182 protected:
00183
00185 void extract(OrderedListItem<T,V>* item, T& data, V& key)
00186 { data = item->Data; key = item->Key; extract(item); }
00188 void extract(OrderedListItem<T,V>* item);
00189
00191 OrderedListItem<T,V>* insert( T& data, V& key);
00193 void extract_all();
00194
00196 OrderedListItem<T,V> *first;
00198 OrderedListItem<T,V> *last;
00199
00201 int Len;
00202
00204 static int counter;
00205
00206 };
00207
00208
00209
00210
00211
00212
00213
00214
00215 template <class T,class V>
00216 OrderedListItem<T,V> *OrderedListItem<T,V>::unused = NULL;
00217
00218
00219 template <class T,class V>
00220 void OrderedListItem<T,V>::delete_unused()
00221 {
00222 OrderedListItem<T,V> *curr = unused;
00223 OrderedListItem<T,V> *next;
00224
00225 while (curr) {
00226 next = curr->next;
00227 char* tmp = (char*) curr;
00228 delete [] tmp;
00229 curr = next;
00230 }
00231
00232 unused = NULL;
00233 }
00234
00235
00236 template <class T,class V>
00237 void* OrderedListItem<T,V>::operator new(size_t size)
00238 {
00239 if (!unused)
00240 return new char[size];
00241 else {
00242 OrderedListItem<T,V> *ptr = unused;
00243 unused = unused->next;
00244 return ptr;
00245 }
00246 }
00247
00248
00249 template <class T,class V>
00250 void OrderedListItem<T,V>::operator delete(void *p, size_t)
00251 {
00252 ((OrderedListItem<T,V>*)p)->next = unused;
00253 unused = (OrderedListItem<T,V>*)p;
00254 }
00255
00256
00257
00258
00259
00260
00261
00262 template <class T,class V>
00263 int OrderedList<T,V>::counter=0;
00264
00265
00266 template <class T,class V>
00267 OrderedList<T,V>::~OrderedList()
00268 {
00269 extract_all();
00270 counter--;
00271
00272 if (!counter)
00273 OrderedListItem<T,V>::delete_unused();
00274 }
00275
00276
00277 template <class T,class V>
00278 void OrderedList<T,V>::extract_all()
00279 {
00280 while (!empty())
00281 extract(first);
00282 }
00283
00284
00285 template <class T, class V>
00286 OrderedList<T,V>& OrderedList<T,V>::operator=(const OrderedList<T,V>& list)
00287 {
00288 extract_all();
00289 OrderedListItem<T,V>* curr = list.head();
00290
00291 while (curr) {
00292 T tdata = curr->data();
00293 V tkey = curr->key();
00294 add(tdata,tkey);
00295 curr = list.next(curr);
00296 }
00297 return *this;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306 template <class T,class V>
00307 void OrderedList<T,V>::update(OrderedListItem<T,V>* item, V& key)
00308 {
00309 insert(item->Data,key);
00310 extract(item);
00311 }
00312
00313
00314 template <class T,class V>
00315 int OrderedList<T,V>::empty() const
00316 {
00317 return (first == NULL ? TRUE : FALSE) ;
00318 }
00319
00320
00321 template <class T,class V>
00322 void OrderedList<T,V>::extract(OrderedListItem<T,V>* item)
00323 {
00324 if (empty()) {
00325 cerr << "extract() on empty list" << endl;
00326 exit(-1);
00327 }
00328
00329 if (item->prev)
00330 item->prev->next = item->next;
00331 else
00332 first = item->next;
00333
00334 if (item->next)
00335 item->next->prev = item->prev;
00336 else
00337 last = item->prev;
00338
00339 delete item;
00340 Len--;
00341 }
00342
00343
00344 template <class T,class V>
00345 OrderedListItem<T,V>* OrderedList<T,V>::insert( T& data, V& key)
00346 {
00347 OrderedListItem<T,V>* item = new OrderedListItem<T,V>(data,key);
00348
00349 OrderedListItem<T,V>* curr = last;
00350
00351 while (curr && (item->Key < curr->Key))
00352 curr = curr->prev;
00353
00354 if (curr) {
00355 item->prev = curr;
00356 if (curr->next)
00357 curr->next->prev = item;
00358 else
00359 last = item;
00360 item->next = curr->next;
00361 curr->next = item;
00362 }
00363
00364 else {
00365 item->prev = NULL;
00366 item->next = first;
00367 if (first)
00368 first->prev = item;
00369 first = item;
00370 if (!last)
00371 last = item;
00372 }
00373
00374 Len++;
00375 return item;
00376 }
00377
00378
00379 template <class T,class V>
00380 OrderedListItem<T,V>* OrderedList<T,V>::find( V& key)
00381 {
00382 OrderedListItem<T,V>* curr = first;
00383
00384 while (curr) {
00385 if (key == curr->key()) break;
00386 curr = curr->next;
00387 }
00388
00389 return curr;
00390 }
00391 #endif