Open
Graph Drawing
Framework

 v.2007.11
 

List.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 1.17 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2007-11-08 16:10:37 +0100 (Do, 08 Nov 2007) $ 
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 }; // class ListElement
00092 
00093 
00094 
00096 
00102 template<class E> class ListIterator {
00103     ListElement<E> *m_pX; // pointer to associated list element
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 }; // class ListIterator
00177 
00178 
00179 
00180 //---------------------------------------------------------
00181 // ListConstIterator<E>
00182 // const iterator for doubly linked lists
00183 //---------------------------------------------------------
00185 
00192 template<class E> class ListConstIterator {
00193     const ListElement<E> *m_pX; // pointer to list element
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 }; // class ListConstIterator
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     // destruction
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         // remove it
00648         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00649         //already at front
00650         if (!pPrev) return;
00651 
00652         //update old position
00653         if (pPrev) pPrev->m_next = pNext;
00654         if (pNext) pNext->m_prev = pPrev;
00655         else m_tail = pPrev;
00656         // insert it at front
00657         pX->m_prev = 0;
00658         pX->m_next = m_head;
00659         m_head = m_head->m_prev = pX;
00660     }//move
00661     
00663 
00666     void moveToBack(ListIterator<E> it) {
00667         OGDF_ASSERT(it.valid())
00668         // remove it
00669         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00670         //already at back
00671         if (!pNext) return;
00672 
00673         //update old position
00674         if (pPrev) pPrev->m_next = pNext;
00675         else m_head = pNext;
00676         if (pNext) pNext->m_prev = pPrev;
00677         // insert it at back
00678         pX->m_prev = m_tail;
00679         pX->m_next = 0;
00680         m_tail = m_tail->m_next = pX;
00681     }//move
00682 
00684 
00687     void moveToSucc(ListIterator<E> it, ListIterator<E> itBefore) {
00688         OGDF_ASSERT(it.valid() && itBefore.valid())
00689         // move it
00690         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00691         //the same of already in place 
00692         ListElement<E> *pY = itBefore;
00693         if(pX == pY || pPrev == pY) return;     
00694 
00695         // update old position
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         // move it after itBefore
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     }//move
00706 
00708 
00711     void moveToPrec(ListIterator<E> it, ListIterator<E> itAfter) {
00712         OGDF_ASSERT(it.valid() && itAfter.valid())
00713         // move it
00714         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00715         //the same of already in place
00716         ListElement<E> *pY = itAfter;
00717         if(pX == pY || pNext == pY) return;
00718 
00719         // update old position
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         // move it before itAfter
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     }//move
00730 
00732 
00735     void moveToFront(ListIterator<E> it, ListPure<E> &L2) {
00736         OGDF_ASSERT(it.valid())
00737         OGDF_ASSERT(this != &L2)
00738         // remove it
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         // insert it at front of L2
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         // remove it
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         // insert it at back of L2
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         // remove it
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         // insert it in list L2 after itBefore
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         // remove it
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         // insert it in list L2 after itBefore
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 =