00001
00002
00003
00004
00005
00006
00007
00008
00050 #ifdef _MSC_VER
00051 #pragma once
00052 #endif
00053
00054 #ifndef OGDF_LIST_H
00055 #define OGDF_LIST_H
00056
00057
00058 #include <ogdf/internal/basic/list_templates.h>
00059
00060
00061 namespace ogdf {
00062
00063
00064 template<class E> class List;
00065 template<class E> class ListPure;
00066 template<class E> class ListIterator;
00067 template<class E> class ListConstIterator;
00068
00069
00071 template<class E>
00072 class ListElement {
00073 friend class ListPure<E>;
00074 friend class List<E>;
00075 friend class ListIterator<E>;
00076 friend class ListConstIterator<E>;
00077
00078 ListElement<E> *m_next;
00079 ListElement<E> *m_prev;
00080 E m_x;
00081
00083 ListElement() : m_next(0), m_prev(0) { }
00085 ListElement(const E &x) : m_next(0), m_prev(0), m_x(x) { }
00087 ListElement(const E &x, ListElement<E> *next, ListElement<E> *prev) :
00088 m_next(next), m_prev(prev), m_x(x) { }
00089
00090 OGDF_NEW_DELETE
00091 };
00092
00093
00094
00096
00102 template<class E> class ListIterator {
00103 ListElement<E> *m_pX;
00104
00105 friend class ListConstIterator<E>;
00106 friend class ListPure<E>;
00107
00109 operator ListElement<E> *() { return m_pX; }
00111 operator const ListElement<E> *() const { return m_pX; }
00112
00113 public:
00115 ListIterator() : m_pX(0) { }
00117 ListIterator(ListElement<E> *pX) : m_pX(pX) { }
00119 ListIterator(const ListIterator<E> &it) : m_pX(it.m_pX) { }
00120
00122 bool valid() const { return m_pX != 0; }
00123
00125 bool operator==(const ListIterator<E> &it) const {
00126 return m_pX == it.m_pX;
00127 }
00128
00130 bool operator!=(const ListIterator<E> &it) const {
00131 return m_pX != it.m_pX;
00132 }
00133
00135 ListIterator<E> succ() const { return m_pX->m_next; }
00136
00138 ListIterator<E> pred() const { return m_pX->m_prev; }
00139
00141 E &operator*() const { return m_pX->m_x; }
00142
00144 ListIterator<E> &operator=(const ListIterator<E> &it) {
00145 m_pX = it.m_pX;
00146 return *this;
00147 }
00148
00150 ListIterator<E> &operator++() {
00151 m_pX = m_pX->m_next;
00152 return *this;
00153 }
00154
00156 ListIterator<E> operator++(int) {
00157 ListIterator<E> it = *this;
00158 m_pX = m_pX->m_next;
00159 return it;
00160 }
00161
00163 ListIterator<E> &operator--() {
00164 m_pX = m_pX->m_prev;
00165 return *this;
00166 }
00167
00169 ListIterator<E> operator--(int) {
00170 ListIterator<E> it = *this;
00171 m_pX = m_pX->m_prev;
00172 return it;
00173 }
00174
00175 OGDF_NEW_DELETE
00176 };
00177
00178
00179
00180
00181
00182
00183
00185
00192 template<class E> class ListConstIterator {
00193 const ListElement<E> *m_pX;
00194
00195 friend class ListPure<E>;
00196
00198 operator const ListElement<E> *() { return m_pX; }
00199
00200 public:
00202 ListConstIterator() : m_pX(0) { }
00203
00205 ListConstIterator(const ListElement<E> *pX) : m_pX(pX) { }
00206
00208 ListConstIterator(const ListIterator<E> &it) : m_pX((const ListElement<E> *)it) { }
00210 ListConstIterator(const ListConstIterator &it) : m_pX(it.m_pX) { }
00211
00213 bool valid() const { return m_pX != 0; }
00214
00216 bool operator==(const ListConstIterator<E> &it) const {
00217 return m_pX == it.m_pX;
00218 }
00219
00221 bool operator!=(const ListConstIterator<E> &it) const {
00222 return m_pX != it.m_pX;
00223 }
00224
00226 ListConstIterator<E> succ() const { return m_pX->m_next; }
00227
00229 ListConstIterator<E> pred() const { return m_pX->m_prev; }
00230
00232 const E &operator*() const { return m_pX->m_x; }
00233
00235 ListConstIterator<E> &operator=(const ListConstIterator<E> &it) {
00236 m_pX = it.m_pX;
00237 return *this;
00238 }
00239
00241 ListConstIterator<E> &operator++() {
00242 m_pX = m_pX->m_next;
00243 return *this;
00244 }
00245
00247 ListConstIterator<E> operator++(int) {
00248 ListConstIterator<E> it = *this;
00249 m_pX = m_pX->m_next;
00250 return it;
00251 }
00252
00254 ListConstIterator<E> &operator--() {
00255 m_pX = m_pX->m_prev;
00256 return *this;
00257 }
00258
00260 ListConstIterator<E> operator--(int) {
00261 ListConstIterator<E> it = *this;
00262 m_pX = m_pX->m_prev;
00263 return it;
00264 }
00265
00266 OGDF_NEW_DELETE
00267 };
00268
00269
00270
00272
00279 template<class E> class ListPure {
00280 protected:
00281
00282 ListElement<E> *m_head;
00283 ListElement<E> *m_tail;
00284
00285 public:
00287 ListPure() : m_head(0), m_tail(0) { }
00288
00290 ListPure(const ListPure<E> &L) : m_head(0), m_tail(0) {
00291 copy(L);
00292 }
00293
00294
00295 ~ListPure() { clear(); }
00296
00297 typedef E value_type;
00298 typedef ListElement<E> element_type;
00299 typedef ListConstIterator<E> const_iterator;
00300 typedef ListIterator<E> iterator;
00301
00303 bool empty() const { return m_head == 0; }
00304
00306
00309 int size() const {
00310 int count = 0;
00311 for (ListElement<E> *pX = m_head; pX; pX = pX->m_next)
00312 ++count;
00313 return count;
00314 }
00315
00317
00320 const ListConstIterator<E> begin() const { return m_head; }
00322
00325 ListIterator<E> begin() { return m_head; }
00326
00328
00331 ListConstIterator<E> end() const { return ListConstIterator<E>(); }
00333
00336 ListIterator<E> end() { return ListIterator<E>(); }
00337
00339
00342 const ListConstIterator<E> rbegin() const { return m_tail; }
00344
00347 ListIterator<E> rbegin() { return m_tail; }
00348
00350
00353 ListConstIterator<E> rend() const { return ListConstIterator<E>(); }
00355
00358 ListIterator<E> rend() { return ListIterator<E>(); }
00359
00361
00364 const E &front() const {
00365 OGDF_ASSERT(m_head != 0)
00366 return m_head->m_x;
00367 }
00368
00370
00373 E &front() {
00374 OGDF_ASSERT(m_head != 0)
00375 return m_head->m_x;
00376 }
00377
00379
00382 const E &back() const {
00383 OGDF_ASSERT(m_tail != 0)
00384 return m_tail->m_x;
00385 }
00386
00388
00391 E &back() {
00392 OGDF_ASSERT(m_tail != 0)
00393 return m_tail->m_x;
00394 }
00395
00397
00400 ListConstIterator<E> cyclicSucc(ListConstIterator<E> it) const {
00401 const ListElement<E> *pX = it;
00402 return (pX->m_next) ? pX->m_next : m_head;
00403 }
00404
00406
00409 ListIterator<E> cyclicSucc(ListIterator<E> it) {
00410 OGDF_ASSERT(it.valid())
00411 ListElement<E> *pX = it;
00412 return (pX->m_next) ? pX->m_next : m_head;
00413 }
00414
00416
00419 ListConstIterator<E> cyclicPred(ListConstIterator<E> it) const {
00420 OGDF_ASSERT(it.valid())
00421 const ListElement<E> *pX = it;
00422 return (pX->m_prev) ? pX->m_prev : m_tail;
00423 }
00424
00426
00429 ListIterator<E> cyclicPred(ListIterator<E> it) {
00430 OGDF_ASSERT(it.valid())
00431 ListElement<E> *pX = it;
00432 return (pX->m_prev) ? pX->m_prev : m_tail;
00433 }
00434
00436
00439 ListConstIterator<E> get(int pos) const {
00440 ListElement<E> *pX;
00441 for(pX = m_head; pX != 0; pX = pX->m_next)
00442 if (pos-- == 0) break;
00443 return pX;
00444 }
00445
00447
00450 ListIterator<E> get(int pos) {
00451 ListElement<E> *pX;
00452 for(pX = m_head; pX != 0; pX = pX->m_next)
00453 if (pos-- == 0) break;
00454 return pX;
00455 }
00456
00458
00462 int pos(ListConstIterator<E> it) const {
00463 OGDF_ASSERT(it.valid())
00464 int p = 0;
00465 for(ListElement<E> *pX = m_head; pX != 0; pX = pX->m_next, ++p)
00466 if (pX == it) break;
00467 return p;
00468 }
00469
00471 ListPure<E> &operator=(const ListPure<E> &L) {
00472 clear(); copy(L);
00473 return *this;
00474 }
00475
00477 ListIterator<E> pushFront(const E &x) {
00478 ListElement<E> *pX = OGDF_NEW ListElement<E>(x,m_head,0);
00479 if (m_head)
00480 m_head = m_head->m_prev = pX;
00481 else
00482 m_head = m_tail = pX;
00483 return m_head;
00484 }
00485
00487 ListIterator<E> pushBack(const E &x) {
00488 ListElement<E> *pX = OGDF_NEW ListElement<E>(x,0,m_tail);
00489 if (m_head)
00490 m_tail = m_tail->m_next = pX;
00491 else
00492 m_tail = m_head = pX;
00493 return m_tail;
00494 }
00495
00497
00504 ListIterator<E> insert(const E &x, ListIterator<E> it, Direction dir = after) {
00505 OGDF_ASSERT(it.valid())
00506 OGDF_ASSERT(dir == after || dir == before)
00507 ListElement<E> *pY = it, *pX;
00508 if (dir == after) {
00509 ListElement<E> *pYnext = pY->m_next;
00510 pY->m_next = pX = OGDF_NEW ListElement<E>(x,pYnext,pY);
00511 if (pYnext) pYnext->m_prev = pX;
00512 else m_tail = pX;
00513 } else {
00514 ListElement<E> *pYprev = pY->m_prev;
00515 pY->m_prev = pX = OGDF_NEW ListElement<E>(x,pY,pYprev);
00516 if (pYprev) pYprev->m_next = pX;
00517 else m_head = pX;
00518 }
00519 return pX;
00520 }
00521
00523
00526 ListIterator<E> insertBefore(const E &x, ListIterator<E> it) {
00527 OGDF_ASSERT(it.valid())
00528 ListElement<E> *pY = it, *pX;
00529 ListElement<E> *pYprev = pY->m_prev;
00530 pY->m_prev = pX = OGDF_NEW ListElement<E>(x,pY,pYprev);
00531 if (pYprev) pYprev->m_next = pX;
00532 else m_head = pX;
00533 return pX;
00534 }
00535
00537
00540 ListIterator<E> insertAfter(const E &x, ListIterator<E> it) {
00541 OGDF_ASSERT(it.valid())
00542 ListElement<E> *pY = it, *pX;
00543 ListElement<E> *pYnext = pY->m_next;
00544 pY->m_next = pX = OGDF_NEW ListElement<E>(x,pYnext,pY);
00545 if (pYnext) pYnext->m_prev = pX;
00546 else m_tail = pX;
00547 return pX;
00548 }
00549
00551
00554 void popFront() {
00555 OGDF_ASSERT(m_head != 0)
00556 ListElement<E> *pX = m_head;
00557 m_head = m_head->m_next;
00558 delete pX;
00559 if (m_head) m_head->m_prev = 0;
00560 else m_tail = 0;
00561 }
00562
00564
00567 E popFrontRet() {
00568 E el = front();
00569 popFront();
00570 return el;
00571 }
00572
00574
00577 void popBack() {
00578 OGDF_ASSERT(m_tail != 0)
00579 ListElement<E> *pX = m_tail;
00580 m_tail = m_tail->m_prev;
00581 delete pX;
00582 if (m_tail) m_tail->m_next = 0;
00583 else m_head = 0;
00584 }
00585
00587
00590 E popBackRet() {
00591 E el = back();
00592 popBack();
00593 return el;
00594 }
00595
00597
00600 void del(ListIterator<E> it) {
00601 OGDF_ASSERT(it.valid())
00602 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00603 delete pX;
00604 if (pPrev) pPrev->m_next = pNext;
00605 else m_head = pNext;
00606 if (pNext) pNext->m_prev = pPrev;
00607 else m_tail = pPrev;
00608 }
00609
00611
00614 void exchange(ListIterator<E> it1, ListIterator<E> it2) {
00615 OGDF_ASSERT(it1.valid() && it2.valid() && it1 != it2)
00616 ListElement<E> *pX = it1, *pY = it2;
00617
00618 swap(pX->m_next,pY->m_next);
00619 swap(pX->m_prev,pY->m_prev);
00620
00621 if(pX->m_next == pX) {
00622 pX->m_next = pY; pY->m_prev = pX;
00623 }
00624 if(pX->m_prev == pX) {
00625 pX->m_prev = pY; pY->m_next = pX;
00626 }
00627
00628 if(pX->m_prev) pX->m_prev->m_next = pX;
00629 else m_head = pX;
00630
00631 if(pY->m_prev) pY->m_prev->m_next = pY;
00632 else m_head = pY;
00633
00634 if(pX->m_next) pX->m_next->m_prev = pX;
00635 else m_tail = pX;
00636
00637 if(pY->m_next) pY->m_next->m_prev = pY;
00638 else m_tail = pY;
00639 }
00640
00642
00645 void moveToFront(ListIterator<E> it) {
00646 OGDF_ASSERT(it.valid())
00647
00648 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00649
00650 if (!pPrev) return;
00651
00652
00653 if (pPrev) pPrev->m_next = pNext;
00654 if (pNext) pNext->m_prev = pPrev;
00655 else m_tail = pPrev;
00656
00657 pX->m_prev = 0;
00658 pX->m_next = m_head;
00659 m_head = m_head->m_prev = pX;
00660 }
00661
00663
00666 void moveToBack(ListIterator<E> it) {
00667 OGDF_ASSERT(it.valid())
00668
00669 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00670
00671 if (!pNext) return;
00672
00673
00674 if (pPrev) pPrev->m_next = pNext;
00675 else m_head = pNext;
00676 if (pNext) pNext->m_prev = pPrev;
00677
00678 pX->m_prev = m_tail;
00679 pX->m_next = 0;
00680 m_tail = m_tail->m_next = pX;
00681 }
00682
00684
00687 void moveToSucc(ListIterator<E> it, ListIterator<E> itBefore) {
00688 OGDF_ASSERT(it.valid() && itBefore.valid())
00689
00690 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00691
00692 ListElement<E> *pY = itBefore;
00693 if(pX == pY || pPrev == pY) return;
00694
00695
00696 if (pPrev) pPrev->m_next = pNext;
00697 else m_head = pNext;
00698 if (pNext) pNext->m_prev = pPrev;
00699 else m_tail = pPrev;
00700
00701 ListElement<E> *pYnext = pX->m_next = pY->m_next;
00702 (pX->m_prev = pY)->m_next = pX;
00703 if (pYnext) pYnext->m_prev = pX;
00704 else m_tail = pX;
00705 }
00706
00708
00711 void moveToPrec(ListIterator<E> it, ListIterator<E> itAfter) {
00712 OGDF_ASSERT(it.valid() && itAfter.valid())
00713
00714 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00715
00716 ListElement<E> *pY = itAfter;
00717 if(pX == pY || pNext == pY) return;
00718
00719
00720 if (pPrev) pPrev->m_next = pNext;
00721 else m_head = pNext;
00722 if (pNext) pNext->m_prev = pPrev;
00723 else m_tail = pPrev;
00724
00725 ListElement<E> *pYprev = pX->m_prev = pY->m_prev;
00726 (pX->m_next = pY)->m_prev = pX;
00727 if (pYprev) pYprev->m_next = pX;
00728 else m_head = pX;
00729 }
00730
00732
00735 void moveToFront(ListIterator<E> it, ListPure<E> &L2) {
00736 OGDF_ASSERT(it.valid())
00737 OGDF_ASSERT(this != &L2)
00738
00739 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00740 if (pPrev) pPrev->m_next = pNext;
00741 else m_head = pNext;
00742 if (pNext) pNext->m_prev = pPrev;
00743 else m_tail = pPrev;
00744
00745 pX->m_prev = 0;
00746 if ((pX->m_next = L2.m_head))
00747 L2.m_head = L2.m_head->m_prev = pX;
00748 else
00749 L2.m_head = L2.m_tail = pX;
00750 }
00751
00753
00756 void moveToBack(ListIterator<E> it, ListPure<E> &L2) {
00757 OGDF_ASSERT(it.valid())
00758 OGDF_ASSERT(this != &L2)
00759
00760 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00761 if (pPrev) pPrev->m_next = pNext;
00762 else m_head = pNext;
00763 if (pNext) pNext->m_prev = pPrev;
00764 else m_tail = pPrev;
00765
00766 pX->m_next = 0;
00767 if ((pX->m_prev = L2.m_tail))
00768 L2.m_tail = L2.m_tail->m_next = pX;
00769 else
00770 L2.m_head = L2.m_tail = pX;
00771 }
00772
00774
00778 void moveToSucc(ListIterator<E> it, ListPure<E> &L2, ListIterator<E> itBefore) {
00779 OGDF_ASSERT(it.valid() && itBefore.valid())
00780 OGDF_ASSERT(this != &L2)
00781
00782 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00783 if (pPrev) pPrev->m_next = pNext;
00784 else m_head = pNext;
00785 if (pNext) pNext->m_prev = pPrev;
00786 else m_tail = pPrev;
00787
00788 ListElement<E> *pY = itBefore;
00789 ListElement<E> *pYnext = pX->m_next = pY->m_next;
00790 (pX->m_prev = pY)->m_next = pX;
00791 if (pYnext) pYnext->m_prev = pX;
00792 else L2.m_tail = pX;
00793 }
00794
00796
00800 void moveToPrec(ListIterator<E> it, ListPure<E> &L2, ListIterator<E> itAfter) {
00801 OGDF_ASSERT(it.valid() && itAfter.valid())
00802 OGDF_ASSERT(this != &L2)
00803
00804 ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00805 if (pPrev) pPrev->m_next = pNext;
00806 else m_head = pNext;
00807 if (pNext) pNext->m_prev = pPrev;
00808 else m_tail = pPrev;
00809
00810 ListElement<E> *pY = itAfter;
00811 ListElement<E> *pYprev = pX->m_prev = pY->m_prev;
00812 (pX->m_next = pY)->m_prev = pX;
00813 if (pYprev) pYprev->m_next = pX;
00814 else L2.m_head = pX;
00815 }
00816
00818 void conc(ListPure<E> &L2) {
00819 OGDF_ASSERT(this != &L2)
00820 if (m_head)
00821 m_tail->m_next = L2.m_head;
00822 else
00823 m_head = L2.m_head;
00824 if (L2.m_head) {
00825 L2.m_head->m_prev = m_tail;
00826 m_tail = L2.m_tail;
00827 }
00828 L2.m_head = L2.m_tail = 0;
00829 }
00830
00832 void concFront(ListPure<E> &L2) {
00833 OGDF_ASSERT(this != &L2)
00834 if (m_head)
00835 m_head->m_prev = L2.m_tail;
00836 else
00837 m_tail = L2.m_tail;
00838 if (L2.m_head) {
00839 L2.m_tail->m_next = m_head;
00840 m_head = L2.m_head;
00841 }
00842 L2.m_head = L2.m_tail = 0;
00843 }
00844
00846
00849 void exchange(ListPure<E>& L2) {
00850 ListElement<E>* t;
00851 t = this->m_head;
00852 this->m_head = L2.m_head;
00853 L2.m_head = t;
00854 t = this->m_tail;
00855 this->m_tail = L2.m_tail;
00856 L2.m_tail = t;
00857 }
00858
00860
00869 void split(ListIterator<E> it,ListPure<E> &L1,ListPure<E> &L2,Direction dir =