00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef _KEYLIST_H
00032 #define _KEYLIST_H
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #define KYL_TRUE 1
00066 #define KYL_FALSE 0
00067 typedef int KYL_BOOL;
00068
00069 #ifdef KYL_PRINT
00070 #include <iostream.h>
00071 #endif
00072
00073 #pragma interface
00074
00075 #define ListHash(ptr, size) (((unsigned int)(ptr) % (unsigned int)(size)))
00076
00077 template <class Type> class KeyList;
00078
00079 template <class Type>
00080 class KeyListItem {
00081 friend class KeyList<Type>;
00082 public:
00083 KeyListItem(const Type &d, const void *k) {
00084 data =d;
00085 next = (KeyListItem<Type>*) 0;
00086 key = k;
00087 }
00088 KeyListItem(const KeyListItem<Type> &it) {
00089 data = it.data;
00090 key = it.key;
00091 next = (KeyListItem<Type>*) 0;
00092 }
00093 ~KeyListItem() {;}
00094 KeyListItem<Type> & operator = (const KeyListItem<Type> &it) {
00095 if (this == &it)
00096 return (*this);
00097 else {
00098 data = it.data;
00099 key = it.key;
00100 return (*this);
00101 }
00102 }
00103 private:
00104 Type data;
00105 void *key;
00106 KeyListItem<Type> *next;
00107 };
00108
00109 template <class Type>
00110 class KeyList {
00111 public:
00112 KeyList() { head = (KeyListItem<Type>*) 0; }
00113 KeyList(const KeyList<Type> &from);
00114 ~KeyList() { destroy(); }
00115
00116 KYL_BOOL destroy();
00117 KYL_BOOL remove (void *key) {
00118 int f;
00119 find(key, f, 1);
00120 return f;
00121 }
00122
00123 int empty() const { return (head == (KeyListItem<Type>*) 0);}
00124 int count() const;
00125
00126 KYL_BOOL inList(const void *key);
00127 void reverse();
00128
00129 KYL_BOOL append(const Type &data, const void *key);
00130 KYL_BOOL prepend(const Type &data, const void *key);
00131 KYL_BOOL appendUnique (const Type &i3, const void *key);
00132 KYL_BOOL prependUnique (const Type &i3, const void *key);
00133
00134 KeyList<Type> & operator += (const KeyList<Type> &mergee);
00135 KeyList<Type> & operator = (const KeyList<Type> &from);
00136
00137 void map (void (*map_function)(const Type &item)) const;
00138
00139 Type car(KYL_BOOL &valid);
00140 KeyList<Type> cdr();
00141
00142
00143 void modify(Type (*mod_func)(Type &input));
00144
00145
00146
00147 Type find(const void *key, KYL_BOOL &found, const int removeMe=0);
00148
00149 #ifdef KYL_PRINT
00150 friend ostream &operator << (ostream& os, const KeyList<Type>& S) {
00151 KeyListItem<Type> *temp;
00152 for (temp=S.head; temp; temp=temp->next)
00153 os << " : d=" << temp->data << " k=" << temp->key << " : " << endl;
00154 return os;
00155 }
00156 #endif
00157
00158 protected:
00159 KeyListItem<Type> *last() {
00160 KeyListItem<Type> *tmp, *lag;
00161 for (tmp=head, lag=0; tmp; lag=tmp, tmp=tmp->next)
00162 ;
00163 return lag;
00164 }
00165 KeyListItem<Type> *head;
00166 };
00167
00168
00169 template <class Type>
00170 KeyList<Type>::KeyList (const KeyList<Type> &from) {
00171 KeyListItem<Type> *temp;
00172 head = 0;
00173 for (temp=from.head; temp; temp = temp-> next) {
00174 prepend(temp->data, temp->key);
00175 }
00176 reverse();
00177 }
00178
00179 template <class Type>
00180 void KeyList<Type>::reverse()
00181 {
00182 KeyListItem<Type> *curr, *lag=0, *ahead;
00183
00184 for (curr=head; curr; curr=ahead) {
00185 ahead = curr->next;
00186 curr->next = lag;
00187 lag = curr;
00188 }
00189 head = lag;
00190 }
00191
00192 template <class Type>
00193 int KeyList<Type>::count() const
00194 {
00195 int c=0;
00196 KeyListItem<Type> *temp;
00197 for (temp=head; temp; temp = temp->next)
00198 c++;
00199 return c;
00200 }
00201
00202 template <class Type>
00203 KYL_BOOL KeyList<Type>::destroy()
00204 {
00205 KeyListItem<Type> *temp, *next;
00206
00207 for (temp=head; temp; temp = next) {
00208 next = temp->next;
00209 delete (temp);
00210 }
00211 head = 0;
00212 return KYL_TRUE;
00213 }
00214
00215 template <class Type>
00216 KeyList<Type> &KeyList<Type>::operator = (const KeyList<Type> &from)
00217 {
00218 KeyListItem<Type> *temp;
00219
00220 if (this == &from)
00221 return (*this);
00222
00223 destroy();
00224
00225 for (temp=from.head; temp; temp = temp->next)
00226 prepend(temp->data, temp->key);
00227 reverse();
00228 return (*this);
00229 }
00230
00231
00232 template <class Type>
00233 KeyList<Type> &KeyList<Type>::operator +=(const KeyList<Type> &mergee)
00234 {
00235 KeyListItem<Type> *curr;
00236
00237 if (this == &mergee)
00238 return (*this);
00239
00240 for (curr=mergee.head; curr; curr=curr->next) {
00241 append(curr->data, curr->key);
00242 }
00243 return (*this);
00244 }
00245
00246 template <class Type>
00247 void KeyList<Type>::map (void (*map_function)(const Type &item)) const
00248 {
00249 const KeyListItem<Type> *temp = 0;
00250
00251 if (!map_function) return;
00252 for (temp = head; temp; temp = temp->next)
00253 map_function (temp->data);
00254 }
00255
00256 template <class Type>
00257 void KeyList<Type>::modify (Type (*mod_f)(Type &item))
00258 {
00259 KeyListItem<Type> *temp = 0;
00260
00261 if (!mod_f) return;
00262 for (temp = head; temp; temp = temp->next)
00263 temp->data = mod_f(temp->data);
00264 }
00265
00266 template <class Type>
00267 KYL_BOOL KeyList<Type>::prependUnique (const Type &comp_me, const void *key)
00268 {
00269 KeyListItem<Type> *temp = 0;
00270
00271 for (temp = head; temp; temp = temp->next)
00272 if (temp->key == key) {
00273 temp->data = comp_me;
00274 return KYL_TRUE;
00275 }
00276
00277 return (prepend(comp_me, key));
00278 }
00279
00280 template <class Type>
00281 KYL_BOOL KeyList<Type>::appendUnique (const Type &comp_me, const void *key)
00282 {
00283 KeyListItem<Type> *temp = 0;
00284
00285 for (temp = head; temp; temp = temp->next)
00286 if (temp->key == key) {
00287 temp->data = comp_me;
00288 return KYL_TRUE;
00289 }
00290
00291 return (append(comp_me, key));
00292 }
00293
00294 template <class Type>
00295 KYL_BOOL KeyList<Type>::prepend (const Type &data, const void *key)
00296 {
00297 KeyListItem<Type> *ni;
00298
00299 ni = new KeyListItem<Type>(data, key);
00300 if (!ni)
00301 return KYL_FALSE;
00302
00303 ni->next = head;
00304 head = ni;
00305 return KYL_TRUE;
00306 }
00307
00308
00309 template <class Type>
00310 KYL_BOOL KeyList<Type>::append(const Type &data, const void *key)
00311 {
00312 KeyListItem<Type> *ni;
00313 KeyListItem<Type> *tl;
00314
00315 ni = new KeyListItem<Type>(data, key);
00316 if (!ni)
00317 return KYL_FALSE;
00318
00319 tl = last();
00320 if (tl) {
00321 tl->next = ni;
00322 } else {
00323 ni->next = head;
00324 head = ni;
00325 }
00326 return KYL_TRUE;
00327 }
00328
00329 template <class Type>
00330 KYL_BOOL KeyList<Type>::inList (const void *key)
00331 {
00332 KeyListItem<Type> *curr;
00333 for (curr=head; curr; curr=curr->next) {
00334 if (curr->key == key)
00335 return KYL_TRUE;
00336 }
00337 return KYL_FALSE;
00338 }
00339
00340 template <class Type>
00341 Type KeyList<Type>::find(const void *key, KYL_BOOL &found, const int removeMe)
00342 {
00343 KeyListItem<Type> *lag, *curr;
00344 Type ret;
00345
00346 for (curr=head, lag = (KeyListItem<Type>*) 0; curr; curr=curr->next) {
00347 if (curr->key == key)
00348 break;
00349 lag = curr;
00350 }
00351
00352 if (curr) {
00353 found = KYL_TRUE;
00354 ret = curr->data;
00355 if (removeMe) {
00356 if (lag)
00357 lag->next = curr->next;
00358 else
00359 head = curr->next;
00360 delete(curr);
00361 }
00362 }
00363
00364 return ret;
00365 }
00366
00367 template <class Type>
00368 Type KeyList<Type>::car(KYL_BOOL &valid)
00369 {
00370 KeyListItem<Type> *nx;
00371 Type ret;
00372
00373 if (head) {
00374 nx = head;
00375 ret = nx->data;
00376 head = head->next;
00377 delete nx;
00378 valid = KYL_TRUE;
00379 return ret;
00380 } else {
00381 valid = KYL_FALSE;
00382 return ret;
00383 }
00384 }
00385
00386
00387 template <class Type>
00388 KeyList<Type> KeyList<Type>::cdr()
00389 {
00390 KeyList<Type> ret;
00391 int val;
00392
00393 ret = *this;
00394 ret.car(val);
00395 return ret;
00396 }
00397
00398
00399
00400 template <class Type> class KHTable {
00401 public:
00402
00403 #ifdef KYL_PRINT
00404 friend ostream &operator<<(ostream &os, KHTable<Type> &data) {
00405 int i;
00406 for (i=0; i < data.tableSize; i++) {
00407 if (data.table[i]) {
00408 os << " list # " << i << endl;
00409 os << *data.table[i];
00410 }
00411 }
00412 return os;
00413 }
00414 #endif
00415
00416 KHTable(const int size=97) {
00417 int s;
00418 tableSize = size;
00419 if (tableSize <= 0) tableSize = 97;
00420 table = new KeyList<Type>*[tableSize];
00421 for (s=0; s<size; ++s)
00422 table[s] = 0;
00423 }
00424
00425 KHTable(const KHTable<Type> &data) {
00426 int j;
00427 tableSize = data.tableSize;
00428 table = new KeyList<Type>*[tableSize];
00429 for (j=0; j < tableSize; ++j)
00430 table[j] = data.table[j];
00431 }
00432
00433 ~KHTable() {delete [] table;}
00434 KYL_BOOL destroy();
00435
00436 Type find(const void *key, int &valid, const int removeMe=0);
00437 KYL_BOOL add(const Type &data, const void *key);
00438 KYL_BOOL addUnique(const Type &data, const void *key);
00439
00440 KYL_BOOL remove(const void *key) {
00441 int val;
00442 find(key, val, 1);
00443 return(val);
00444 }
00445
00446 KHTable<Type> & operator =(const KHTable<Type> & arg);
00447 KYL_BOOL operator == (const KHTable<Type> & arg);
00448
00449 KYL_BOOL inTable(const void *key);
00450 int count() const;
00451
00452 private:
00453 KeyList<Type> **table;
00454 int tableSize;
00455 };
00456
00457
00458 template <class Type>
00459 KYL_BOOL KHTable<Type>::destroy()
00460 {
00461 int j;
00462 for (j=0; j<tableSize; ++j)
00463 if (table[j]) {
00464 delete (table[j]);
00465 table[j] = 0;
00466 }
00467 return KYL_TRUE;
00468 }
00469
00470 template <class Type>
00471 Type KHTable<Type>::find(const void *key, int &valid, const int removeMe)
00472 {
00473 int hid;
00474 Type ret;
00475
00476 hid = ListHash(key, tableSize);
00477 if ((hid < 0) ||
00478 (hid > tableSize)) {
00479 valid = KYL_FALSE;
00480 return ret;
00481 } else if (!table[hid]) {
00482 valid = KYL_FALSE;
00483 return ret;
00484 } else {
00485 return(table[hid]->find(key, valid, removeMe));
00486 }
00487 }
00488
00489 template <class Type>
00490 KYL_BOOL KHTable<Type>::add(const Type &data, const void *key)
00491 {
00492 int hid;
00493
00494 hid = ListHash(key, tableSize);
00495 if (hid <0 || hid > tableSize)
00496 return KYL_FALSE;
00497
00498 if (!table[hid])
00499 table[hid] = new(KeyList<Type>);
00500
00501 return (table[hid]->prepend(data, key));
00502 }
00503
00504 template <class Type>
00505 KHTable<Type> & KHTable<Type>::operator = (const KHTable<Type> &arg)
00506 {
00507 int j;
00508
00509 if (this == &arg)
00510 return (*this);
00511
00512 destroy();
00513 tableSize = arg.tableSize;
00514 table = new KeyList<Type>*[tableSize];
00515 for (j=0; j < arg.tableSize; ++j)
00516 table[j] = arg.table[j];
00517 return(*this);
00518 }
00519
00520 template <class Type>
00521 KYL_BOOL KHTable<Type>::operator == (const KHTable<Type> &arg)
00522 {
00523 int i;
00524 if (tableSize != arg.tableSize)
00525 return KYL_FALSE;
00526 else {
00527 for (i=0; i<tableSize; ++i) {
00528 if (!(table[i] == arg.table[i]))
00529 return KYL_FALSE;
00530 }
00531 }
00532 return KYL_TRUE;
00533 }
00534
00535 template <class Type>
00536 KYL_BOOL KHTable<Type>::addUnique(const Type &data, const void *key)
00537 {
00538 if (inTable(key))
00539 return KYL_FALSE;
00540 else
00541 return (add(data, key));
00542 }
00543
00544 template <class Type>
00545 int KHTable<Type>::count() const {
00546 int i, total=0;
00547 for (i=0; i < tableSize; i++) {
00548 if (table[i]) {
00549 total += table[i]->count();
00550 }
00551 }
00552 return(total);
00553 }
00554
00555 template <class Type>
00556 KYL_BOOL KHTable<Type>::inTable(const void *key)
00557 {
00558 int hid;
00559
00560 hid = ListHash(key, tableSize);
00561 if ((hid < 0) ||
00562 (hid > tableSize))
00563 return KYL_FALSE;
00564 else if (!table[hid])
00565 return KYL_FALSE;
00566 else
00567 return(table[hid]->inList(key));
00568 }
00569
00570 #endif