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
00032
00033 #ifndef LIST_H
00034 #define LIST_H
00035
00036 #include "common/h/language.h"
00037
00038 #include <ostream>
00039 #include <string.h>
00040
00041 #if !defined(DO_INLINE_P)
00042 #define DO_INLINE_P
00043 #endif
00044
00045 #if !defined(DO_INLINE_F)
00046 #define DO_INLINE_F
00047 #endif
00048
00049 #define ListHash(ptr, size) (((unsigned int)(ptr) % (unsigned int)(size)))
00050
00051 template <class DataType> class List;
00052 template <class DataType, class KeyType> class ListBase;
00053 template <class Type> class StringList;
00054 template <class Type> class HTable;
00055
00056
00057 template <class DataType, class KeyType> class _list_node {
00058 public:
00059 friend class ListBase<DataType, KeyType>;
00060 friend class StringList<DataType>;
00061 const KeyType key;
00062 DataType data;
00063 _list_node<DataType, KeyType> *next;
00064
00065 _list_node() : next(NULL) { }
00066 _list_node(DataType &dataA, const KeyType &keyA,
00067 _list_node<DataType, KeyType> *nextA) : key(keyA),
00068 data(dataA), next(nextA) { }
00069 explicit _list_node(const _list_node<DataType, KeyType> &from) :
00070 key(from.key), data(from.data), next(NULL) {
00071
00072 }
00073 _list_node<DataType, KeyType> *get_next_node() { return next; }
00074 };
00075
00076
00077 template <class DataType, class KeyType> class _list_iterator {
00078 typedef _list_node<DataType, KeyType> node;
00079 mutable node *cur;
00080
00081 void move_to_next() const {
00082 cur = cur->get_next_node();
00083 }
00084
00085 public:
00086 _list_iterator(node *cur_) :
00087 cur(cur_) {
00088 }
00089 node *getNode() { return cur; }
00090
00091 DataType &operator*() {
00092 return cur->data;
00093 }
00094 const DataType &operator*() const {
00095 return cur->data;
00096 }
00097
00098 _list_iterator operator++(int) const {
00099 _list_iterator result = *this;
00100 move_to_next();
00101 return result;
00102 }
00103
00104 _list_iterator operator++() const {
00105 move_to_next();
00106 return *this;
00107 }
00108 _list_iterator operator+(unsigned n) const {
00109 _list_iterator current = *this;
00110 for(unsigned i=0; i<n; i++) {
00111 current++;
00112 }
00113 return current;
00114 }
00115 bool operator==(const _list_iterator &iter) const {
00116 return (cur == iter.cur);
00117 }
00118 bool operator!=(const _list_iterator &iter) const {
00119 return (cur != iter.cur);
00120 }
00121 };
00122
00123
00124 template <class DataType, class KeyType> class ListBase {
00125 public:
00126 typedef _list_iterator<DataType, KeyType> iterator;
00127 typedef const _list_iterator<DataType, KeyType> const_iterator;
00128 typedef _list_node<DataType, KeyType> node;
00129
00130 ListBase() { head = NULL; }
00131 ListBase(const ListBase &fromList) {
00132 node *lastCopiedNode = NULL;
00133 node *headCopiedNode = NULL;
00134 for(const node *cur = fromList.head; cur; cur=cur->next) {
00135 node *curCopiedNode = new node(*cur);
00136 if(lastCopiedNode)
00137 lastCopiedNode->next = curCopiedNode;
00138 else
00139 headCopiedNode = curCopiedNode;
00140 }
00141 head = headCopiedNode;
00142 }
00143 ~ListBase() {
00144 clear();
00145 }
00146 friend std::ostream &operator<<(std::ostream &os,
00147 const ListBase<DataType, KeyType> &data)
00148 {
00149 TYPENAME ListBase<DataType, KeyType>::iterator curr = data.begin();
00150 TYPENAME ListBase<DataType, KeyType>::iterator endMarker = data.end();
00151
00152 for(; curr != endMarker; ++curr) {
00153 os << *curr << std::endl;
00154 }
00155 return os;
00156 }
00157
00158
00159 DataType &front() { return *(begin()); }
00160 const DataType &front() const { return *(begin()); }
00161
00162
00163 DataType &back() { return getLastNode()->data; }
00164
00165 void __push_front(DataType &data, const KeyType &key);
00166 void __push_back(DataType &data, const KeyType &key);
00167 bool __addIfUniqueKey(DataType &data, const KeyType &key) {
00168 DataType temp;
00169
00170 bool foundIt = __find_with_key(key, &temp);
00171 if (!foundIt) {
00172 __push_front(data, key);
00173 return(true);
00174 } else {
00175 return(false);
00176 }
00177 }
00178 bool __addIfUniqueVal(DataType &data, const KeyType &key) {
00179 bool foundIt = __find_with_val(data);
00180 if (!foundIt) {
00181 __push_front(data, key);
00182 return(true);
00183 } else {
00184 return(false);
00185 }
00186 }
00187 bool __find_with_key(const KeyType &key, DataType *saveVal);
00188 bool __find_with_val(const DataType &saveVal) const;
00189 bool __remove_with_key(const KeyType &key);
00190 bool __remove_with_val(const DataType &val);
00191 void clear();
00192 iterator begin() {
00193 return iterator(head);
00194 }
00195 const_iterator begin() const {
00196 return iterator(head);
00197 }
00198
00199 iterator end() {
00200 return iterator(NULL);
00201 }
00202 const_iterator end() const {
00203 return iterator(NULL);
00204 }
00205
00206 int count() const {
00207 int c;
00208 node *curr;
00209
00210 for (curr=head,c=0; curr; curr=curr->next) c++;
00211 return(c);
00212 }
00213 bool isEmpty() { return (head == NULL); }
00214
00215
00216 void insert(iterator &, DataType &) {
00217
00218 }
00219 void map (void (*map_function)(const DataType item)) {
00220 const node *temp_ptr = 0;
00221
00222 if (!map_function) return;
00223 for (temp_ptr = head; temp_ptr; temp_ptr = temp_ptr->next)
00224 map_function (temp_ptr->data);
00225 }
00226
00227 protected:
00228 node *getLastNode();
00229
00230 node *head;
00231 };
00232
00233
00234 template <class DataType> class List : public ListBase<DataType, void*> {
00235 typedef void* KeyType;
00236 public:
00237 List() : ListBase<DataType, KeyType>() { };
00238 List(const List &fromList) : ListBase<DataType, KeyType>(fromList) { }
00239 ~List() { }
00240 friend std::ostream &operator<<(std::ostream &os,
00241 const List<DataType> &data) {
00242 return operator<<(os, static_cast<ListBase<DataType, KeyType> >(data));
00243 }
00244
00245 void push_front(DataType &data) {
00246 __push_front(data, static_cast<KeyType>(NULL));
00247 }
00248 void push_back(DataType &data) {
00249 __push_back(data, static_cast<KeyType>(NULL));
00250 }
00251 bool addIfUniqueVal(DataType &data) {
00252 return __addIfUniqueVal(data, NULL);
00253 }
00254 bool find(const DataType &val) const {
00255 return __find_with_val(val);
00256 }
00257 bool remove(const DataType &data) {
00258 return __remove_with_val(data);
00259 }
00260 };
00261
00262
00263 template <class DataType, class KeyType> class ListWithKey :
00264 public ListBase<DataType, KeyType> {
00265 public:
00266 ListWithKey() : ListBase<DataType, KeyType>() { };
00267 ListWithKey(const ListWithKey &fromList) :
00268 ListBase<DataType, KeyType>(fromList) {}
00269 ~ListWithKey() { }
00270 friend std::ostream &operator<<(std::ostream &os,
00271 const ListWithKey<DataType, KeyType> &data)
00272 {
00273 return operator<<(os, static_cast<ListBase<DataType, KeyType> >(data));
00274 }
00275
00276 void push_front(DataType &data, KeyType &key) {
00277 __push_front(data, key);
00278 }
00279 void push_back(DataType &data, KeyType &key) {
00280 __push_back(data, key);
00281 }
00282 bool addIfUniqueKey(DataType &data, KeyType &key) {
00283 return __addIfUniqueKey(data, key);
00284 }
00285 bool find_with_key(KeyType &key, DataType *saveVal) {
00286 return __find_with_key(key, saveVal);
00287 }
00288 bool find_with_val(const DataType &val) const {
00289 return __find_with_val(val);
00290 }
00291 bool remove_with_key(KeyType &key) {
00292 return __remove_with_key(key);
00293 }
00294 bool remove_with_val(const DataType &data) {
00295 return __remove_with_val(data);
00296 }
00297 };
00298
00299
00300 template <class Type> std::ostream &operator<<(std::ostream &os,
00301 HTable<Type> &data);
00302
00303 template <class Type> class HTable {
00304 public:
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 #if (defined(i386_unknown_nt4_0) && _MSC_VER < 1300) || defined(mips_sgi_irix6_4)
00315 friend std::ostream& operator<< (std::ostream &os, HTable<Type> &data);
00316 #else
00317 friend std::ostream& operator<< <> (std::ostream &os, HTable<Type> &data);
00318 #endif
00319
00320 HTable(Type data) { (void) HTable(); add(data, (void *) data); }
00321 DO_INLINE_F void add(Type data, void *key);
00322 DO_INLINE_F HTable();
00323 bool addUnique(Type data, void *key) {
00324 Type temp;
00325
00326 bool foundIt = find(key, &temp);
00327 if (foundIt) {
00328 return(false);
00329 } else {
00330 add(data, key);
00331 return(true);
00332 }
00333 }
00334 DO_INLINE_F Type find(void *key);
00335 DO_INLINE_F bool remove(void *key);
00336 DO_INLINE_F HTable<Type> operator =(HTable<Type> arg);
00337 Type operator *() {
00338 return(*currList);
00339 }
00340
00341 Type operator ++(int) {
00342 Type curr;
00343
00344 ++currList;
00345 curr = *currList;
00346 if (curr) return(curr);
00347 for (currHid++; currHid < tableSize; currHid++) {
00348 if (table[currHid]) {
00349 currList = *table[currHid];
00350 curr = *currList;
00351 if (curr) return(curr);
00352 }
00353 }
00354 return(NULL);
00355 }
00356
00357 Type operator ++() {
00358 Type curr;
00359
00360 ++currList;
00361 curr = *currList;
00362 if (curr) return(curr);
00363 for (currHid++; currHid < tableSize; currHid++) {
00364 if (table[currHid]) {
00365 currList = *table[currHid];
00366 curr = *currList;
00367 if (curr) return(curr);
00368 }
00369 }
00370 return(NULL);
00371 }
00372 int count() {
00373 int i, total;
00374
00375 total = 0;
00376 for (i=0; i < tableSize; i++) {
00377 if (table[i]) {
00378 total += table[i]->count();
00379 }
00380 }
00381 return(total);
00382 }
00383
00384 private:
00385 List<Type> **table;
00386 List<Type> currList;
00387 int currHid;
00388 int tableSize;
00389 };
00390
00391
00392 template <class Type> std::ostream &operator<<(std::ostream &os,
00393 HTable<Type> &data) {
00394 int i, total;
00395
00396 total = 0;
00397 for (i=0; i < data.tableSize; i++) {
00398 if (data.table[i]) {
00399 os << *data.table[i];
00400 }
00401 }
00402 return os;
00403 }
00404
00405
00406 template <class Type> DO_INLINE_F HTable<Type> HTable<Type>::operator =(HTable<Type> arg) {
00407 table = arg.table;
00408 tableSize = arg.tableSize;
00409
00410
00411 currHid = -1;
00412 ++(*this);
00413 return(*this);
00414 }
00415
00416 template <class Type> DO_INLINE_F HTable<Type>::HTable()
00417 {
00418 table = NULL;
00419 currHid = 0;
00420 tableSize = 0;
00421 }
00422
00423 template <class Type> DO_INLINE_F Type HTable<Type>::find(void *key)
00424 {
00425 int hid;
00426
00427 if (!tableSize) return(NULL);
00428 hid = ListHash(key, tableSize);
00429 if (hid <0 || hid > tableSize) abort();
00430 if (!table[hid]) {
00431 return(NULL);
00432 } else {
00433 return(table[hid]->find(key));
00434 }
00435 }
00436
00437 template <class Type> DO_INLINE_F void HTable<Type>::add(Type data, void *key)
00438 {
00439 int hid;
00440
00441 if (!tableSize) {
00442 tableSize = 97;
00443 table = (List<Type>**) calloc(tableSize, sizeof(List<Type>*));
00444 }
00445 hid = ListHash(key, tableSize);
00446 if (hid <0 || hid > tableSize) abort();
00447 if (!table[hid]) {
00448 table[hid] = new(List<Type>);
00449 }
00450 table[hid]->add(data, key);
00451 }
00452
00453
00454 template <class Type> DO_INLINE_F bool HTable<Type>::remove(void *key)
00455 {
00456 int hid;
00457
00458 hid = ListHash(key, tableSize);
00459 if (hid <0 || hid > tableSize) abort();
00460 if (table[hid]) {
00461 return(table[hid]->remove(key));
00462 }
00463 return(false);
00464 }
00465
00466 template <class Type> class StringList: public List<Type> {
00467 public:
00468 DO_INLINE_F Type find(void *key)
00469 {
00470
00471
00472 typename StringList<Type>::node *it;
00473
00474 for (it=this->head; it; it=it->next) {
00475 if (!strcmp((char *) it->key, (char *) key)) {
00476 return(it->data);
00477 }
00478 }
00479 return((Type) 0);
00480 }
00481 };
00482
00483
00484 #endif