ULAPI  8.0
ulcontainers.h
1 
14 #ifndef ULCONTAINERS_H
15 #define ULCONTAINERS_H
16 
17 #include "ultypes.h"
18 #include "ulassert.h"
19 
20 // Forward declarations.
21 template <class T>
22 class ULList;
23 template <class K, class V>
25 
26 
36 template <class T, class U>
37 class ULPair
38 {
39  UL_TEST_FRIEND;
40 
41 public:
42  ULPair();
43  ULPair(const T& firstItem, const U& secondItem);
44  ULPair(const ULPair<T,U>& p);
45 
47 
48  bool operator==(const ULPair<T,U>& p) const;
49  bool operator<(const ULPair<T,U>& p) const;
50  bool operator!=(const ULPair<T,U>& p) const;
51 
52  const T& getFirst() const;
53  const U& getSecond() const;
54  void setFirst(const T& f);
55  void setSecond(const U& s);
56 
57  T first;
58  U second;
59 };
60 
64 template <class T, class U>
66 {
67 }
68 
72 template <class T, class U>
73 ULPair<T,U>::ULPair(const T& firstItem, const U& secondItem)
74 {
75  this->first = firstItem;
76  this->second = secondItem;
77 }
78 
82 template <class T, class U>
84 {
85  *this = p;
86 }
87 
91 template <class T, class U>
93 {
94  if (this != &p) {
95  this->first = p.first;
96  this->second = p.second;
97  }
98 
99  return *this;
100 }
101 
107 template <class T, class U>
109 {
110  return (this->first == p.first && this->second == p.second);
111 }
112 
119 template <class T, class U>
121 {
122  return !(*this == p);
123 }
124 
125 
134 template <class T, class U>
136 {
137  if (!(this->first == p.first)) {
138  return this->first < p.first;
139  }
140 
141  return this->second < p.second;
142 }
143 
147 template <class T, class U>
148 const T& ULPair<T,U>::getFirst() const
149 {
150  return this->first;
151 }
152 
156 template <class T, class U>
157 const U& ULPair<T,U>::getSecond() const
158 {
159  return this->second;
160 }
161 
166 template <class T, class U>
167 void ULPair<T,U>::setFirst(const T& f)
168 {
169  this->first = f;
170 }
171 
176 template <class T, class U>
177 void ULPair<T,U>::setSecond(const U& s)
178 {
179  this->second = s;
180 }
181 
182 
188 template <class T>
190 {
191  ULListNode();
192  ULListNode(const T& data);
193  ULListNode(const ULListNode<T>& node);
194 
195  ULListNode<T>& operator=(const ULListNode<T>& node);
196 
197  T data;
200 };
201 
205 template <class T>
207 {
208  this->next = 0;
209  this->previous = 0;
210 }
211 
217 template <class T>
219 {
220  this->next = 0;
221  this->previous = 0;
222  this->data = data;
223 }
224 
228 template <class T>
230 {
231  *this = node;
232 }
233 
237 template <class T>
239 {
240  if (this != &node) {
241  this->data = node.data;
242  this->next = node.next;
243  this->previous = node.previous;
244  }
245 
246  return *this;
247 }
248 
249 
254 template <class T>
256 {
257  friend class ULList<T>;
258  UL_TEST_FRIEND;
259 
260 public:
261  ULListIterator();
263 
264  void clear();
266 
267  operator bool() const;
268  bool operator==(const ULListIterator<T>& it) const;
269  bool operator!=(const ULListIterator<T>& it) const;
270 
275  void increment(); // non-operator synonym for operator++(), to help SWIG
276  void decrement(); // non-operator synonym for operator--(), to help SWIG
277 
278  T& operator*();
279  T& getData(); // non-operator synonym for operator*, to help SWIG
280 
281  bool isAtEnd() const;
282  bool isAtBeginning() const;
283  int getIndex() const;
284 
285  ULList<T> *getList();
286 
287 private:
288  ULList<T> *list;
289  ULListNode<T> *current;
290 };
291 
295 template <class T>
297 {
298  this->current = 0;
299  this->list = 0;
300 }
301 
305 template <class T>
307 {
308  *this = it;
309 }
310 
315 template <class T>
317 {
318  this->current = 0;
319  this->list = 0;
320 }
321 
325 template <class T>
327 {
328  if (this != &it) {
329  this->current = it.current;
330  this->list = it.list;
331  }
332 
333  return *this;
334 }
335 
343 template <class T>
345 {
346  return (this->current == 0);
347 }
348 
354 template <class T>
356 {
357  return (this->list == 0 || this->current == this->list->frontNode);
358 }
359 
366 template <class T>
368 {
369  if (this->list == 0 || this->current == 0) {
370  return -1;
371  }
372 
373  int count = -1;
374  const ULListNode<T> *nodePtr;
375  for (nodePtr = this->current; nodePtr != 0; nodePtr = nodePtr->previous) {
376  count++;
377  }
378 
379  return count;
380 }
381 
385 template <class T>
387 {
388  return this->list;
389 }
390 
397 template <class T>
399 {
400  return !(this->isAtEnd());
401 }
402 
406 template <class T>
408 {
409  return this->current == it.current && this->list == it.list;
410 }
411 
415 template <class T>
417 {
418  return !(*this == it);
419 }
420 
427 template <class T>
429 {
430  if (this->current != 0) {
431  this->current = this->current->next;
432  }
433 
434  return *this;
435 }
436 
444 template <class T>
446 {
447  ULListIterator<T> tmp = *this;
448  ++(*this);
449  return tmp;
450 }
451 
458 template <class T>
460 {
461  UL_ASSERT(this->list != 0);
462 
463  if (this->current == this->list->frontNode) {
464  } else if (this->current != 0) {
465  this->current = this->current->previous;
466  } else if (this->list != 0) {
467  this->current = this->list->backNode;
468  }
469 
470  return *this;
471 }
472 
480 template <class T>
482 {
483  ULListIterator<T> tmp = *this;
484  --(*this);
485  return tmp;
486 }
487 
492 template <class T>
494 {
495  ++(*this);
496 }
497 
502 template <class T>
504 {
505  --(*this);
506 }
507 
515 template <class T>
517 {
518  UL_ASSERT(this->current != 0);
519  return this->current->data;
520 }
521 
526 template <class T>
528 {
529  return *(*this);
530 }
531 
536 template <class T>
538 {
539  friend class ULList<T>;
540  UL_TEST_FRIEND;
541 
542 public:
545 
546  void clear();
548 
549  operator bool() const;
550  bool operator==(const ULListConstIterator<T>& it) const;
551  bool operator!=(const ULListConstIterator<T>& it) const;
552 
557  void increment(); // non-operator synonym for operator++(), to help SWIG
558  void decrement(); // non-operator synonym for operator--(), to help SWIG
559 
560  const T& operator*() const;
561  const T& getData(); // non-operator synonym for operator*, to help SWIG
562 
563  bool isAtEnd() const;
564  bool isAtBeginning() const;
565  int getIndex() const;
566 
567  const ULList<T> *getList() const;
568 
569 private:
570  const ULList<T> *list;
571  const ULListNode<T> *current;
572 };
573 
577 template <class T>
579 {
580  this->current = 0;
581  this->list = 0;
582 }
583 
587 template <class T>
589 {
590  *this = it;
591 }
592 
597 template <class T>
599 {
600  this->current = 0;
601  this->list = 0;
602 }
603 
607 template <class T>
609 {
610  if (this != &it) {
611  this->current = it.current;
612  this->list = it.list;
613  }
614 
615  return *this;
616 }
617 
625 template <class T>
627 {
628  return (this->current == 0);
629 }
630 
636 template <class T>
638 {
639  return (this->list == 0 || this->current == this->list->frontNode);
640 }
641 
648 template <class T>
650 {
651  if (this->list == 0 || this->current == 0) {
652  return -1;
653  }
654 
655  int count = -1;
656  const ULListNode<T> *nodePtr;
657  for (nodePtr = this->current; nodePtr != 0; nodePtr = nodePtr->previous) {
658  count++;
659  }
660 
661  return count;
662 }
663 
667 template <class T>
669 {
670  return this->list;
671 }
672 
679 template <class T>
681 {
682  return !(this->isAtEnd());
683 }
684 
688 template <class T>
690 {
691  return this->current == it.current && this->list == it.list;
692 }
693 
697 template <class T>
699 {
700  return !(*this == it);
701 }
702 
709 template <class T>
711 {
712  if (this->current != 0) {
713  this->current = this->current->next;
714  }
715 
716  return *this;
717 }
718 
726 template <class T>
728 {
729  ULListConstIterator<T> tmp = *this;
730  ++(*this);
731  return tmp;
732 }
733 
740 template <class T>
742 {
743  UL_ASSERT(this->list != 0);
744 
745  if (this->current == this->list->frontNode) {
746  } else if (this->current != 0) {
747  this->current = this->current->previous;
748  } else if (this->list != 0) {
749  this->current = this->list->backNode;
750  }
751 
752  return *this;
753 }
754 
762 template <class T>
764 {
765  ULListConstIterator<T> tmp = *this;
766  --(*this);
767  return tmp;
768 }
769 
774 template <class T>
776 {
777  ++(*this);
778 }
779 
784 template <class T>
786 {
787  --(*this);
788 }
789 
799 template <class T>
801 {
802  UL_ASSERT(this->current != 0);
803  return this->current->data;
804 }
805 
810 template <class T>
812 {
813  return *(*this);
814 }
815 
827 template <class T>
828 class ULList
829 {
830  friend class ULListIterator<T>;
831  friend class ULListConstIterator<T>;
832  UL_TEST_FRIEND;
833 
834 public:
835  ULList();
836  ULList(const ULList<T>& list);
837  ~ULList();
838 
839  void clear();
840  ULList<T>& operator=(const ULList<T>& list);
841  bool operator==(const ULList<T>& list) const;
842 
843  T& operator[](uluint32 n) const;
844  T& getAtIndex(uluint32 n) const; // non-operator synonym for operator[], to help SWIG
845 
846  ULListConstIterator<T> find(const T& data) const;
847 
848  void erase(uluint32 n);
849  void erase(ULListIterator<T>& it);
850  void erase(ULListIterator<T>& start, ULListIterator<T>& stop);
851 
852  bool empty() const;
853  uluint32 size() const;
854  uluint32 length() const; // synonym for size
855 
856  void push_front(const T& data);
857  void push_back(const T& data);
858  void append(const T& data); // synonym for push_back
859  void prepend(const T& data); // synonym for push_front
860  void add(const T& data);
861  void insert(ULListIterator<T>& it, const T& data);
862  void insert(const T& data);
863 
864  void pop();
865  T& top();
866 
873 
874  // Node-based operations to allow rearrangement of the list
875  // without lots of copying when T is large.
878  void insertNode(ULListIterator<T>& it, ULListNode<T> *node);
879 
880  void splice(ULList<T>& tail);
881  void sort(int (*func)(T&, T&, void *), void *context);
882  void mergeSort(int (*func)(T&, T&, void *), void *context);
883 
884 private:
885  uluint32 listLength;
886  ULListNode<T> *frontNode;
887  ULListNode<T> *backNode;
888 
889  void destroy();
890 };
891 
895 template <class T>
897 {
898  this->listLength = 0;
899  this->frontNode = 0;
900  this->backNode = 0;
901 }
902 
906 template <class T>
908 {
909  this->listLength = 0;
910  this->frontNode = 0;
911  this->backNode = 0;
912  *this = list;
913 }
914 
918 template <class T>
920 {
921  this->destroy();
922 }
923 
927 template <class T>
928 void ULList<T>::destroy()
929 {
930  ULListNode<T> *tmp;
931  ULListNode<T> *current = this->frontNode;
932 
933  while (current != 0) {
934  tmp = current;
935  current = current->next;
936  delete tmp;
937  }
938 
939  this->listLength = 0;
940 }
941 
947 template <class T>
949 {
950  if (this == &list) {
951  return *this;
952  }
953 
954  ULListNode<T> *current, *tmp;
955  this->destroy();
956  this->frontNode = this->backNode = 0;
957  this->listLength = 0;
958  for (current=list.frontNode; current != 0; current = current->next) {
959  tmp = new ULListNode<T>(current->data); // sets next = previous = 0
960  if (tmp == 0) {
961  return *this;
962  }
963 
964  tmp->previous = this->backNode;
965  if (this->backNode == 0) {
966  this->frontNode = tmp;
967  } else {
968  this->backNode->next = tmp;
969  }
970  this->backNode = tmp;
971  (this->listLength)++;
972  }
973 
974  return *this;
975 }
976 
982 template <class T>
983 bool ULList<T>::operator==(const ULList<T>& other) const
984 {
985  if (this == &other) {
986  return true;
987  }
988 
989  if (this->length() != other.length()) {
990  return false;
991  }
992 
993  ULListNode<T> *current = this->frontNode;
994  ULListNode<T> *otherCurrent = other.frontNode;
995  while (current != 0 && otherCurrent != 0) {
996  if (!(current->data == otherCurrent->data)) {
997  return false;
998  }
999  current = current->next;
1000  otherCurrent = otherCurrent->next;
1001  }
1002 
1003  return current == 0 && otherCurrent == 0;
1004 }
1005 
1012 template <class T>
1013 T& ULList<T>::operator[](uluint32 n) const
1014 {
1015  UL_ASSERT(n < this->listLength);
1016  ULListNode<T> *current = this->frontNode;
1017  for (uluint32 k=0; current != 0 && k < n; k++) {
1018  current = current->next;
1019  }
1020 
1021  UL_ASSERT(current != 0);
1022  return current->data;
1023 }
1024 
1031 template <class T>
1032 T& ULList<T>::getAtIndex(uluint32 n) const
1033 {
1034  UL_ASSERT(n < this->listLength);
1035  ULListNode<T> *current = this->frontNode;
1036  for (uluint32 k=0; current != 0 && k < n; k++) {
1037  current = current->next;
1038  }
1039 
1040  UL_ASSERT(current != 0);
1041  return current->data;
1042 }
1043 
1047 template <class T>
1048 uluint32 ULList<T>::size() const
1049 {
1050  return this->listLength;
1051 }
1052 
1056 template <class T>
1057 uluint32 ULList<T>::length() const
1058 {
1059  return this->listLength;
1060 }
1061 
1066 template <class T>
1068 {
1069  this->destroy();
1070  this->frontNode = this->backNode = 0;
1071  this->listLength = 0;
1072 }
1073 
1079 template <class T>
1081 {
1082  ULListConstIterator<T> it = cbegin();
1083  while (!it.isAtEnd()) {
1084  if (data == *it) {
1085  break;
1086  }
1087 
1088  ++it;
1089  }
1090 
1091  return it;
1092 }
1093 
1097 template <class T>
1098 bool ULList<T>::empty() const
1099 {
1100  return this->frontNode == 0;
1101 }
1102 
1109 template <class T>
1110 void ULList<T>::erase(uluint32 n)
1111 {
1112  ULListNode<T> *current = this->frontNode;
1113  for (uluint32 k=0; current != 0 && k < n; k++) {
1114  current = current->next;
1115  }
1116 
1117  UL_ASSERT(current != 0);
1118 
1119  ULListIterator<T> it;
1120  it.list = this;
1121  it.current = current;
1122  erase(it);
1123 }
1124 
1132 template <class T>
1134 {
1135  if (!it.isAtEnd()) {
1136  ULListNode<T> *node = removeNode(it);
1137  delete node;
1138  }
1139 }
1140 
1151 template <class T>
1153 {
1154  if (start.isAtBeginning()) {
1155  ULListIterator<T> it;
1156  while (!empty()) {
1157  it = begin();
1158  if (it.current == stop.current) {
1159  break;
1160  }
1161  erase(it);
1162  }
1163  } else {
1164  ULListIterator<T> previous = start;
1165  --previous;
1166 
1167  ULListIterator<T> it = start;
1168  while (!it.isAtEnd() && it.current != stop.current) {
1169  ULListNode<T> *node = removeNode(it);
1170  delete node;
1171  it = previous;
1172  ++it;
1173  }
1174  }
1175 }
1176 
1182 template <class T>
1183 void ULList<T>::push_front(const T& data)
1184 {
1185  ULListNode<T> *newNode = new ULListNode<T>;
1186  if (newNode == 0) {
1187  return;
1188  }
1189 
1190  newNode->data = data;
1191  newNode->next = this->frontNode;
1192  newNode->previous = 0;
1193  if (this->frontNode == 0) {
1194  this->backNode = newNode;
1195  } else {
1196  this->frontNode->previous = newNode;
1197  }
1198  this->frontNode = newNode;
1199  (this->listLength)++;
1200 }
1201 
1207 template <class T>
1208 void ULList<T>::push_back(const T& data)
1209 {
1210  ULListNode<T> *newNode = new ULListNode<T>;
1211  if (newNode == 0) {
1212  return;
1213  }
1214 
1215  newNode->data = data;
1216  newNode->next = 0;
1217  newNode->previous = this->backNode;
1218 
1219  if (this->backNode == 0) {
1220  this->frontNode = newNode;
1221  } else {
1222  this->backNode->next = newNode;
1223  }
1224 
1225  this->backNode = newNode;
1226  (this->listLength)++;
1227 }
1228 
1234 template <class T>
1235 void ULList<T>::append(const T& data)
1236 {
1237  this->push_back(data);
1238 }
1239 
1245 template <class T>
1246 void ULList<T>::prepend(const T& data)
1247 {
1248  this->push_front(data);
1249 }
1250 
1256 template <class T>
1257 void ULList<T>::add(const T& data)
1258 {
1259  ULListIterator<T> it = begin();
1260  while (!it.isAtEnd()) {
1261  if (data == *it) {
1262  break;
1263  }
1264  ++it;
1265  }
1266 
1267  if (it.isAtEnd()) {
1268  push_back(data);
1269  }
1270 }
1271 
1280 template <class T>
1281 void ULList<T>::insert(ULListIterator<T>& it, const T& data)
1282 {
1283  ULListNode<T> *node = new ULListNode<T>(data);
1284  if (node != 0) {
1285  this->insertNode(it, node);
1286  }
1287 }
1288 
1297 template <class T>
1298 void ULList<T>::insert(const T& data)
1299 {
1300  ULListIterator<T> it = begin();
1301  while (!it.isAtEnd() && *it < data) {
1302  ++it;
1303  }
1304 
1305  if (it.isAtEnd() || !(*it == data)) {
1306  insert(it, data);
1307  }
1308 }
1309 
1313 template <class T>
1315 {
1316  if (!empty()) {
1317  ULListIterator<T> it = end();
1318  --it;
1319  erase(it);
1320  }
1321 }
1322 
1327 template <class T>
1329 {
1330  UL_ASSERT(!empty());
1331  return this->backNode->data;
1332 }
1333 
1337 template <class T>
1339 {
1340  ULListIterator<T> it;
1341  it.list = this;
1342  it.current = this->frontNode;
1343  return it;
1344 }
1345 
1349 template <class T>
1351 {
1353  it.list = this;
1354  it.current = this->frontNode;
1355  return it;
1356 }
1357 
1364 template <class T>
1366 {
1367  ULListIterator<T> it;
1368  it.list = this;
1369  it.current = 0;
1370  return it;
1371 }
1372 
1379 template <class T>
1381 {
1383  it.list = this;
1384  it.current = 0;
1385  return it;
1386 }
1387 
1392 template <class T>
1394 {
1395  ULListIterator<T> it;
1396  it.list = this;
1397  it.current = this->backNode;
1398  return it;
1399 }
1400 
1405 template <class T>
1407 {
1409  it.list = this;
1410  it.current = this->backNode;
1411  return it;
1412 }
1413 
1425 template <class T>
1427 {
1428  ULListNode<T> *node = it.current;
1429 
1430  UL_ASSERT(it.list == this);
1431  if (it.current != 0 && it.list == this) {
1432  if (it.current == this->frontNode) {
1433  this->frontNode = this->frontNode->next;
1434  }
1435 
1436  if (it.current == this->backNode) {
1437  this->backNode = this->backNode->previous;
1438  }
1439 
1440  if (it.current->next != 0) {
1441  it.current->next->previous = it.current->previous;
1442  }
1443 
1444  if (it.current->previous != 0) {
1445  it.current->previous->next = it.current->next;
1446  }
1447 
1448  // This enables you to iterate through a list and safely remove nodes
1449  // based on some criterion without corrupting the iterator in the process.
1450  it.current = it.current->next;
1451  }
1452 
1453  (this->listLength)--;
1454  return node;
1455 }
1456 
1462 template <class T>
1464 {
1465  ULListIterator<T> it = this->begin();
1466  return removeNode(it);
1467 }
1468 
1478 template <class T>
1480 {
1481  UL_ASSERT(node != 0);
1482  UL_ASSERT(it.list == this);
1483  if (node == 0 || it.list != this) {
1484  return;
1485  }
1486 
1487  node->next = it.current;
1488  if (it.current == 0) {
1489  node->previous = this->backNode;
1490  if (this->backNode != 0) {
1491  this->backNode->next = node;
1492  }
1493  this->backNode = node;
1494  } else {
1495  node->previous = it.current->previous;
1496  if (it.current->previous != 0) {
1497  it.current->previous->next = node;
1498  }
1499 
1500  it.current->previous = node;
1501  }
1502 
1503  if (it.current == this->frontNode) {
1504  this->frontNode = node;
1505  }
1506 
1507  this->listLength++;
1508  it.current = node;
1509 }
1510 
1518 template <class T>
1520 {
1521  // Adjust this list.
1522  if (this->listLength == 0) {
1523  this->frontNode = tail.frontNode;
1524  } else {
1525  this->backNode->next = tail.frontNode;
1526  }
1527 
1528  if (tail.frontNode != 0) {
1529  tail.frontNode->previous = this->backNode;
1530  }
1531 
1532  this->listLength += tail.listLength;
1533  if (tail.listLength != 0) {
1534  this->backNode = tail.backNode;
1535  }
1536 
1537  // Remove spliced nodes from tail list so they don't get deleted when tail gets deleted.
1538  tail.listLength = 0;
1539  tail.frontNode = 0;
1540  tail.backNode = 0;
1541 }
1542 
1552 template <class T>
1553 void ULList<T>::sort(int (*func)(T&, T&, void *), void *context)
1554 {
1555  // this function implements a qsort algorithm with func() as the
1556  // comparison function
1557 
1558  // it relies on the internal structure of ULList, and tries to perform
1559  // an efficient sort. No objects are copied, just nodes rearranged and some
1560  // temporary ULList instances created on the stack
1561 
1562  if (this->frontNode == this->backNode) { // this is a fast way to see if size() is 0 or 1
1563  return; // a list of 0 or 1 elements is always sorted
1564  }
1565 
1566  // take the first node in the list as the pivot
1567  ULListNode<T> *pivot = this->removeFrontNode();
1568 
1569  ULList<T> lteqList, gtList; // our two sublists
1570 
1571  // iterate the list, removing elements and adding them to the sublists
1572  while (!empty()) {
1573  ULListNode<T> *cur = this->removeFrontNode();
1574  ULList<T>& list =
1575  func(cur->data, pivot->data, context) <= 0
1576  ? lteqList
1577  : gtList;
1578 
1579  ULListIterator<T> it = list.begin();
1580  list.insertNode(it, cur);
1581  }
1582 
1583  // the list is divided, now recurse!
1584  lteqList.sort(func, context);
1585  gtList.sort(func, context);
1586 
1587  // now we rebuild our own list from the pivot and the two others
1588 
1589  // add the <= list
1590  while (!lteqList.empty()) {
1591  ULListNode<T> *node = lteqList.removeFrontNode();
1592  ULListIterator<T> it = this->end();
1593  this->insertNode(it, node);
1594  }
1595 
1596  // add the pivot
1597  ULListIterator<T> it = this->end();
1598  this->insertNode(it, pivot);
1599 
1600  // add the > list
1601  while (!gtList.empty()) {
1602  ULListNode<T> *node = gtList.removeFrontNode();
1603  ULListIterator<T> it = this->end();
1604  this->insertNode(it, node);
1605  }
1606 
1607  // the list is now sorted, and there's no cleanup
1608 }
1609 
1619 template <class T>
1620 void ULList<T>::mergeSort(int (*func)(T&, T&, void*), void *context)
1621 {
1622  // this function implements an in-place mergesort using
1623  // func() as the comparison function
1624 
1625  // it relies on the internal structure of ULList and
1626  // avoids copying any objects
1627 
1628  if (this->frontNode == this->backNode) {
1629  return; // a list of 0 or 1 elements is always sorted
1630  }
1631 
1632  // first, split ourselves into two sublists
1633  // we go even/odd so we don't have to iterate twice
1634  ULList<T> evenList, oddList;
1635  for (bool odd = false; !this->empty(); odd = !odd) {
1636  ULListNode<T> *front = this->removeFrontNode();
1637  ULList<T>& list = odd ? oddList : evenList;
1638  ULListIterator<T> it = list.begin();
1639  list.insertNode(it, front);
1640  }
1641 
1642  // recurse on the sublists
1643  evenList.mergeSort(func, context);
1644  oddList.mergeSort(func, context);
1645 
1646  // now merge
1647  while (!evenList.empty() && !oddList.empty()) {
1648  ULList<T>& list =
1649  func(evenList.frontNode->data, oddList.frontNode->data, context) <= 0
1650  ? evenList
1651  : oddList;
1652  ULListIterator<T> it = this->end();
1653  this->insertNode(it, list.removeFrontNode());
1654  }
1655 
1656  // scoop up stragglers from whichever list has stuff left
1657  while (!evenList.empty()) {
1658  ULListIterator<T> it = this->end();
1659  this->insertNode(it, evenList.removeFrontNode());
1660  }
1661  while (!oddList.empty()) {
1662  ULListIterator<T> it = this->end();
1663  this->insertNode(it, oddList.removeFrontNode());
1664  }
1665 
1666  // all done!
1667 }
1668 
1669 
1676 template <class K, class V>
1678 {
1679  friend class ULHashTable<K,V>;
1680  UL_TEST_FRIEND;
1681 
1682 public:
1686 
1688  const ULPair<K,V>& operator*() const;
1689  void operator++();
1690  void operator++(int);
1691  operator bool() const;
1692 
1693  bool isAtEnd() const;
1694  uluint32 getHashIndex() const;
1695 
1696 private:
1697  const ULHashTable<K,V> *hashTable;
1698  uluint32 hashIndex;
1699  ULListConstIterator< ULPair<K,V> > listIterator;
1700 };
1701 
1705 template <class K, class V>
1707  : hashTable(0), hashIndex(0)
1708 {
1709 }
1710 
1714 template <class K, class V>
1716  : hashTable(0), hashIndex(0)
1717 {
1718  *this = it;
1719 }
1720 
1724 template <class K, class V>
1726 {
1727 }
1728 
1732 template <class K, class V>
1734 {
1735  if (&it != this) {
1736  this->hashTable = it.hashTable;
1737  this->hashIndex = it.hashIndex;
1738  this->listIterator = it.listIterator;
1739  }
1740 
1741  return *this;
1742 }
1743 
1750 template <class K, class V>
1752 {
1753  UL_ASSERT(!isAtEnd());
1754  return *(this->listIterator);
1755 }
1756 
1762 template <class K, class V>
1764 {
1765  if (this->hashTable == 0) {
1766  return;
1767  }
1768 
1769  ++(this->listIterator);
1770  if (this->listIterator.isAtEnd()) {
1771  this->hashIndex++;
1772  this->listIterator = this->hashTable->table[this->hashIndex].cbegin();
1773  while (this->hashIndex < this->hashTable->tableSize && this->listIterator.isAtEnd()) {
1774  this->hashIndex++;
1775  this->listIterator = this->hashTable->table[this->hashIndex].cbegin();
1776  }
1777  }
1778 }
1779 
1785 template <class K, class V>
1787 {
1788  ++(*this);
1789 }
1790 
1798 template <class K, class V>
1800 {
1801  return !(this->isAtEnd());
1802 }
1803 
1811 template <class K, class V>
1813 {
1814  return this->hashTable == 0 || this->hashIndex >= this->hashTable->tableSize;
1815 }
1816 
1820 template <class K, class V>
1822 {
1823  return this->hashIndex;
1824 }
1825 
1838 template <class K, class V>
1839 class ULHashTable
1840 {
1841  friend class ULHashTableIterator<K,V>;
1842  UL_TEST_FRIEND;
1843 
1844 public:
1845  ULHashTable();
1846  ULHashTable(uluint32 tableSize);
1847  ~ULHashTable();
1848 
1849  void clear();
1851 
1852  uluint32 getTableSize() const;
1853  uluint32 getKeyCount() const;
1854  bool resize(uluint32 tableSize);
1855 
1856  void add(const K& key, const V& value);
1857  void add(const ULPair<K,V>& keyValuePair);
1858 
1859  bool find(const K& key, V& value) const;
1860  bool find(const K& key) const;
1861 
1862  ULHashTableIterator<K,V> end() const;
1864 
1865  void getStats(double& avgListLength, uluint32& maxListLength);
1866 
1867 private:
1868  ULList< ULPair<K,V> > *table;
1869  uluint32 tableSize;
1870  uluint32 keyCount;
1871 };
1872 
1878 template <class K, class V>
1880  : table(0), tableSize(0), keyCount(0)
1881 {
1882 }
1883 
1888 template <class K, class V>
1889 ULHashTable<K,V>::ULHashTable(uluint32 initialTableSize)
1890 {
1891  this->table = 0;
1892  this->tableSize = 0;
1893  this->keyCount = 0;
1894  if (initialTableSize > 0) {
1895  this->table = new ULList< ULPair<K,V> >[initialTableSize];
1896  if (this->table != 0) {
1897  this->tableSize = initialTableSize;
1898  }
1899  }
1900 }
1901 
1905 template <class K, class V>
1907 {
1908  delete [] this->table;
1909 }
1910 
1915 template <class K, class V>
1917 {
1918  if (this->table != 0) {
1919  for (uluint32 k=0; k < this->tableSize; k++) {
1920  this->table[k].clear();
1921  }
1922  this->keyCount = 0;
1923  }
1924 }
1925 
1931 template <class K, class V>
1933 {
1934  delete [] this->table;
1935  this->table = 0;
1936  this->tableSize = 0;
1937  this->keyCount = 0;
1938  if (otherTable.tableSize > 0) {
1939  this->table = new ULList< ULPair<K,V> >[otherTable.tableSize];
1940  }
1941 
1942  if (this->table != 0) {
1943  this->tableSize = otherTable.tableSize;
1944  for (uluint32 k=0; k < this->tableSize; k++) {
1945  this->table[k] = otherTable.table[k];
1946  }
1947  this->keyCount = otherTable.keyCount;
1948  }
1949 
1950  return *this;
1951 }
1952 
1957 template <class K, class V>
1959 {
1960  return this->tableSize;
1961 }
1962 
1966 template <class K, class V>
1968 {
1969  return this->keyCount;
1970 }
1971 
1980 template <class K, class V>
1981 bool ULHashTable<K,V>::resize(uluint32 tableSize)
1982 {
1983  if (tableSize == 0 || tableSize == this->tableSize) {
1984  return true;
1985  }
1986 
1987  ULList< ULPair<K,V> > *newTable = new ULList< ULPair<K,V> >[tableSize];
1988  if (newTable == 0) {
1989  return false;
1990  }
1991 
1992  if (this->tableSize != 0) {
1993  uluint32 hashValue;
1995  this->keyCount = 0;
1996  for (uluint32 k=0; k < this->tableSize; k++) {
1997  for (it = this->table[k].cbegin(); it; ++it) {
1998  hashValue = (*it).getFirst().hash(tableSize);
1999  UL_ASSERT(hashValue < tableSize);
2000  newTable[hashValue].push_back(*it);
2001  this->keyCount++;
2002  }
2003  }
2004  }
2005 
2006  delete [] this->table;
2007  this->table = newTable;
2008  this->tableSize = tableSize;
2009 
2010  return true;
2011 }
2012 
2018 template <class K, class V>
2019 void ULHashTable<K,V>::add(const K& key, const V& value)
2020 {
2021  ULPair<K,V> keyValuePair;
2022  keyValuePair.setFirst(key);
2023  keyValuePair.setSecond(value);
2024  this->add(keyValuePair);
2025 }
2026 
2034 template <class K, class V>
2035 void ULHashTable<K,V>::add(const ULPair<K,V>& keyValuePair)
2036 {
2037  uluint32 hashValue = keyValuePair.getFirst().hash(this->tableSize);
2038  UL_ASSERT(hashValue < this->tableSize);
2039  if (hashValue < this->tableSize) {
2041  for (it = this->table[hashValue].begin(); it; ++it) {
2042  if (keyValuePair.getFirst() == (*it).getFirst()) {
2043  (*it).setSecond(keyValuePair.getSecond());
2044  return;
2045  }
2046  }
2047 
2048  this->table[hashValue].push_back(keyValuePair);
2049  this->keyCount++;
2050  }
2051 }
2052 
2060 template <class K, class V>
2061 bool ULHashTable<K,V>::find(const K& key, V& value) const
2062 {
2063  uluint32 hashValue = key.hash(this->tableSize);
2064  UL_ASSERT(hashValue < this->tableSize);
2065  if (hashValue < this->tableSize) {
2067  for (it = this->table[hashValue].cbegin(); it; ++it) {
2068  if (key == (*it).getFirst()) {
2069  value = (*it).getSecond();
2070  return true;
2071  }
2072  }
2073  }
2074 
2075  return false;
2076 }
2077 
2081 template <class K, class V>
2082 bool ULHashTable<K,V>::find(const K& key) const
2083 {
2084  uluint32 hashValue = key.hash(this->tableSize);
2085  UL_ASSERT(hashValue < this->tableSize);
2087  for (it = this->table[hashValue].cbegin(); it; ++it) {
2088  if (key == (*it).getFirst()) {
2089  return true;
2090  }
2091  }
2092 
2093  return false;
2094 }
2095 
2103 template <class K, class V>
2105 {
2107  it.hashTable = this;
2108  it.hashIndex = this->tableSize;
2109  return it;
2110 }
2111 
2116 template <class K, class V>
2118 {
2120  it.hashTable = this;
2121  it.hashIndex = 0;
2122  it.listIterator = this->table[it.hashIndex].cbegin();
2123  while (it.hashIndex < this->tableSize && it.listIterator.isAtEnd()) {
2124  it.hashIndex++;
2125  it.listIterator = this->table[it.hashIndex].cbegin();
2126  }
2127 
2128  return it;
2129 }
2130 
2140 template <class K, class V>
2141 void ULHashTable<K,V>::getStats(double& avgChainLength, uluint32& maxChainLength)
2142 {
2143  maxChainLength = 0;
2144  uluint32 chainLengthTotal = 0;
2145  uluint32 nNonemptyChains = 0;
2146  for (uluint32 k=0; k < this->tableSize; k++) {
2147  uluint32 chainLength = this->table[k].size();
2148  chainLengthTotal += chainLength;
2149  if (chainLength > maxChainLength) {
2150  maxChainLength = chainLength;
2151  }
2152  if (chainLength > 0) {
2153  nNonemptyChains++;
2154  }
2155  }
2156 
2157  if (nNonemptyChains > 0) {
2158  avgChainLength = double(chainLengthTotal) / double(nNonemptyChains);
2159  } else {
2160  avgChainLength = 0;
2161  }
2162 }
2163 
2164 
2175 template <class T>
2177 {
2178  UL_TEST_FRIEND;
2179 
2180 public:
2181  ULVector();
2182  ULVector(uluint32 newSize);
2183  ULVector(const ULVector<T>& v);
2184  ~ULVector();
2185 
2186  ULVector<T>& operator=(const ULVector<T>& v);
2187  void clear();
2188  T& operator[](uluint32 n);
2189  uluint32 size() const;
2190  void resize(uluint32 newSize);
2191  void append(const T& item);
2192 
2193 private:
2194  T **vector;
2195  uluint32 vectorSize;
2196 };
2197 
2201 template <class T>
2203 {
2204  this->vector = 0;
2205  this->vectorSize = 0;
2206 }
2207 
2212 template <class T>
2213 ULVector<T>::ULVector(uluint32 newSize)
2214 {
2215  this->vector = 0;
2216  this->vectorSize = 0;
2217  resize(newSize);
2218 }
2219 
2223 template <class T>
2225 {
2226  this->vector = 0;
2227  this->vectorSize = 0;
2228  *this = v;
2229 }
2230 
2234 template <class T>
2236 {
2237  this->clear();
2238 }
2239 
2244 template <class T>
2246 {
2247  if (this->vector != 0) {
2248  for (uluint32 k=0; k < this->vectorSize; k++) {
2249  delete this->vector[k];
2250  }
2251  delete [] this->vector;
2252  }
2253 
2254  this->vector = 0;
2255  this->vectorSize = 0;
2256 }
2257 
2263 template <class T>
2265 {
2266  if (this == &v) {
2267  return *this;
2268  }
2269 
2270  this->clear();
2271  this->resize(v.size());
2272  if(this->vector != 0) {
2273  for (uluint32 k=0; k < this->vectorSize; k++) {
2274  (*this)[k] = v[k];
2275  }
2276  }
2277 
2278  return *this;
2279 }
2280 
2285 template <class T>
2287 {
2288  UL_ASSERT(n < (1 << 30));
2289  if (n >= this->vectorSize) {
2290  uluint32 newSize = (this->vectorSize == 0 ? 16 : 2 * this->vectorSize);
2291  while (newSize <= n) {
2292  newSize *= 2;
2293  }
2294  UL_ASSERT(newSize <= (1 << 30));
2295 
2296  this->resize(newSize);
2297  }
2298 
2299  UL_ASSERT(n < this->vectorSize);
2300  if (this->vector[n] == 0) {
2301  this->vector[n] = new T;
2302  }
2303 
2304  return *(this->vector[n]);
2305 }
2306 
2310 template <class T>
2311 uluint32 ULVector<T>::size() const
2312 {
2313  return this->vectorSize;
2314 }
2315 
2324 template <class T>
2325 void ULVector<T>::resize(uluint32 newSize)
2326 {
2327  if (newSize != this->vectorSize) {
2328  if (newSize == 0) {
2329  clear();
2330  } else {
2331  typedef T *TPtr;
2332  T **newVector = new TPtr[newSize];
2333  if (newVector != 0) {
2334  uluint32 k;
2335  for (k=0; k < newSize && k < this->vectorSize; k++) {
2336  newVector[k] = this->vector[k];
2337  this->vector[k] = 0;
2338  }
2339 
2340  for ( ; k < newSize; k++) {
2341  newVector[k] = 0;
2342  }
2343 
2344  this->clear();
2345  this->vector = newVector;
2346  this->vectorSize = newSize;
2347  }
2348  }
2349  }
2350 }
2351 
2352 template <class T>
2353 void ULVector<T>::append(const T& item)
2354 {
2355 }
2356 
2357 #endif