00001
00002
00003
00004
00005
00006
00007
00008
00052 #ifdef _MSC_VER
00053 #pragma once
00054 #endif
00055
00056 #ifndef OGDF_LIST_H
00057 #define OGDF_LIST_H
00058
00059
00060 #include <ogdf/internal/basic/list_templates.h>
00061
00062
00063 namespace ogdf {
00064
00065
00066 template<class E> class List;
00067 template<class E> class ListPure;
00068 template<class E> class ListIterator;
00069 template<class E> class ListConstIterator;
00070
00071
00073 template<class E>
00074 class ListElement {
00075 friend class ListPure<E>;
00076 friend class List<E>;
00077 friend class ListIterator<E>;
00078 friend class ListConstIterator<E>;
00079
00080 ListElement<E> *m_next;
00081 ListElement<E> *m_prev;
00082 E m_x;
00083
00085 ListElement() : m_next(0), m_prev(0) { }
00087 ListElement(const E &x) : m_next(0), m_prev(0), m_x(x) { }
00089 ListElement(const E &x, ListElement<E> *next, ListElement<E> *prev) :
00090 m_next(next), m_prev(prev), m_x(x) { }
00091
00092 OGDF_NEW_DELETE
00093 };
00094
00095
00096
00098
00104 template<class E> class ListIterator {
00105 ListElement<E> *m_pX;
00106
00107 friend class ListConstIterator<E>;
00108 friend class ListPure<E>;
00109
00111 operator ListElement<E> *() { return m_pX; }
00113 operator const ListElement<E> *() const { return m_pX; }
00114
00115 public:
00117 ListIterator() : m_pX(0) { }
00119 ListIterator(ListElement<E> *pX) : m_pX(pX) { }
00121 ListIterator(const ListIterator<E> &it) : m_pX(it.m_pX) { }
00122
00124 bool valid() const { return m_pX != 0; }
00125
00127 bool operator==(const ListIterator<E> &it) const {
00128 return m_pX == it.m_pX;
00129 }
00130
00132 bool operator!=(const ListIterator<E> &it) const {
00133 return m_pX != it.m_pX;
00134 }
00135
00137 ListIterator<E> succ() const { return m_pX->m_next; }
00138
00140 ListIterator<E> pred() const { return m_pX->m_prev; }
00141
00143 E &operator*() const { return m_pX->m_x; }
00144
00146 ListIterator<E> &operator=(const ListIterator<E> &it) {
00147 m_pX = it.m_pX;
00148 return *this;
00149 }
00150
00152 ListIterator<E> &operator++() {
00153 m_pX = m_pX->m_next;
00154 return *this;
00155 }
00156
00158 ListIterator<E> operator++(int) {
00159 ListIterator<E> it = *this;
00160 m_pX = m_pX->m_next;
00161 return it;
00162 }
00163
00165 ListIterator<E> &operator--() {
00166 m_pX = m_pX->m_prev;
00167 return *this;
00168 }
00169
00171 ListIterator<E> operator--(int) {
00172 ListIterator<E> it = *this;
00173 m_pX = m_pX->m_prev;
00174 return it;
00175 }
00176
00177 OGDF_NEW_DELETE
00178 };
00179
00180
00181
00182
00183
00184
00185
00187
00194 template<class E> class ListConstIterator {
00195 const ListElement<E> *m_pX;
00196
00197 friend class ListPure<E>;
00198
00200 operator const ListElement<E> *() { return m_pX; }
00201
00202 public:
00204 ListConstIterator() : m_pX(0) { }
00205
00207 ListConstIterator(const ListElement<E> *pX) : m_pX(pX) { }
00208
00210 ListConstIterator(const ListIterator<E> &it) : m_pX((const ListElement<E> *)it) { }
00212 ListConstIterator(const ListConstIterator &it) : m_pX(it.m_pX) { }
00213
00215 bool valid() const { return m_pX != 0; }
00216
00218 bool operator==(const ListConstIterator<E> &it) const {
00219 return m_pX == it.m_pX;
00220 }
00221
00223 bool operator!=(const ListConstIterator<E> &it) const {
00224 return m_pX != it.m_pX;
00225 }
00226
00228 ListConstIterator<E> succ() const { return m_pX->m_next; }
00229
00231 ListConstIterator<E> pred() const { return m_pX->m_prev; }
00232
00234 const E &operator*() const { return m_pX->m_x; }
00235
00237 ListConstIterator<E> &operator=(const ListConstIterator<E> &it) {
00238 m_pX = it.m_pX;
00239 return *this;
00240 }
00241
00243 ListConstIterator<E> &operator++() {
00244 m_pX = m_pX->m_next;
00245 return *this;
00246 }
00247
00249 ListConstIterator<E> operator++(int) {
00250 ListConstIterator<E> it = *this;
00251 m_pX = m_pX->m_next;
00252 return it;
00253 }
00254
00256 ListConstIterator<E> &operator--() {
00257 m_pX = m_pX->m_prev;
00258 return *this;
00259 }
00260
00262 ListConstIterator<E> operator--(int) {
00263 ListConstIterator<E> it = *this;
00264 m_pX = m_pX->m_prev;
00265 return it;
00266 }
00267
00268 OGDF_NEW_DELETE
00269 };
00270
00271
00272
00274
00281 template<class E> class ListPure {
00282 protected:
00283
00284 ListElement<E> *m_head;
00285 ListElement<E> *m_tail;
00286
00287 public:
00289 ListPure() : m_head(0), m_tail(0) { }
00290
00292 ListPure(const ListPure<E> &L) : m_head(0), m_tail(0) {
00293 copy(L);
00294 }
00295
00296
00297 ~ListPure() { clear(); }
00298
00299 typedef E value_type;
00300 typedef ListElement<E> element_type;
00301 typedef ListConstIterator<E> const_iterator;
00302 typedef ListIterator<E> iterator;
00303
00305 bool empty() const { return m_head == 0; }
00306
00308
00311 int size() const {
00312 int count = 0;
00313 for (ListElement<E> *pX = m_head; pX; pX = pX->m_next)
00314 ++count;
00315 return count;
00316 }
00317
00319
00322 const ListConstIterator<E> begin() const { return m_head; }
00324
00327 ListIterator<E> begin() { return m_head; }
00328
00330
00333 ListConstIterator<E> end() const { return ListConstIterator<E>(); }
00335
00338 ListIterator<E> end() { return ListIterator<E>(); }
00339
00341
00344 const ListConstIterator<E> rbegin() const { return m_tail; }
00346
00349 ListIterator<E> rbegin() { return m_tail; }
00350
00352
00355 ListConstIterator<E> rend() const { return ListConstIterator<E>(); }
00357
00360 ListIterator<E> rend() { return ListIterator<E>(); }
00361
00363
00366 const E &front() const {
00367 OGDF_ASSERT(m_head != 0)
00368 return m_head->m_x;
00369 }
00370
00372
00375 E &front() {
00376 OGDF_ASSERT(m_head != 0)
00377 return m_head->m_x;
00378 }
00379
00381
00384 const E &back() const {
00385 OGDF_ASSERT(m_tail != 0)
00386 return m_tail->m_x;
00387 }
00388
00390
00393 E &back() {
00394 OGDF_ASSERT(m_tail != 0)
00395 return m_tail->m_x;
00396 }
00397
00399
00402 ListConstIterator<E> cyclicSucc(ListConstIterator<E> it) const {
00403 const ListElement<E> *pX = it;
00404 return (pX->m_next) ? pX->m_next : m_head;
00405 }
00406
00408
00411 ListIterator<E> cyclicSucc(ListIterator<E> it) {
00412 OGDF_ASSERT(it.valid())
00413 ListElement<E> *pX = it;
00414 return (pX->m_next) ? pX->m_next : m_head;
00415 }
00416
00418
00421 ListConstIterator<E> cyclicPred(ListConstIterator<E> it) const {
00422 OGDF_ASSERT(it.valid())
00423 const ListElement<E> *pX = it;
00424 return (pX->m_prev) ? pX->m_prev : m_tail;
00425 }
00426
00428
00431 ListIterator<E> cyclicPred(ListIterator<E> it) {
00432 OGDF_ASSERT(it.valid())
00433 ListElement<E> *pX = it;
00434 return (pX->m_prev) ? pX->m_prev : m_tail;
00435 }
00436
00438
00441 ListConstIterator<E> get(int pos) const {
00442 ListElement<E> *pX;
00443 for(pX = m_head; pX != 0; pX = pX->m_next)
00444 if (pos-- == 0) break;
00445 return pX;
00446 }
00447
00449
00452 ListIterator<E> get(int pos) {
00453 ListElement<E> *pX;
00454 for(pX = m_head; pX != 0; pX = pX->m_next)
00455 if (pos-- == 0) break;
00456 return pX;
00457 }
00458
00460
00464 int pos(ListConstIterator<E> it) const {
00465 OGDF_ASSERT(it.valid())
00466 int p = 0;
00467 for(ListElement<E> *pX = m_head; pX != 0; pX = pX->m_next, ++p)
00468 if (pX == it) break;
00469 return p;
00470 }
00471
00473 ListPure<E> &operator=(const ListPure<E> &L) {
00474 clear(); copy(L);
00475 return *this;
00476 }
00477
00479 bool operator==(const ListPure<E> &L) const {
00480 ListElement<E> *pX = m_head, *pY = L.m_head;
00481 while(pX != 0 && pY != 0) {
00482 if(pX->m_x != pY->m_x)
00483 return false;
00484 pX = pX->m_next;
00485 pY = pY->m_next;
00486 }
00487 return (pX == 0 && pY == 0);
00488 }
00489
00491 bool operator!=(const ListPure<E> &L) const {
00492 return !operator==(L);
00493 }
00494
00496 ListIterator<E> pushFront(const E &x) {
00497 ListElement<E> *pX = OGDF_NEW ListElement<E>(x,m_head,0);
00498 if (m_head)
00499 m_head = m_head->m_prev = pX;
00500 else
00501 m_head = m_tail = pX;
00502 return m_head;
00503 }
00504
00506 ListIterator<E> pushBack(const E &x) {
00507 ListElement<E> *pX = OGDF_NEW ListElement<E>(x,0,m_tail);
00508 if (m_head)
00509 m_tail = m_tail->m_next = pX;
00510 else
00511 m_tail = m_head = pX;
00512 return m_tail;
00513 }
00514
00516
00523 ListIterator<E> insert(const E &x, ListIterator<E> it, Direction dir = after) {
00524 OGDF_ASSERT(it.valid())
00525 OGDF_ASSERT(dir == after || dir == before)
00526 ListElement<E> *pY = it, *pX;
00527 if (dir == after) {
00528 ListElement<E> *pYnext = pY->m_next;
00529 pY->m_next = pX = OGDF_NEW ListElement<E>(x,pYnext,pY);
00530 if (pYnext) pYnext->m_prev = pX;
00531 else m_tail = pX;
00532 } else {
00533 ListElement<E> *pYprev = pY->m_prev;
00534 pY->m_prev = pX = OGDF_NEW ListElement<E>(x,pY,pYprev);
00535 if (pYprev) pYprev->m_next = pX;
00536 else m_head = pX;
00537 }
00538 return pX;
00539 }
00540
00542
00545 ListIterator<E> insertBefore(const E &x, ListIterator<E> it) {
00546 OGDF_ASSERT(it.valid())
00547 ListElement<E> *pY = it, *pX;
00548 ListElement<E> *pYprev = pY->m_prev;
00549 pY->m_prev = pX = OGDF_NEW ListElement<E>(x,pY,pYprev);
00550 if (pYprev) pYprev->m_next = pX;
00551 else m_head = pX;
00552 return pX;
00553 }
00554
00556
00559 ListIterator<E> insertAfter(const E &x, ListIterator<E> it) {
00560 OGDF_ASSERT(it.valid())
00561 ListElement<E> *pY = it, *pX;
00562 ListElement<E> *pYnext = pY->m_next;
00563 pY->m_next = pX = OGDF_NEW ListElement<E>(x,pYnext,pY);
00564 if (pYnext) pYnext->m_prev = pX;
00565 else m_tail = pX;
00566 return pX;
00567 }
00568
00570
00573 void popFront() {
00574 OGDF_ASSERT(m_head != 0)
00575 ListElement<E> *pX = m_head;
00576 m_head = m_head->m_next;
00577 delete pX;
00578 if (m_head) m_head->m_prev = 0;
00579 else m_tail = 0;
00580 }
00581
00583
00586 E popFrontRet() {
00587 E el = front();
00588 popFront();
00589 return el;
00590 }
00591
00593
00596 void popBack() {
00597 OGDF_ASSERT(m_tail != 0)
00598 ListElement<E> *pX = m_tail;
00599 m_tail = m_tail->m_prev;
00600 delete pX;
00601 if (m_tail) m_tail->m_next = 0;
00602 else m_head = 0;
00603 }
00604
00606
00609 E popBackRet() {
00610 E el = back();
00611 popBack();
00612 return el;
00613 }
00614
00616
00619 void del(ListIterator<E> it) {
00620 OGDF_ASSERT(it.valid())
00621 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00622 delete pX;
00623 if (pPrev) pPrev->m_next = pNext;
00624 else m_head = pNext;
00625 if (pNext) pNext->m_prev = pPrev;
00626 else m_tail = pPrev;
00627 }
00628
00630
00633 void exchange(ListIterator<E> it1, ListIterator<E> it2) {
00634 OGDF_ASSERT(it1.valid() && it2.valid() && it1 != it2)
00635 ListElement<E> *pX = it1, *pY = it2;
00636
00637 std::swap(pX->m_next,pY->m_next);
00638 std::swap(pX->m_prev,pY->m_prev);
00639
00640 if(pX->m_next == pX) {
00641 pX->m_next = pY; pY->m_prev = pX;
00642 }
00643 if(pX->m_prev == pX) {
00644 pX->m_prev = pY; pY->m_next = pX;
00645 }
00646
00647 if(pX->m_prev) pX->m_prev->m_next = pX;
00648 else m_head = pX;
00649
00650 if(pY->m_prev) pY->m_prev->m_next = pY;
00651 else m_head = pY;
00652
00653 if(pX->m_next) pX->m_next->m_prev = pX;
00654 else m_tail = pX;
00655
00656 if(pY->m_next) pY->m_next->m_prev = pY;
00657 else m_tail = pY;
00658 }
00659
00661
00664 void moveToFront(ListIterator<E> it) {
00665 OGDF_ASSERT(it.valid())
00666
00667 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00668
00669 if (!pPrev) return;
00670
00671
00672 if (pPrev) pPrev->m_next = pNext;
00673 if (pNext) pNext->m_prev = pPrev;
00674 else m_tail = pPrev;
00675
00676 pX->m_prev = 0;
00677 pX->m_next = m_head;
00678 m_head = m_head->m_prev = pX;
00679 }
00680
00682
00685 void moveToBack(ListIterator<E> it) {
00686 OGDF_ASSERT(it.valid())
00687
00688 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00689
00690 if (!pNext) return;
00691
00692
00693 if (pPrev) pPrev->m_next = pNext;
00694 else m_head = pNext;
00695 if (pNext) pNext->m_prev = pPrev;
00696
00697 pX->m_prev = m_tail;
00698 pX->m_next = 0;
00699 m_tail = m_tail->m_next = pX;
00700 }
00701
00703
00706 void moveToSucc(ListIterator<E> it, ListIterator<E> itBefore) {
00707 OGDF_ASSERT(it.valid() && itBefore.valid())
00708
00709 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00710
00711 ListElement<E> *pY = itBefore;
00712 if(pX == pY || pPrev == pY) return;
00713
00714
00715 if (pPrev) pPrev->m_next = pNext;
00716 else m_head = pNext;
00717 if (pNext) pNext->m_prev = pPrev;
00718 else m_tail = pPrev;
00719
00720 ListElement<E> *pYnext = pX->m_next = pY->m_next;
00721 (pX->m_prev = pY)->m_next = pX;
00722 if (pYnext) pYnext->m_prev = pX;
00723 else m_tail = pX;
00724 }
00725
00727
00730 void moveToPrec(ListIterator<E> it, ListIterator<E> itAfter) {
00731 OGDF_ASSERT(it.valid() && itAfter.valid())
00732
00733 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00734
00735 ListElement<E> *pY = itAfter;
00736 if(pX == pY || pNext == pY) return;
00737
00738
00739 if (pPrev) pPrev->m_next = pNext;
00740 else m_head = pNext;
00741 if (pNext) pNext->m_prev = pPrev;
00742 else m_tail = pPrev;
00743
00744 ListElement<E> *pYprev = pX->m_prev = pY->m_prev;
00745 (pX->m_next = pY)->m_prev = pX;
00746 if (pYprev) pYprev->m_next = pX;
00747 else m_head = pX;
00748 }
00749
00751
00754 void moveToFront(ListIterator<E> it, ListPure<E> &L2) {
00755 OGDF_ASSERT(it.valid())
00756 OGDF_ASSERT(this != &L2)
00757
00758 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00759 if (pPrev) pPrev->m_next = pNext;
00760 else m_head = pNext;
00761 if (pNext) pNext->m_prev = pPrev;
00762 else m_tail = pPrev;
00763
00764 pX->m_prev = 0;
00765 if ((pX->m_next = L2.m_head) != 0)
00766 L2.m_head = L2.m_head->m_prev = pX;
00767 else
00768 L2.m_head = L2.m_tail = pX;
00769 }
00770
00772
00775 void moveToBack(ListIterator<E> it, ListPure<E> &L2) {
00776 OGDF_ASSERT(it.valid())
00777 OGDF_ASSERT(this != &L2)
00778
00779 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00780 if (pPrev) pPrev->m_next = pNext;
00781 else m_head = pNext;
00782 if (pNext) pNext->m_prev = pPrev;
00783 else m_tail = pPrev;
00784
00785 pX->m_next = 0;
00786 if ((pX->m_prev = L2.m_tail) != 0)
00787 L2.m_tail = L2.m_tail->m_next = pX;
00788 else
00789 L2.m_head = L2.m_tail = pX;
00790 }
00791
00793
00797 void moveToSucc(ListIterator<E> it, ListPure<E> &L2, ListIterator<E> itBefore) {
00798 OGDF_ASSERT(it.valid() && itBefore.valid())
00799 OGDF_ASSERT(this != &L2)
00800
00801 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00802 if (pPrev) pPrev->m_next = pNext;
00803 else m_head = pNext;
00804 if (pNext) pNext->m_prev = pPrev;
00805 else m_tail = pPrev;
00806
00807 ListElement<E> *pY = itBefore;
00808 ListElement<E> *pYnext = pX->m_next = pY->m_next;
00809 (pX->m_prev = pY)->m_next = pX;
00810 if (pYnext) pYnext->m_prev = pX;
00811 else L2.m_tail = pX;
00812 }
00813
00815
00819 void moveToPrec(ListIterator<E> it, ListPure<E> &L2, ListIterator<E> itAfter) {
00820 OGDF_ASSERT(it.valid() && itAfter.valid())
00821 OGDF_ASSERT(this != &L2)
00822
00823 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00824 if (pPrev) pPrev->m_next = pNext;
00825 else m_head = pNext;
00826 if (pNext) pNext->m_prev = pPrev;
00827 else m_tail = pPrev;
00828
00829 ListElement<E> *pY = itAfter;
00830 ListElement<E> *pYprev = pX->m_prev = pY->m_prev;
00831 (pX->m_next = pY)->m_prev = pX;
00832 if (pYprev) pYprev->m_next = pX;
00833 else L2.m_head = pX;
00834 }
00835
00837 void conc(ListPure<E> &L2) {
00838 OGDF_ASSERT(this != &L2)
00839 if (m_head)
00840 m_tail->m_next = L2.m_head;
00841 else
00842 m_head = L2.m_head;
00843 if (L2.m_head) {
00844 L2.m_head->m_prev = m_tail;
00845 m_tail = L2.m_tail;
00846 }
00847 L2.m_head = L2.m_tail = 0;
00848 }
00849
00851 void concFront(ListPure<E> &L2) {
00852 OGDF_ASSERT(this != &L2)
00853 if (m_head)
00854 m_head->m_prev = L2.m_tail;
00855 else
00856 m_tail = L2.m_tail;
00857 if (L2.m_head) {
00858 L2.m_tail->m_next = m_head;
00859 m_head = L2.m_head;
00860 }
00861 L2.m_head = L2.m_tail = 0;
00862 }
00863
00865
00868 void exchange(ListPure<E>& L2) {
00869 ListElement<E>* t;
00870 t = this->m_head;
00871 this->m_head = L2.m_head;
00872 L2.m_head = t;
00873 t = this->m_tail;
00874 this->m_tail = L2.m_tail;
00875 L2.m_tail = t;
00876 }
00877
00879
00888 void split(ListIterator<E> it,ListPure<E> &L1,ListPure<E> &L2,Direction dir = before) {
00889 if (&L1 != this) L1.clear();
00890 if (&L2 != this) L2.clear();
00891
00892 if (it.valid()){
00893 L1.m_head = m_head;
00894 L2.m_tail = m_tail;
00895 if (dir == before){
00896 L2.m_head = it;
00897 L1.m_tail = L2.m_head->m_prev;
00898 }
00899 else {
00900 L1.m_tail = it;
00901 L2.m_head = L1.m_tail->m_next;
00902 }
00903 L2.m_head->m_prev = L1.m_tail->m_next = 0;
00904
00905 } else {
00906 L1.m_head = L1.m_tail = 0;
00907 L2.m_head = m_head;
00908 L2.m_tail = m_tail;
00909 }
00910
00911 if (this != &L1 && this != &L2) {
00912 m_head = m_tail = 0;
00913 }
00914 }
00915
00917 void splitAfter(ListIterator<E> it, ListPure<E> &L2) {
00918 OGDF_ASSERT(it.valid())
00919 OGDF_ASSERT(this != &L2)
00920 L2.clear();
00921 ListElement<E> *pX = it;
00922 if (pX != m_tail) {
00923 (L2.m_head = pX->m_next)->m_prev = 0;
00924 pX->m_next = 0;
00925 L2.m_tail = m_tail;
00926 m_tail = pX;
00927 }
00928 }
00929
00931 void splitBefore(ListIterator<E> it, ListPure<E> &L2) {
00932 OGDF_ASSERT(it.valid())
00933 OGDF_ASSERT(this != &L2)
00934 L2.clear();
00935 ListElement<E> *pX = it;
00936 L2.m_head = pX; L2.m_tail = m_tail;
00937 if ((m_tail = pX->m_prev) == 0)
00938 m_head = 0;
00939 else
00940 m_tail->m_next = 0;
00941 pX->m_prev = 0;
00942 }
00943
00945 void reverse() {
00946 ListElement<E> *pX = m_head;
00947 m_head = m_tail;
00948 m_tail = pX;
00949 while(pX) {
00950 ListElement<E> *pY = pX->m_next;
00951 pX->m_next = pX->m_prev;
00952 pX = pX->m_prev = pY;
00953 }
00954 }
00955
00957 void clear() {
00958 if (m_head == 0) return;
00959
00960 #if (_MSC_VER == 1100)
00961
00962
00963 while (!empty())
00964 popFront();
00965
00966 #else
00967
00968 if (doDestruction((E*)0)) {
00969 for(ListElement<E> *pX = m_head; pX != 0; pX = pX->m_next)
00970 pX->m_x.~E();
00971 }
00972 OGDF_ALLOCATOR::deallocateList(sizeof(ListElement<E>),m_head,m_tail);
00973
00974 #endif
00975
00976 m_head = m_tail = 0;
00977 }
00978
00980 void quicksort() {
00981 ogdf::quicksortTemplate(*this);
00982 }
00983
00985 template<class COMPARER>
00986 void quicksort(const COMPARER &comp) {
00987 ogdf::quicksortTemplate(*this,comp);
00988 }
00989
00991
00998 void bucketSort(int l, int h, BucketFunc<E> &f);
00999
01001 void permute() {
01002 permute(size());
01003 }
01004
01006 int search (const E& e) const {
01007 int x = 0;
01008 for(ListConstIterator<E> i = begin(); i.valid(); ++i, ++x)
01009 if(*i == e) return x;
01010 return -1;
01011 }
01012
01014 template<class COMPARER>
01015 int search (const E& e, const COMPARER &comp) const {
01016 int x = 0;
01017 for(ListConstIterator<E> i = begin(); i.valid(); ++i, ++x)
01018 if(comp.equal(*i,e)) return x;
01019 return -1;
01020 }
01021
01022 protected:
01023 void copy(const ListPure<E> &L) {
01024 for(ListElement<E> *pX = L.m_head; pX != 0; pX = pX->m_next)
01025 pushBack(pX->m_x);
01026 }
01027
01028 void permute(const int n);
01029
01030 OGDF_NEW_DELETE
01031 };
01032
01033
01034
01036
01060 #define forall_listiterators(type, it, L) \
01061 for(ListConstIterator< type > it = (L).begin(); it.valid(); ++it)
01062
01064
01068 #define forall_rev_listiterators(type, it, L) \
01069 for(ListConstIterator< type > it = (L).rbegin(); it.valid(); --it)
01070
01072
01076 #define forall_nonconst_listiterators(type, it, L) \
01077 for(ListIterator< type > it = (L).begin(); it.valid(); ++it)
01078
01080
01084 #define forall_rev_nonconst_listiterators(type, it, L) \
01085 for(ListIterator< type > it = (L).rbegin(); it.valid(); --it)
01086
01088
01092 #define forall_slistiterators(type, it, L) \
01093 for(SListConstIterator< type > it = (L).begin(); it.valid(); ++it)
01094
01096
01100 #define forall_nonconst_slistiterators(type, it, L) \
01101 for(SListIterator< type > it = (L).begin(); it.valid(); ++it)
01102
01103
01104
01105
01107
01116 template<class E>
01117 class List : private ListPure<E> {
01118
01119 int m_count;
01120
01121 public:
01123 List() : m_count(0) { }
01124
01126 List(const List<E> &L) : ListPure<E>(L), m_count(L.m_count) { }
01127
01128
01129 ~List() { }
01130
01131 typedef E value_type;
01132 typedef ListElement<E> element_type;
01133 typedef ListConstIterator<E> const_iterator;
01134 typedef ListIterator<E> iterator;
01135
01137 bool empty() const { return ListPure<E>::empty(); }
01138
01139
01140 int size() const { return m_count; }
01141
01142
01143 const ListConstIterator<E> begin() const { return ListPure<E>::begin(); }
01144
01145 ListIterator<E> begin() { return ListPure<E>::begin(); }
01146
01147
01148 ListConstIterator<E> end() const { return ListConstIterator<E>(); }
01149
01150 ListIterator<E> end() { return ListIterator<E>(); }
01151
01152
01153 const ListConstIterator<E> rbegin() const { return ListPure<E>::rbegin(); }
01154
01155 ListIterator<E> rbegin() { return ListPure<E>::rbegin(); }
01156
01157
01158 ListConstIterator<E> rend() const { return ListConstIterator<E>(); }
01159
01160 ListIterator<E> rend() { return ListIterator<E>(); }
01161
01162
01163 const E &front() const { return ListPure<E>::front(); }
01164
01165 E &front() { return ListPure<E>::front(); }
01166
01167
01168 const E &back() const { return ListPure<E>::back(); }
01169
01170 E &back() { return ListPure<E>::back(); }
01171
01172
01173 ListConstIterator<E> cyclicSucc(ListConstIterator<E> it) const {
01174 return ListPure<E>::cyclicSucc(it);
01175 }
01176
01177
01178 ListIterator<E> cyclicSucc(ListIterator<E> it) {
01179 return ListPure<E>::cyclicSucc(it);
01180 }
01181
01182
01183 ListConstIterator<E> cyclicPred(ListConstIterator<E> it) const {
01184 return ListPure<E>::cyclicPred(it);
01185 }
01186
01187
01188 ListIterator<E> cyclicPred(ListIterator<E> it) {
01189 return ListPure<E>::cyclicPred(it);
01190 }
01191
01192
01193 ListConstIterator<E> get(int pos) const {
01194 OGDF_ASSERT(0 <= pos && pos < m_count)
01195 return ListPure<E>::get(pos);
01196 }
01197
01198
01199 ListIterator<E> get(int pos) {
01200 OGDF_ASSERT(0 <= pos && pos < m_count)
01201 return ListPure<E>::get(pos);
01202 }
01203
01204
01205 int pos(ListConstIterator<E> it) const {
01206 return ListPure<E>::pos(it);
01207 }
01208
01209
01210 List<E> &operator=(const List<E> &L) {
01211 ListPure<E>::operator=(L);
01212 m_count = L.m_count;
01213 return *this;
01214 }
01215
01217 bool operator==(const List<E> &L) const {
01218 if(m_count != L.m_count)
01219 return false;
01220
01221 ListElement<E> *pX = ListPure<E>::m_head, *pY = L.m_head;
01222 while(pX != 0) {
01223 if(pX->m_x != pY->m_x)
01224 return false;
01225 pX = pX->m_next;
01226 pY = pY->m_next;
01227 }
01228 return true;
01229 }
01230
01232 bool operator!=(const List<E> &L) const {
01233 return !operator==(L);
01234 }
01235
01236
01237 ListIterator<E> pushFront(const E &x) {
01238 ++m_count;
01239 return ListPure<E>::pushFront(x);
01240 }
01241
01242
01243 ListIterator<E> pushBack(const E &x) {
01244 ++m_count;
01245 return ListPure<E>::pushBack(x);
01246 }
01247
01248
01249 ListIterator<E> insert(const E &x, ListIterator<E> it, Direction dir = after) {
01250 ++m_count;
01251 return ListPure<E>::insert(x,it,dir);
01252 }
01253
01254
01255 ListIterator<E> insertBefore(const E &x, ListIterator<E> it) {
01256 ++m_count;
01257 return ListPure<E>::insertBefore(x,it);
01258 }
01259
01260
01261 ListIterator<E> insertAfter(const E &x, ListIterator<E> it) {
01262 ++m_count;
01263 return ListPure<E>::insertAfter(x,it);
01264 }
01265
01266
01267 void popFront() {
01268 --m_count;
01269 ListPure<E>::popFront();
01270 }
01271
01272
01273 E popFrontRet() {
01274 E el = front();
01275 popFront();
01276 return el;
01277 }
01278
01279
01280 void popBack() {
01281 --m_count;
01282 ListPure<E>::popBack();
01283 }
01284
01285
01286 E popBackRet() {
01287 E el = back();
01288 popBack();
01289 return el;
01290 }
01291
01292 void exchange(ListIterator<E> it1, ListIterator<E> it2) {
01293 ListPure<E>::exchange(it1,it2);
01294 }
01295
01297
01300 void moveToFront(ListIterator<E> it) {
01301 ListPure<E>::moveToFront(it);
01302 }
01304
01307 void moveToBack(ListIterator<E> it) {
01308 ListPure<E>::moveToBack(it);
01309 }
01311
01314 void moveToSucc(ListIterator<E> it, ListIterator<E> itBefore) {
01315 ListPure<E>::moveToSucc(it,itBefore);
01316 }
01318
01321 void moveToPrec(ListIterator<E> it, ListIterator<E> itAfter) {
01322 ListPure<E>::moveToPrec(it,itAfter);
01323 }
01324
01326
01329 void moveToFront(ListIterator<E> it, List<E> &L2) {
01330 ListPure<E>::moveToFront(it,L2);
01331 --m_count; ++L2.m_count;
01332 }
01334
01337 void moveToBack(ListIterator<E> it, List<E> &L2) {
01338 ListPure<E>::moveToBack(it,L2);
01339 --m_count; ++L2.m_count;
01340 }
01341
01343
01347 void moveToSucc(ListIterator<E> it, List<E> &L2, ListIterator<E> itBefore) {
01348 ListPure<E>::moveToSucc(it,L2,itBefore);
01349 --m_count; ++L2.m_count;
01350 }
01352
01356 void moveToPrec(ListIterator<E> it, List<E> &L2, ListIterator<E> itAfter) {
01357 ListPure<E>::moveToPrec(it,L2,itAfter);
01358 --m_count; ++L2.m_count;
01359 }
01360
01361
01362 void del(ListIterator<E> it) {
01363 --m_count;
01364 ListPure<E>::del(it);
01365 }
01366
01368 void conc(List<E> &L2) {
01369 ListPure<E>::conc(L2);
01370 m_count += L2.m_count;
01371 L2.m_count = 0;
01372 }
01373
01375 void concFront(List<E> &L2) {
01376 ListPure<E>::concFront(L2);
01377 m_count += L2.m_count;
01378 L2.m_count = 0;
01379 }
01380
01382
01385 void exchange(List<E>& L2) {
01386 ListPure<E>::exchange(L2);
01387 int t = this->m_count;
01388 this->m_count = L2.m_count;
01389 L2.m_count = t;
01390 }
01391
01393
01401 void split(ListIterator<E> it,List<E> &L1,List<E> &L2,Direction dir = before) {
01402 ListPure<E>::split(it,L1,L2,dir);
01403 int countL = m_count, countL1 = 0;
01404 for(ListElement<E> *pX = L1.m_head; pX != 0; pX = pX->m_next)
01405 ++countL1;
01406
01407 L1.m_count = countL1;
01408 L2.m_count = countL - countL1;
01409 if (this->m_head == 0) m_count = 0;
01410 }
01411
01412
01413 void reverse() { ListPure<E>::reverse(); }
01414
01415
01416 void clear() {
01417 m_count = 0;
01418 ListPure<E>::clear();
01419 }
01420
01422 const ListPure<E> &getListPure() const { return *this; }
01423
01424
01425 void quicksort() {
01426 ogdf::quicksortTemplate(*this);
01427 }
01428
01429
01430 template<class COMPARER>
01431 void quicksort(const COMPARER &comp) {
01432 ogdf::quicksortTemplate(*this,comp);
01433 }
01434
01435
01436 void bucketSort(int l, int h, BucketFunc<E> &f) {
01437 ListPure<E>::bucketSort(l,h,f);
01438 }
01439
01440
01441 void permute() {
01442 ListPure<E>::permute(m_count);
01443 }
01444
01445 int search (const E& e) const {
01446 return ListPure<E>::search(e);
01447 }
01448 template<class COMPARER>
01449 int search (const E& e, const COMPARER &comp) const {
01450 return ListPure<E>::search(e, comp);
01451 }
01452
01453
01454 OGDF_NEW_DELETE
01455 };
01456
01457
01458
01459 template<class E>
01460 void ListPure<E>::bucketSort(int l, int h, BucketFunc<E> &f)
01461 {
01462 if (m_head == m_tail) return;
01463
01464 Array<ListElement<E> *> head(l,h,0), tail(l,h);
01465
01466 ListElement<E> *pX;
01467 for (pX = m_head; pX; pX = pX->m_next) {
01468 int i = f.getBucket(pX->m_x);
01469 if (head[i])
01470 tail[i] = ((pX->m_prev = tail[i])->m_next = pX);
01471 else
01472 head[i] = tail[i] = pX;
01473 }
01474
01475 ListElement<E> *pY = 0;
01476 for (int i = l; i <= h; i++) {
01477 pX = head[i];
01478 if (pX) {
01479 if (pY) {
01480 (pY->m_next = pX)->m_prev = pY;
01481 } else
01482 (m_head = pX)->m_prev = 0;
01483 pY = tail[i];
01484 }
01485 }
01486
01487 m_tail = pY;
01488 pY->m_next = 0;
01489 }
01490
01491
01492
01493 template<class E>
01494 void ListPure<E>::permute(const int n)
01495 {
01496 Array<ListElement<E> *> A(n+2);
01497 A[0] = A[n+1] = 0;
01498
01499 int i = 1;
01500 ListElement<E> *pX;
01501 for (pX = m_head; pX; pX = pX->m_next)
01502 A[i++] = pX;
01503
01504 A.permute(1,n);
01505
01506 for (i = 1; i <= n; i++) {
01507 pX = A[i];
01508 pX->m_next = A[i+1];
01509 pX->m_prev = A[i-1];
01510 }
01511
01512 m_head = A[1];
01513 m_tail = A[n];
01514 }
01515
01516
01517
01518 template<class E>
01519 void print(ostream &os, const ListPure<E> &L, char delim = ' ')
01520 {
01521 ListConstIterator<E> pX = L.begin();
01522 if (pX.valid()) {
01523 os << *pX;
01524 for(++pX; pX.valid(); ++pX)
01525 os << delim << *pX;
01526 }
01527 }
01528
01529
01530 template<class E>
01531 void print(ostream &os, const List<E> &L, char delim = ' ')
01532 {
01533 print(os, L.getListPure(), delim);
01534 }
01535
01536
01537 template<class E>
01538 ostream &operator<<(ostream &os, const ListPure<E> &L)
01539 {
01540 print(os,L);
01541 return os;
01542 }
01543
01544
01545 template<class E>
01546 ostream &operator<<(ostream &os, const List<E> &L)
01547 {
01548 return os << L.getListPure();
01549 }
01550
01551
01552 }
01553
01554
01555 #endif