Open
Graph Drawing
Framework

 v.2012.05
 

List.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008 
00042 #ifdef _MSC_VER
00043 #pragma once
00044 #endif
00045 
00046 #ifndef OGDF_LIST_H
00047 #define OGDF_LIST_H
00048 
00049 
00050 #include <ogdf/internal/basic/list_templates.h>
00051 
00052 
00053 namespace ogdf {
00054 
00055 
00056 template<class E> class List;
00057 template<class E> class ListPure;
00058 template<class E> class ListIterator;
00059 template<class E> class ListConstIterator;
00060 
00061 
00063 template<class E>
00064 class ListElement {
00065     friend class ListPure<E>;
00066     friend class List<E>;
00067     friend class ListIterator<E>;
00068     friend class ListConstIterator<E>;
00069 
00070     ListElement<E> *m_next; 
00071     ListElement<E> *m_prev; 
00072     E m_x; 
00073 
00075     ListElement() : m_next(0), m_prev(0) { }
00077     ListElement(const E &x) : m_next(0), m_prev(0), m_x(x) { }
00079     ListElement(const E &x, ListElement<E> *next, ListElement<E> *prev) :
00080         m_next(next), m_prev(prev), m_x(x) { }
00081 
00082     OGDF_NEW_DELETE
00083 }; // class ListElement
00084 
00085 
00086 
00088 
00094 template<class E> class ListIterator {
00095     ListElement<E> *m_pX; // pointer to associated list element
00096 
00097     friend class ListConstIterator<E>;
00098     friend class ListPure<E>;
00099 
00101     operator ListElement<E> *() { return m_pX; }
00103     operator const ListElement<E> *() const { return m_pX; }
00104 
00105 public:
00107     ListIterator() : m_pX(0) { }
00109     ListIterator(ListElement<E> *pX) : m_pX(pX) { }
00111     ListIterator(const ListIterator<E> &it) : m_pX(it.m_pX) { }
00112 
00114     bool valid() const { return m_pX != 0; }
00115 
00117     bool operator==(const ListIterator<E> &it) const {
00118         return m_pX == it.m_pX;
00119     }
00120 
00122     bool operator!=(const ListIterator<E> &it) const {
00123         return m_pX != it.m_pX;
00124     }
00125 
00127     ListIterator<E> succ() const { return m_pX->m_next; }
00128 
00130     ListIterator<E> pred() const { return m_pX->m_prev; }
00131 
00133     E &operator*() const { return m_pX->m_x; }
00134 
00136     ListIterator<E> &operator=(const ListIterator<E> &it) {
00137         m_pX = it.m_pX;
00138         return *this;
00139     }
00140 
00142     ListIterator<E> &operator++() {
00143         m_pX = m_pX->m_next;
00144         return *this;
00145     }
00146 
00148     ListIterator<E> operator++(int) {
00149         ListIterator<E> it = *this;
00150         m_pX = m_pX->m_next;
00151         return it;
00152     }
00153 
00155     ListIterator<E> &operator--() {
00156         m_pX = m_pX->m_prev;
00157         return *this;
00158     }
00159 
00161     ListIterator<E> operator--(int) {
00162         ListIterator<E> it = *this;
00163         m_pX = m_pX->m_prev;
00164         return it;
00165     }
00166 
00167     OGDF_NEW_DELETE
00168 }; // class ListIterator
00169 
00170 
00171 
00172 //---------------------------------------------------------
00173 // ListConstIterator<E>
00174 // const iterator for doubly linked lists
00175 //---------------------------------------------------------
00177 
00184 template<class E> class ListConstIterator {
00185     const ListElement<E> *m_pX; // pointer to list element
00186 
00187     friend class ListPure<E>;
00188 
00190     operator const ListElement<E> *() { return m_pX; }
00191 
00192 public:
00194     ListConstIterator() : m_pX(0) { }
00195     
00197     ListConstIterator(const ListElement<E> *pX) : m_pX(pX) { }
00198 
00200     ListConstIterator(const ListIterator<E> &it) : m_pX((const ListElement<E> *)it) { }
00202     ListConstIterator(const ListConstIterator &it) : m_pX(it.m_pX) { }
00203 
00205     bool valid() const { return m_pX != 0; }
00206 
00208     bool operator==(const ListConstIterator<E> &it) const {
00209         return m_pX == it.m_pX;
00210     }
00211 
00213     bool operator!=(const ListConstIterator<E> &it) const {
00214         return m_pX != it.m_pX;
00215     }
00216 
00218     ListConstIterator<E> succ() const { return m_pX->m_next; }
00219 
00221     ListConstIterator<E> pred() const { return m_pX->m_prev; }
00222 
00224     const E &operator*() const { return m_pX->m_x; }
00225 
00227     ListConstIterator<E> &operator=(const ListConstIterator<E> &it) {
00228         m_pX = it.m_pX;
00229         return *this;
00230     }
00231 
00233     ListConstIterator<E> &operator++() {
00234         m_pX = m_pX->m_next;
00235         return *this;
00236     }
00237 
00239     ListConstIterator<E> operator++(int) {
00240         ListConstIterator<E> it = *this;
00241         m_pX = m_pX->m_next;
00242         return it;
00243     }
00244 
00246     ListConstIterator<E> &operator--() {
00247         m_pX = m_pX->m_prev;
00248         return *this;
00249     }
00250 
00252     ListConstIterator<E> operator--(int) {
00253         ListConstIterator<E> it = *this;
00254         m_pX = m_pX->m_prev;
00255         return it;
00256     }
00257 
00258     OGDF_NEW_DELETE
00259 }; // class ListConstIterator
00260 
00261 
00262 
00264 
00271 template<class E> class ListPure {
00272 protected:
00273 
00274     ListElement<E> *m_head; 
00275     ListElement<E> *m_tail; 
00276 
00277 public:
00279     ListPure() : m_head(0), m_tail(0) { }
00280 
00282     ListPure(const ListPure<E> &L) : m_head(0), m_tail(0) {
00283         copy(L);
00284     }
00285 
00286     // destruction
00287     ~ListPure() { clear(); }
00288 
00289     typedef E value_type;
00290     typedef ListElement<E> element_type;
00291     typedef ListConstIterator<E> const_iterator;
00292     typedef ListIterator<E> iterator;
00293 
00295     bool empty() const { return m_head == 0; }
00296 
00298 
00301     int size() const {
00302         int count = 0;
00303         for (ListElement<E> *pX = m_head; pX; pX = pX->m_next)
00304             ++count;
00305         return count;
00306     }
00307 
00309 
00312     const ListConstIterator<E> begin() const { return m_head; }
00314 
00317     ListIterator<E> begin() { return m_head; }
00318 
00320 
00323     ListConstIterator<E> end() const { return ListConstIterator<E>(); }
00325 
00328     ListIterator<E> end() { return ListIterator<E>(); }
00329 
00331 
00334     const ListConstIterator<E> rbegin() const { return m_tail; }
00336 
00339     ListIterator<E> rbegin() { return m_tail; }
00340 
00342 
00345     ListConstIterator<E> rend() const { return ListConstIterator<E>(); }
00347 
00350     ListIterator<E> rend() { return ListIterator<E>(); }
00351 
00353 
00356     const E &front() const {
00357         OGDF_ASSERT(m_head != 0)
00358         return m_head->m_x;
00359     }
00360 
00362 
00365     E &front() {
00366         OGDF_ASSERT(m_head != 0)
00367         return m_head->m_x;
00368     }
00369 
00371 
00374     const E &back() const {
00375         OGDF_ASSERT(m_tail != 0)
00376         return m_tail->m_x;
00377     }
00378 
00380 
00383     E &back() {
00384         OGDF_ASSERT(m_tail != 0)
00385         return m_tail->m_x;
00386     }
00387 
00389 
00392     ListConstIterator<E> cyclicSucc(ListConstIterator<E> it) const {
00393         const ListElement<E> *pX = it;
00394         return (pX->m_next) ? pX->m_next : m_head;
00395     }
00396 
00398 
00401     ListIterator<E> cyclicSucc(ListIterator<E> it) {
00402         OGDF_ASSERT(it.valid())
00403         ListElement<E> *pX = it;
00404         return (pX->m_next) ? pX->m_next : m_head;
00405     }
00406 
00408 
00411     ListConstIterator<E> cyclicPred(ListConstIterator<E> it) const {
00412         OGDF_ASSERT(it.valid())
00413         const ListElement<E> *pX = it;
00414         return (pX->m_prev) ? pX->m_prev : m_tail;
00415     }
00416 
00418 
00421     ListIterator<E> cyclicPred(ListIterator<E> it) {
00422         OGDF_ASSERT(it.valid())
00423         ListElement<E> *pX = it;
00424         return (pX->m_prev) ? pX->m_prev : m_tail;
00425     }
00426 
00428 
00431     ListConstIterator<E> get(int pos) const {
00432       ListElement<E> *pX;
00433         for(pX = m_head; pX != 0; pX = pX->m_next)
00434             if (pos-- == 0) break;
00435         return pX;
00436     }
00437 
00439 
00442     ListIterator<E> get(int pos) {
00443       ListElement<E> *pX;
00444         for(pX = m_head; pX != 0; pX = pX->m_next)
00445             if (pos-- == 0) break;
00446         return pX;
00447     }
00448 
00450 
00454     int pos(ListConstIterator<E> it) const {
00455         OGDF_ASSERT(it.valid())
00456         int p = 0;
00457         for(ListElement<E> *pX = m_head; pX != 0; pX = pX->m_next, ++p)
00458             if (pX == it) break;
00459         return p;
00460     }
00461 
00462     // returns random valid iterator. Note that this takes linear time (doubled).
00463     ListConstIterator<E> chooseIterator() const {
00464         return get(randomNumber(0,size()-1));
00465     }
00466 
00467     // returns random valid iterator. Note that this takes linear time (doubled).
00468     ListIterator<E> chooseIterator() {
00469         return get(randomNumber(0,size()-1));
00470     }
00471 
00472     // returns random element. Note that this takes linear time.
00473     const E chooseElement() const {
00474         return *chooseIterator();
00475     }
00476 
00477     // returns random element. Note that this takes linear time.
00478     E chooseElement() {
00479         return *chooseIterator();
00480     }
00481 
00483     ListPure<E> &operator=(const ListPure<E> &L) {
00484         clear(); copy(L);
00485         return *this;
00486     }
00487 
00489     bool operator==(const ListPure<E> &L) const {
00490         ListElement<E> *pX = m_head, *pY = L.m_head;
00491         while(pX != 0 && pY != 0) {
00492             if(pX->m_x != pY->m_x)
00493                 return false;
00494             pX = pX->m_next;
00495             pY = pY->m_next;
00496         }
00497         return (pX == 0 && pY == 0);
00498     }
00499 
00501     bool operator!=(const ListPure<E> &L) const {
00502         return !operator==(L);
00503     }
00504 
00506     ListIterator<E> pushFront(const E &x) {
00507         ListElement<E> *pX = OGDF_NEW ListElement<E>(x,m_head,0);
00508         if (m_head)
00509             m_head = m_head->m_prev = pX;
00510         else
00511             m_head = m_tail = pX;
00512         return m_head;
00513     }
00514 
00516     ListIterator<E> pushBack(const E &x) {
00517         ListElement<E> *pX = OGDF_NEW ListElement<E>(x,0,m_tail);
00518         if (m_head)
00519             m_tail = m_tail->m_next = pX;
00520         else
00521             m_tail = m_head = pX;
00522         return m_tail;
00523     }
00524 
00526 
00533     ListIterator<E> insert(const E &x, ListIterator<E> it, Direction dir = after) {
00534         OGDF_ASSERT(it.valid())
00535         OGDF_ASSERT(dir == after || dir == before)
00536         ListElement<E> *pY = it, *pX;
00537         if (dir == after) {
00538             ListElement<E> *pYnext = pY->m_next;
00539             pY->m_next = pX = OGDF_NEW ListElement<E>(x,pYnext,pY);
00540             if (pYnext) pYnext->m_prev = pX;
00541             else m_tail = pX;
00542         } else {
00543             ListElement<E> *pYprev = pY->m_prev;
00544             pY->m_prev = pX = OGDF_NEW ListElement<E>(x,pY,pYprev);
00545             if (pYprev) pYprev->m_next = pX;
00546             else m_head = pX;
00547         }
00548         return pX;
00549     }
00550 
00552 
00555     ListIterator<E> insertBefore(const E &x, ListIterator<E> it) {
00556         OGDF_ASSERT(it.valid())
00557         ListElement<E> *pY = it, *pX;
00558         ListElement<E> *pYprev = pY->m_prev;
00559         pY->m_prev = pX = OGDF_NEW ListElement<E>(x,pY,pYprev);
00560         if (pYprev) pYprev->m_next = pX;
00561         else m_head = pX;
00562         return pX;
00563     }
00564 
00566 
00569     ListIterator<E> insertAfter(const E &x, ListIterator<E> it) {
00570         OGDF_ASSERT(it.valid())
00571         ListElement<E> *pY = it, *pX;
00572         ListElement<E> *pYnext = pY->m_next;
00573         pY->m_next = pX = OGDF_NEW ListElement<E>(x,pYnext,pY);
00574         if (pYnext) pYnext->m_prev = pX;
00575         else m_tail = pX;
00576         return pX;
00577     }
00578 
00580 
00583     void popFront() {
00584         OGDF_ASSERT(m_head != 0)
00585         ListElement<E> *pX = m_head;
00586         m_head = m_head->m_next;
00587         delete pX;
00588         if (m_head) m_head->m_prev = 0;
00589         else m_tail = 0;
00590     }
00591 
00593 
00596     E popFrontRet() {
00597         E el = front(); 
00598         popFront();
00599         return el;
00600     }
00601 
00603 
00606     void popBack() {
00607         OGDF_ASSERT(m_tail != 0)
00608         ListElement<E> *pX = m_tail;
00609         m_tail = m_tail->m_prev;
00610         delete pX;
00611         if (m_tail) m_tail->m_next = 0;
00612         else m_head = 0;
00613     }
00614 
00616 
00619     E popBackRet() {
00620         E el = back(); 
00621         popBack();
00622         return el;
00623     }
00624 
00626 
00629     void del(ListIterator<E> it) {
00630         OGDF_ASSERT(it.valid())
00631         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00632         delete pX;
00633         if (pPrev) pPrev->m_next = pNext;
00634         else m_head = pNext;
00635         if (pNext) pNext->m_prev = pPrev;
00636         else m_tail = pPrev;
00637     }
00638 
00640 
00643     void exchange(ListIterator<E> it1, ListIterator<E> it2) {
00644         OGDF_ASSERT(it1.valid() && it2.valid() && it1 != it2)
00645         ListElement<E> *pX = it1, *pY = it2;
00646 
00647         std::swap(pX->m_next,pY->m_next);
00648         std::swap(pX->m_prev,pY->m_prev);
00649 
00650         if(pX->m_next == pX) {
00651             pX->m_next = pY; pY->m_prev = pX;
00652         }
00653         if(pX->m_prev == pX) {
00654             pX->m_prev = pY; pY->m_next = pX;
00655         }
00656 
00657         if(pX->m_prev) pX->m_prev->m_next = pX;
00658         else m_head = pX;
00659 
00660         if(pY->m_prev) pY->m_prev->m_next = pY;
00661         else m_head = pY;
00662 
00663         if(pX->m_next) pX->m_next->m_prev = pX;
00664         else m_tail = pX;
00665 
00666         if(pY->m_next) pY->m_next->m_prev = pY;
00667         else m_tail = pY;
00668     }
00669 
00671 
00674     void moveToFront(ListIterator<E> it) {
00675         OGDF_ASSERT(it.valid())
00676         // remove it
00677         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00678         //already at front
00679         if (!pPrev) return;
00680 
00681         //update old position
00682         if (pPrev) pPrev->m_next = pNext;
00683         if (pNext) pNext->m_prev = pPrev;
00684         else m_tail = pPrev;
00685         // insert it at front
00686         pX->m_prev = 0;
00687         pX->m_next = m_head;
00688         m_head = m_head->m_prev = pX;
00689     }//move
00690     
00692 
00695     void moveToBack(ListIterator<E> it) {
00696         OGDF_ASSERT(it.valid())
00697         // remove it
00698         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00699         //already at back
00700         if (!pNext) return;
00701 
00702         //update old position
00703         if (pPrev) pPrev->m_next = pNext;
00704         else m_head = pNext;
00705         if (pNext) pNext->m_prev = pPrev;
00706         // insert it at back
00707         pX->m_prev = m_tail;
00708         pX->m_next = 0;
00709         m_tail = m_tail->m_next = pX;
00710     }//move
00711 
00713 
00716     void moveToSucc(ListIterator<E> it, ListIterator<E> itBefore) {
00717         OGDF_ASSERT(it.valid() && itBefore.valid())
00718         // move it
00719         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00720         //the same of already in place 
00721         ListElement<E> *pY = itBefore;
00722         if(pX == pY || pPrev == pY) return;     
00723 
00724         // update old position
00725         if (pPrev) pPrev->m_next = pNext;
00726         else m_head = pNext;
00727         if (pNext) pNext->m_prev = pPrev;
00728         else m_tail = pPrev;
00729         // move it after itBefore
00730         ListElement<E> *pYnext = pX->m_next = pY->m_next;
00731         (pX->m_prev = pY)->m_next = pX;
00732         if (pYnext) pYnext->m_prev = pX;
00733         else m_tail = pX;
00734     }//move
00735 
00737 
00740     void moveToPrec(ListIterator<E> it, ListIterator<E> itAfter) {
00741         OGDF_ASSERT(it.valid() && itAfter.valid())
00742         // move it
00743         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00744         //the same of already in place
00745         ListElement<E> *pY = itAfter;
00746         if(pX == pY || pNext == pY) return;
00747 
00748         // update old position
00749         if (pPrev) pPrev->m_next = pNext;
00750         else m_head = pNext;
00751         if (pNext) pNext->m_prev = pPrev;
00752         else m_tail = pPrev;
00753         // move it before itAfter
00754         ListElement<E> *pYprev = pX->m_prev = pY->m_prev;
00755         (pX->m_next = pY)->m_prev = pX;
00756         if (pYprev) pYprev->m_next = pX;
00757         else m_head = pX;
00758     }//move
00759 
00761 
00764     void moveToFront(ListIterator<E> it, ListPure<E> &L2) {
00765         OGDF_ASSERT(it.valid())
00766         OGDF_ASSERT(this != &L2)
00767         // remove it
00768         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00769         if (pPrev) pPrev->m_next = pNext;
00770         else m_head = pNext;
00771         if (pNext) pNext->m_prev = pPrev;
00772         else m_tail = pPrev;
00773         // insert it at front of L2
00774         pX->m_prev = 0;
00775         if ((pX->m_next = L2.m_head) != 0)
00776             L2.m_head = L2.m_head->m_prev = pX;
00777         else
00778             L2.m_head = L2.m_tail = pX;
00779     }
00780 
00782 
00785     void moveToBack(ListIterator<E> it, ListPure<E> &L2) {
00786         OGDF_ASSERT(it.valid())
00787         OGDF_ASSERT(this != &L2)
00788         // remove it
00789         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00790         if (pPrev) pPrev->m_next = pNext;
00791         else m_head = pNext;
00792         if (pNext) pNext->m_prev = pPrev;
00793         else m_tail = pPrev;
00794         // insert it at back of L2
00795         pX->m_next = 0;
00796         if ((pX->m_prev = L2.m_tail) != 0)
00797             L2.m_tail = L2.m_tail->m_next = pX;
00798         else
00799             L2.m_head = L2.m_tail = pX;
00800     }
00801 
00803 
00807     void moveToSucc(ListIterator<E> it, ListPure<E> &L2, ListIterator<E> itBefore) {
00808         OGDF_ASSERT(it.valid() && itBefore.valid())
00809         OGDF_ASSERT(this != &L2)
00810         // remove it
00811         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00812         if (pPrev) pPrev->m_next = pNext;
00813         else m_head = pNext;
00814         if (pNext) pNext->m_prev = pPrev;
00815         else m_tail = pPrev;
00816         // insert it in list L2 after itBefore
00817         ListElement<E> *pY = itBefore;
00818         ListElement<E> *pYnext = pX->m_next = pY->m_next;
00819         (pX->m_prev = pY)->m_next = pX;
00820         if (pYnext) pYnext->m_prev = pX;
00821         else L2.m_tail = pX;
00822     }
00823 
00825 
00829     void moveToPrec(ListIterator<E> it, ListPure<E> &L2, ListIterator<E> itAfter) {
00830         OGDF_ASSERT(it.valid() && itAfter.valid())
00831         OGDF_ASSERT(this != &L2)
00832         // remove it
00833         ListElement<E> *pX = it, *pPrev = pX->m_prev, *pNext = pX->m_next;
00834         if (pPrev) pPrev->m_next = pNext;
00835         else m_head = pNext;
00836         if (pNext) pNext->m_prev = pPrev;
00837         else m_tail = pPrev;
00838         // insert it in list L2 after itBefore
00839         ListElement<E> *pY = itAfter;
00840         ListElement<E> *pYprev = pX->m_prev = pY->m_prev;
00841         (pX->m_next = pY)->m_prev = pX;
00842         if (pYprev) pYprev->m_next = pX;
00843         else L2.m_head = pX;
00844     }
00845 
00847     void conc(ListPure<E> &L2) {
00848         OGDF_ASSERT(this != &L2)
00849         if (m_head)
00850             m_tail->m_next = L2.m_head;
00851         else
00852             m_head = L2.m_head;
00853         if (L2.m_head) {
00854             L2.m_head->m_prev = m_tail;
00855             m_tail = L2.m_tail;
00856         }
00857         L2.m_head = L2.m_tail = 0;
00858     }
00859 
00861     void concFront(ListPure<E> &L2) {
00862         OGDF_ASSERT(this != &L2)
00863         if (m_head)
00864             m_head->m_prev = L2.m_tail;
00865         else
00866             m_tail = L2.m_tail;
00867         if (L2.m_head) {
00868             L2.m_tail->m_next = m_head;
00869             m_head = L2.m_head;
00870         }
00871         L2.m_head = L2.m_tail = 0;
00872     }
00873 
00875 
00878     void exchange(ListPure<E>& L2) {
00879         ListElement<E>* t;
00880         t = this->m_head;
00881         this->m_head = L2.m_head; 
00882         L2.m_head = t; 
00883         t = this->m_tail;
00884         this->m_tail = L2.m_tail; 
00885         L2.m_tail = t; 
00886     }
00887 
00889 
00898     void split(ListIterator<E> it,ListPure<E> &L1,ListPure<E> &L2,Direction dir = before) {
00899         if (&L1 != this) L1.clear();
00900         if (&L2 != this) L2.clear();
00901 
00902         if (it.valid()){
00903             L1.m_head = m_head;
00904             L2.m_tail = m_tail;
00905             if (dir == before){
00906                 L2.m_head = it;
00907                 L1.m_tail = L2.m_head->m_prev;
00908             }
00909             else {
00910                 L1.m_tail = it;
00911                 L2.m_head = L1.m_tail->m_next;
00912             }
00913             L2.m_head->m_prev = L1.m_tail->m_next = 0;
00914 
00915         } else {
00916             L1.m_head = L1.m_tail = 0;
00917             L2.m_head = m_head;
00918             L2.m_tail = m_tail;
00919         }
00920         
00921         if (this != &L1 && this != &L2) {
00922             m_head = m_tail = 0;
00923         }
00924     }
00925 
00927     void splitAfter(ListIterator<E> it, ListPure<E> &L2) {
00928         OGDF_ASSERT(it.valid())
00929         OGDF_ASSERT(this != &L2)
00930         L2.clear();
00931         ListElement<E> *pX = it;
00932         if (pX != m_tail) {
00933             (L2.m_head = pX->m_next)->m_prev = 0;
00934             pX->m_next = 0; 
00935             L2.m_tail = m_tail;
00936             m_tail = pX;
00937         }
00938     }
00939 
00941     void splitBefore(ListIterator<E> it, ListPure<E> &L2) {
00942         OGDF_ASSERT(it.valid())
00943         OGDF_ASSERT(this != &L2)
00944         L2.clear();
00945         ListElement<E> *pX = it;
00946         L2.m_head = pX; L2.m_tail = m_tail;
00947         if ((m_tail = pX->m_prev) == 0)
00948             m_head = 0;
00949         else
00950             m_tail->m_next = 0;
00951         pX->m_prev = 0;
00952     }
00953 
00955     void reverse() {
00956         ListElement<E> *pX = m_head;
00957         m_head = m_tail;
00958         m_tail = pX;
00959         while(pX) {
00960             ListElement<E> *pY = pX->m_next;
00961             pX->m_next = pX->m_prev;
00962             pX = pX->m_prev = pY;
00963         }
00964     }
00965 
00967     void clear() {
00968         if (m_head == 0) return;
00969 
00970 #if (_MSC_VER == 1100)
00971 // workaround for bug in Visual Studio 5.0
00972 
00973         while (!empty())
00974             popFront();
00975 
00976 #else
00977 
00978         if (doDestruction((E*)0)) {
00979             for(ListElement<E> *pX = m_head; pX != 0; pX = pX->m_next)
00980                 pX->m_x.~E();
00981         }
00982         OGDF_ALLOCATOR::deallocateList(sizeof(ListElement<E>),m_head,m_tail);
00983 
00984 #endif
00985 
00986         m_head = m_tail = 0;
00987     }
00988 
00990     void quicksort() {
00991         ogdf::quicksortTemplate(*this);
00992     }
00993 
00995     template<class COMPARER>
00996     void quicksort(const COMPARER &comp) {
00997         ogdf::quicksortTemplate(*this,comp);
00998     }
00999 
01001 
01008     void bucketSort(int l, int h, BucketFunc<E> &f);
01009 
01011     void permute() {
01012         permute(size());
01013     }
01014     
01016     int search (const E& e) const {
01017         int x = 0;
01018         for(ListConstIterator<E> i = begin(); i.valid(); ++i, ++x)
01019             if(*i == e) return x;
01020         return -1;
01021     }
01022     
01024     template<class COMPARER>
01025     int search (const E& e, const COMPARER &comp) const {
01026         int x = 0;
01027         for(ListConstIterator<E> i = begin(); i.valid(); ++i, ++x)
01028             if(comp.equal(*i,e)) return x;
01029         return -1;
01030     }
01031 
01032 protected:
01033     void copy(const ListPure<E> &L) {
01034         for(ListElement<E> *pX = L.m_head; pX != 0; pX = pX->m_next)
01035             pushBack(pX->m_x);
01036     }
01037 
01038     void permute(const int n);
01039 
01040     OGDF_NEW_DELETE
01041 }; // class ListPure
01042 
01043 
01044 
01046 
01070 #define forall_listiterators(type, it, L) \
01071    for(ListConstIterator< type > it = (L).begin(); it.valid(); ++it)
01072 
01074 
01078 #define forall_rev_listiterators(type, it, L) \
01079    for(ListConstIterator< type > it = (L).rbegin(); it.valid(); --it)
01080 
01082 
01086 #define forall_nonconst_listiterators(type, it, L) \
01087    for(ListIterator< type > it = (L).begin(); it.valid(); ++it)
01088 
01090 
01094 #define forall_rev_nonconst_listiterators(type, it, L) \
01095    for(ListIterator< type > it = (L).rbegin(); it.valid(); --it)
01096  
01098 
01102 #define forall_slistiterators(type, it, L) \
01103    for(SListConstIterator< type > it = (L).begin(); it.valid(); ++it)
01104 
01106 
01110 #define forall_nonconst_slistiterators(type, it, L) \
01111    for(SListIterator< type > it = (L).begin(); it.valid(); ++it)
01112 
01113 
01114 
01115 
01117 
01126 template<class E>
01127 class List : private ListPure<E> {
01128 
01129     int m_count; 
01130 
01131 public:
01133     List() : m_count(0) { }
01134 
01136     List(const List<E> &L) : ListPure<E>(L), m_count(L.m_count) { }
01137 
01138     // destruction
01139     ~List() { }
01140 
01141     typedef E value_type;
01142     typedef ListElement<E> element_type;
01143     typedef ListConstIterator<E> const_iterator;
01144     typedef ListIterator<E> iterator;
01145 
01147     bool empty() const { return ListPure<E>::empty(); }
01148 
01149     // returns length of list
01150     int size() const { return m_count; }
01151 
01152     // returns first element of list (0 if empty)
01153     const ListConstIterator<E> begin() const { return ListPure<E>::begin(); }
01154     // returns first element of list (0 if empty)
01155     ListIterator<E> begin() { return ListPure<E>::begin(); }
01156 
01157     // returns iterator to one-past-last element of list
01158     ListConstIterator<E> end() const { return ListConstIterator<E>(); }
01159     // returns iterator to one-past-last element of list
01160     ListIterator<E> end() { return ListIterator<E>(); }
01161 
01162     // returns last element of list (0 if empty)
01163     const ListConstIterator<E> rbegin() const { return ListPure<E>::rbegin(); }
01164     // returns last element of list (0 if empty)
01165     ListIterator<E> rbegin() { return ListPure<E>::rbegin(); }
01166 
01167     // returns iterator to one-before-first element of list
01168     ListConstIterator<E> rend() const { return ListConstIterator<E>(); }
01169     // returns iterator to one-before-first element of list
01170     ListIterator<E> rend() { return ListIterator<E>(); }
01171 
01172     // returns reference to first element
01173     const E &front() const { return ListPure<E>::front(); }
01174     // returns reference to first element
01175     E &front() { return ListPure<E>::front(); }
01176 
01177     // returns reference to last element
01178     const E &back() const { return ListPure<E>::back(); }
01179     // returns reference to last element
01180     E &back() { return ListPure<E>::back(); }
01181 
01182     // returns cyclic successor
01183     ListConstIterator<E> cyclicSucc(ListConstIterator<E> it) const {
01184         return ListPure<E>::cyclicSucc(it);
01185     }
01186 
01187     // returns cyclic successor
01188     ListIterator<E> cyclicSucc(ListIterator<E> it) {
01189         return ListPure<E>::cyclicSucc(it);
01190     }
01191 
01192     // returns cyclic predecessor
01193     ListConstIterator<E> cyclicPred(ListConstIterator<E> it) const {
01194         return ListPure<E>::cyclicPred(it);
01195     }
01196 
01197     // returns cyclic predecessor
01198     ListIterator<E> cyclicPred(ListIterator<E> it) {
01199         return ListPure<E>::cyclicPred(it);
01200     }
01201 
01202     // returns the iterator at position pos. Note that this takes time linear in pos.
01203     ListConstIterator<E> get(int pos) const {
01204         OGDF_ASSERT(0 <= pos && pos < m_count)
01205         return ListPure<E>::get(pos);
01206     }
01207 
01208     // returns the iterator at position pos. Note that this takes time linear in pos.
01209     ListIterator<E> get(int pos) {
01210         OGDF_ASSERT(0 <= pos && pos < m_count)
01211         return ListPure<E>::get(pos);
01212     }
01213 
01214     // returns the position (starting with 0) of it in the list
01215     int pos(ListConstIterator<E> it) const {
01216         return ListPure<E>::pos(it);
01217     }
01218 
01219     // returns random valid iterator. Note that this takes linear time.
01220     ListConstIterator<E> chooseIterator() const {
01221         return get(randomNumber(0,m_count-1));
01222     }
01223 
01224     // returns random valid iterator. Note that this takes linear time.
01225     ListIterator<E> chooseIterator() {
01226         return get(randomNumber(0,m_count-1));
01227     }
01228 
01229     // returns random element. Note that this takes linear time.
01230     const E chooseElement() const {
01231         return *chooseIterator();
01232     }
01233 
01234     // returns random element. Note that this takes linear time.
01235     E chooseElement() {
01236         return *chooseIterator();
01237     }
01238 
01239     // assignment
01240     List<E> &operator=(const List<E> &L) {
01241         ListPure<E>::operator=(L);
01242         m_count = L.m_count;
01243         return *this;
01244     }
01245 
01247     bool operator==(const List<E> &L) const {
01248         if(m_count != L.m_count)
01249             return false;
01250 
01251         ListElement<E> *pX = ListPure<E>::m_head, *pY = L.m_head;
01252         while(pX != 0) {
01253             if(pX->m_x != pY->m_x)
01254                 return false;
01255             pX = pX->m_next;
01256             pY = pY->m_next;
01257         }
01258         return true;
01259     }
01260 
01262     bool operator!=(const List<E> &L) const {
01263         return !operator==(L);
01264     }
01265 
01266     // adds element x at beginning
01267     ListIterator<E> pushFront(const E &x) {
01268         ++m_count;
01269         return ListPure<E>::pushFront(x);
01270     }
01271 
01272     // adds element x at end
01273     ListIterator<E> pushBack(const E &x) {
01274         ++m_count;
01275         return ListPure<E>::pushBack(x);
01276     }
01277 
01278     // inserts x before or after it
01279     ListIterator<E> insert(const E &x, ListIterator<E> it, Direction dir = after) {
01280         ++m_count;
01281         return ListPure<E>::insert(x,it,dir);
01282     }
01283 
01284     // inserts x before it
01285     ListIterator<E> insertBefore(const E &x, ListIterator<E> it) {
01286         ++m_count;
01287         return ListPure<E>::insertBefore(x,it);
01288     }
01289 
01290     // inserts x after it
01291     ListIterator<E> insertAfter(const E &x, ListIterator<E> it) {
01292         ++m_count;
01293         return ListPure<E>::insertAfter(x,it);
01294     }
01295 
01296     // removes first element
01297     void popFront() {
01298         --m_count;
01299         ListPure<E>::popFront();
01300     }
01301 
01302     // removes first element and returns it
01303     E popFrontRet() {
01304         E el = front(); 
01305         popFront();
01306         return el;
01307     }
01308 
01309     // removes last element
01310     void popBack() {
01311         --m_count;
01312         ListPure<E>::popBack();
01313     }
01314 
01315     // removes last element and returns it
01316     E popBackRet() {
01317         E el = back(); 
01318         popBack();
01319         return el;
01320     }
01321 
01322     void exchange(ListIterator<E> it1, ListIterator<E> it2) {
01323         ListPure<E>::exchange(it1,it2);
01324     }
01325 
01327 
01330     void moveToFront(ListIterator<E> it) {
01331         ListPure<E>::moveToFront(it);
01332     }
01334 
01337     void moveToBack(ListIterator<E> it) {
01338         ListPure<E>::moveToBack(it);
01339     }
01341 
01344     void moveToSucc(ListIterator<E> it, ListIterator<E> itBefore) {
01345         ListPure<E>::moveToSucc(it,itBefore);
01346     }
01348 
01351     void moveToPrec(ListIterator<E> it, ListIterator<E> itAfter) {
01352         ListPure<E>::moveToPrec(it,itAfter);
01353     }
01354 
01356 
01359     void moveToFront(ListIterator<E> it, List<E> &L2) {
01360         ListPure<E>::moveToFront(it,L2);
01361         --m_count; ++L2.m_count;
01362     }
01364 
01367     void moveToBack(ListIterator<E> it, List<E> &L2) {
01368         ListPure<E>::moveToBack(it,L2);
01369         --m_count; ++L2.m_count;
01370     }
01371 
01373 
01377     void moveToSucc(ListIterator<E> it, List<E> &L2, ListIterator<E> itBefore) {
01378         ListPure<E>::moveToSucc(it,L2,itBefore);
01379         --m_count; ++L2.m_count;
01380     }
01382 
01386     void moveToPrec(ListIterator<E> it, List<E> &L2, ListIterator<E> itAfter) {
01387         ListPure<E>::moveToPrec(it,L2,itAfter);
01388         --m_count; ++L2.m_count;
01389     }
01390 
01391     // removes it and frees memory
01392     void del(ListIterator<E> it) {
01393         --m_count;
01394         ListPure<E>::del(it);
01395     }
01396 
01398     void conc(List<E> &L2) {
01399         ListPure<E>::conc(L2);
01400         m_count += L2.m_count;
01401         L2.m_count = 0;
01402     }
01403     
01405     void concFront(List<E> &L2) {
01406         ListPure<E>::concFront(L2);
01407         m_count += L2.m_count;
01408         L2.m_count = 0;
01409     }
01410     
01412 
01415     void exchange(List<E>& L2) {
01416         ListPure<E>::exchange(L2);
01417         int t = this->m_count;
01418         this->m_count = L2.m_count; 
01419         L2.m_count = t; 
01420     }
01421     
01423 
01431     void split(ListIterator<E> it,List<E> &L1,List<E> &L2,Direction dir = before) {
01432         ListPure<E>::split(it,L1,L2,dir);
01433         int countL = m_count, countL1 = 0;
01434         for(ListElement<E> *pX = L1.m_head; pX != 0; pX = pX->m_next)
01435             ++countL1;
01436 
01437         L1.m_count = countL1;
01438         L2.m_count = countL - countL1;
01439         if (this->m_head == 0) m_count = 0;
01440     }
01441 
01442     // reverses the order of the list elements
01443     void reverse() { ListPure<E>::reverse(); }
01444 
01445     // removes all elements from list
01446     void clear() {
01447         m_count = 0;
01448         ListPure<E>::clear();
01449     }
01450 
01452     const ListPure<E> &getListPure() const { return *this; }
01453 
01454     // sorts list using quicksort
01455     void quicksort() {
01456         ogdf::quicksortTemplate(*this);
01457     }
01458 
01459     // sorts list using quicksort and parameterized compare element comp
01460     template<class COMPARER>
01461     void quicksort(const COMPARER &comp) {
01462         ogdf::quicksortTemplate(*this,comp);
01463     }
01464 
01465     // sorts list using bucket sort
01466     void bucketSort(int l, int h, BucketFunc<E> &f) {
01467         ListPure<E>::bucketSort(l,h,f);
01468     }
01469 
01470     // permutes elements in list randomly
01471     void permute() {
01472         ListPure<E>::permute(m_count);
01473     }
01474 
01476     int search (const E& e) const {
01477         return ListPure<E>::search(e);
01478     }
01479 
01481     template<class COMPARER>
01482     int search (const E& e, const COMPARER &comp) const {
01483         return ListPure<E>::search(e, comp);
01484     }
01485 
01486  
01487     OGDF_NEW_DELETE
01488 }; // class List
01489 
01490 
01491 
01492 template<class E>
01493 void ListPure<E>::bucketSort(int l, int h, BucketFunc<E> &f)
01494 {
01495     if (m_head == m_tail) return;
01496 
01497     Array<ListElement<E> *> head(l,h,0), tail(l,h);
01498 
01499     ListElement<E> *pX;
01500     for (pX = m_head; pX; pX = pX->m_next) {
01501         int i = f.getBucket(pX->m_x);
01502         if (head[i])
01503             tail[i] = ((pX->m_prev = tail[i])->m_next = pX);
01504         else
01505             head[i] = tail[i] = pX;
01506     }
01507 
01508     ListElement<E> *pY = 0;
01509     for (int i = l; i <= h; i++) {
01510         pX = head[i];
01511         if (pX) {
01512             if (pY) {
01513                 (pY->m_next = pX)->m_prev = pY;
01514             } else
01515                 (m_head = pX)->m_prev = 0;
01516             pY = tail[i];
01517         }
01518     }
01519     
01520     m_tail = pY;
01521     pY->m_next = 0;
01522 }
01523 
01524 
01525 // permutes elements in list randomly; n is the length of the list
01526 template<class E>
01527 void ListPure<E>::permute(const int n)
01528 {
01529     Array<ListElement<E> *> A(n+2);
01530     A[0] = A[n+1] = 0;
01531 
01532     int i = 1;
01533     ListElement<E> *pX;
01534     for (pX = m_head; pX; pX = pX->m_next)
01535         A[i++] = pX;
01536 
01537     A.permute(1,n);
01538 
01539     for (i = 1; i <= n; i++) {
01540         pX = A[i];
01541         pX->m_next = A[i+1];
01542         pX->m_prev = A[i-1];
01543     }
01544 
01545     m_head = A[1];
01546     m_tail = A[n];
01547 }
01548 
01549 
01550 // prints list L to output stream os using delimiter delim
01551 template<class E>
01552 void print(ostream &os, const ListPure<E> &L, char delim = ' ')
01553 {
01554     ListConstIterator<E> pX = L.begin();
01555     if (pX.valid()) {
01556         os << *pX;
01557         for(++pX; pX.valid(); ++pX)
01558             os << delim << *pX;
01559     }
01560 }
01561 
01562 // prints list L to output stream os using delimiter delim
01563 template<class E>
01564 void print(ostream &os, const List<E> &L, char delim = ' ')
01565 {
01566     print(os, L.getListPure(), delim);
01567 }
01568 
01569 // prints list L to output stream os
01570 template<class E>
01571 ostream &operator<<(ostream &os, const ListPure<E> &L)
01572 {
01573     print(os,L);
01574     return os;
01575 }
01576 
01577 // prints list L to output stream os
01578 template<class E>
01579 ostream &operator<<(ostream &os, const List<E> &L)
01580 {
01581     return os << L.getListPure();
01582 }
01583 
01584 
01585 } // end namespace ogdf
01586 
01587 
01588 #endif