Open
Graph Drawing
Framework

 v.2010.10
 

List.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 2071 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2010-10-19 16:18:38 +0200 (Tue, 19 Oct 2010) $ 
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 }; // class ListElement
00094 
00095 
00096 
00098 
00104 template<class E> class ListIterator {
00105     ListElement<E> *m_pX; // pointer to associated list element
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 }; // class ListIterator
00179 
00180 
00181 
00182 //---------------------------------------------------------
00183 // ListConstIterator<E>
00184 // const iterator for doubly linked lists
00185 //---------------------------------------------------------
00187 
00194 template<class E> class ListConstIterator {
00195     const ListElement<E> *m_pX; // pointer to list element
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 }; // class ListConstIterator
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     // destruction
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         // remove it
00667         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00668         //already at front
00669         if (!pPrev) return;
00670 
00671         //update old position
00672         if (pPrev) pPrev->m_next = pNext;
00673         if (pNext) pNext->m_prev = pPrev;
00674         else m_tail = pPrev;
00675         // insert it at front
00676         pX->m_prev = 0;
00677         pX->m_next = m_head;
00678         m_head = m_head->m_prev = pX;
00679     }//move
00680     
00682 
00685     void moveToBack(ListIterator<E> it) {
00686         OGDF_ASSERT(it.valid())
00687         // remove it
00688         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00689         //already at back
00690         if (!pNext) return;
00691 
00692         //update old position
00693         if (pPrev) pPrev->m_next = pNext;
00694         else m_head = pNext;
00695         if (pNext) pNext->m_prev = pPrev;
00696         // insert it at back
00697         pX->m_prev = m_tail;
00698         pX->m_next = 0;
00699         m_tail = m_tail->m_next = pX;
00700     }//move
00701 
00703 
00706     void moveToSucc(ListIterator<E> it, ListIterator<E> itBefore) {
00707         OGDF_ASSERT(it.valid() && itBefore.valid())
00708         // move it
00709         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00710         //the same of already in place 
00711         ListElement<E> *pY = itBefore;
00712         if(pX == pY || pPrev == pY) return;     
00713 
00714         // update old position
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         // move it after itBefore
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     }//move
00725 
00727 
00730     void moveToPrec(ListIterator<E> it, ListIterator<E> itAfter) {
00731         OGDF_ASSERT(it.valid() && itAfter.valid())
00732         // move it
00733         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00734         //the same of already in place
00735         ListElement<E> *pY = itAfter;
00736         if(pX == pY || pNext == pY) return;
00737 
00738         // update old position
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         // move it before itAfter
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     }//move
00749 
00751 
00754     void moveToFront(ListIterator<E> it, ListPure<E> &L2) {
00755         OGDF_ASSERT(it.valid())
00756         OGDF_ASSERT(this != &L2)
00757         // remove it
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         // insert it at front of L2
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         // remove it
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         // insert it at back of L2
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         // remove it
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         // insert it in list L2 after itBefore
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         // remove it
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         // insert it in list L2 after itBefore
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 // workaround for bug in Visual Studio 5.0
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 }; // class ListPure
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     // destruction
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     // returns length of list
01140     int size() const { return m_count; }
01141 
01142     // returns first element of list (0 if empty)
01143     const ListConstIterator<E> begin() const { return ListPure<E>::begin(); }
01144     // returns first element of list (0 if empty)
01145     ListIterator<E> begin() { return ListPure<E>::begin(); }
01146 
01147     // returns iterator to one-past-last element of list
01148     ListConstIterator<E> end() const { return ListConstIterator<E>(); }
01149     // returns iterator to one-past-last element of list
01150     ListIterator<E> end() { return ListIterator<E>(); }
01151 
01152     // returns last element of list (0 if empty)
01153     const ListConstIterator<E> rbegin() const { return ListPure<E>::rbegin(); }
01154     // returns last element of list (0 if empty)
01155     ListIterator<E> rbegin() { return ListPure<E>::rbegin(); }
01156 
01157     // returns iterator to one-before-first element of list
01158     ListConstIterator<E> rend() const { return ListConstIterator<E>(); }
01159     // returns iterator to one-before-first element of list
01160     ListIterator<E> rend() { return ListIterator<E>(); }
01161 
01162     // returns reference to first element
01163     const E &front() const { return ListPure<E>::front(); }
01164     // returns reference to first element
01165     E &front() { return ListPure<E>::front(); }
01166 
01167     // returns reference to last element
01168     const E &back() const { return ListPure<E>::back(); }
01169     // returns reference to last element
01170     E &back() { return ListPure<E>::back(); }
01171 
01172     // returns cyclic successor
01173     ListConstIterator<E> cyclicSucc(ListConstIterator<E> it) const {
01174         return ListPure<E>::cyclicSucc(it);
01175     }
01176 
01177     // returns cyclic successor
01178     ListIterator<E> cyclicSucc(ListIterator<E> it) {
01179         return ListPure<E>::cyclicSucc(it);
01180     }
01181 
01182     // returns cyclic predecessor
01183     ListConstIterator<E> cyclicPred(ListConstIterator<E> it) const {
01184         return ListPure<E>::cyclicPred(it);
01185     }
01186 
01187     // returns cyclic predecessor
01188     ListIterator<E> cyclicPred(ListIterator<E> it) {
01189         return ListPure<E>::cyclicPred(it);
01190     }
01191 
01192     // returns the iterator at position pos. Note that this takes time linear in pos.
01193     ListConstIterator<E> get(int pos) const {
01194         OGDF_ASSERT(0 <= pos && pos < m_count)
01195         return ListPure<E>::get(pos);
01196     }
01197 
01198     // returns the iterator at position pos. Note that this takes time linear in pos.
01199     ListIterator<E> get(int pos) {
01200         OGDF_ASSERT(0 <= pos && pos < m_count)
01201         return ListPure<E>::get(pos);
01202     }
01203 
01204     // returns the position (starting with 0) of it in the list
01205     int pos(ListConstIterator<E> it) const {
01206         return ListPure<E>::pos(it);
01207     }
01208 
01209     // assignment
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     // adds element x at beginning
01237     ListIterator<E> pushFront(const E &x) {
01238         ++m_count;
01239         return ListPure<E>::pushFront(x);
01240     }
01241 
01242     // adds element x at end
01243     ListIterator<E> pushBack(const E &x) {
01244         ++m_count;
01245         return ListPure<E>::pushBack(x);
01246     }
01247 
01248     // inserts x before or after it
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     // inserts x before it
01255     ListIterator<E> insertBefore(const E &x, ListIterator<E> it) {
01256         ++m_count;
01257         return ListPure<E>::insertBefore(x,it);
01258     }
01259 
01260     // inserts x after it
01261     ListIterator<E> insertAfter(const E &x, ListIterator<E> it) {
01262         ++m_count;
01263         return ListPure<E>::insertAfter(x,it);
01264     }
01265 
01266     // removes first element
01267     void popFront() {
01268         --m_count;
01269         ListPure<E>::popFront();
01270     }
01271 
01272     // removes first element and returns it
01273     E popFrontRet() {
01274         E el = front(); 
01275         popFront();
01276         return el;
01277     }
01278 
01279     // removes last element
01280     void popBack() {
01281         --m_count;
01282         ListPure<E>::popBack();
01283     }
01284 
01285     // removes last element and returns it
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     // removes it and frees memory
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     // reverses the order of the list elements
01413     void reverse() { ListPure<E>::reverse(); }
01414 
01415     // removes all elements from list
01416     void clear() {
01417         m_count = 0;
01418         ListPure<E>::clear();
01419     }
01420 
01422     const ListPure<E> &getListPure() const { return *this; }
01423 
01424     // sorts list using quicksort
01425     void quicksort() {
01426         ogdf::quicksortTemplate(*this);
01427     }
01428 
01429     // sorts list using quicksort and parameterized compare element comp
01430     template<class COMPARER>
01431     void quicksort(const COMPARER &comp) {
01432         ogdf::quicksortTemplate(*this,comp);
01433     }
01434 
01435     // sorts list using bucket sort
01436     void bucketSort(int l, int h, BucketFunc<E> &f) {
01437         ListPure<E>::bucketSort(l,h,f);
01438     }
01439 
01440     // permutes elements in list randomly
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 }; // class List
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 // permutes elements in list randomly; n is the length of the list
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 // prints list L to output stream os using delimiter delim
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 // prints list L to output stream os using delimiter delim
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 // prints list L to output stream os
01537 template<class E>
01538 ostream &operator<<(ostream &os, const ListPure<E> &L)
01539 {
01540     print(os,L);
01541     return os;
01542 }
01543 
01544 // prints list L to output stream os
01545 template<class E>
01546 ostream &operator<<(ostream &os, const List<E> &L)
01547 {
01548     return os << L.getListPure();
01549 }
01550 
01551 
01552 } // end namespace ogdf
01553 
01554 
01555 #endif