Open
Graph Drawing
Framework

 v.2012.05
 

EList.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 
00095 #ifdef _MSC_VER
00096 #pragma once
00097 #endif
00098 
00099 #ifndef OGDF_ELIST_H
00100 #define OGDF_ELIST_H
00101 
00102 namespace ogdf {
00103 
00104 // EStack forward declaration
00105 template<typename S, typename E, E* S::*first, E* E::*next> class EStack;
00106 // EListIterator forward declaration
00107 template<typename E, E* E::*prev, E* E::*next> class EListIterator;
00108 // EList forward declaration
00109 template<typename L, typename E, int L::*numElem, E* L::*first, E* L::*last, E* E::*next, E* E::*prev> class EList;
00110 
00112 template<typename S, typename E, E* S::*first, E* E::*next>
00113 class EStack
00114 {
00115 public:
00117     static inline void init(S* pStack)
00118     {
00119         pStack->*first = 0;
00120     }
00121 
00123     static inline void pop(S* pStack)
00124     {
00125         pStack->*first = pStack->*first->*next;
00126     }
00127 
00129     static inline E* popRet(S* pStack)
00130     {
00131         E* res = pStack->*first;
00132         pStack->*first = pStack->*first->*next;
00133         return res;
00134     }
00135 
00137     static inline void push(S* pStack, E* pElem)
00138     {
00139         pElem->*next = pStack->*first;
00140         pStack->*first = pElem;
00141     }
00142 
00144     static inline E* top(const S* pStack)
00145     {
00146         return pStack->*first;
00147     }
00148 
00150     static inline bool empty(const S* pStack)
00151     {
00152         return (pStack->*first == 0);
00153     }
00154 };
00155 
00157 template<typename E, E* E::*prev, E* E::*next>
00158 class EListIterator
00159 {
00160 public:
00162     inline EListIterator( ) : m_ptr(0) {}
00163 
00165     inline EListIterator(E* ptr) : m_ptr(ptr) {}
00166 
00168     inline EListIterator(const EListIterator<E, prev, next>& other) : m_ptr(other.m_ptr) {}
00169 
00171     inline bool valid() const {  return (m_ptr != 0); }
00172 
00174     inline bool operator==(const EListIterator<E, prev, next>& other) const { return m_ptr == other.m_ptr; }
00175 
00177     inline bool operator!=(const EListIterator<E, prev, next>& other) const { return m_ptr != other.m_ptr; }
00178 
00180     inline EListIterator<E, prev, next> succ() const { return m_ptr->*next; }
00181 
00183     inline EListIterator<E, prev, next> pred() const { return m_ptr->*prev; }
00184 
00186     //E& operator*() const { return *m_ptr; }
00187 
00189     E* operator*() const { return m_ptr; }
00190 
00192     inline EListIterator<E, prev, next> &operator=(const EListIterator<E, prev, next>& other)
00193     {
00194         m_ptr = other.m_ptr;
00195         return *this;
00196     }
00197 
00199     inline EListIterator<E, prev, next>& operator++()
00200     {
00201         m_ptr = m_ptr->*next;
00202         return *this;
00203     }
00204 
00206     inline EListIterator<E, prev, next> operator++(int)
00207     {
00208         EListIterator<E, prev, next> it = *this;
00209         m_ptr = m_ptr->*next;
00210         return it;
00211     }
00212 
00214     inline EListIterator<E, prev, next>& operator--()
00215     {
00216         m_ptr = m_ptr->*prev;
00217         return *this;
00218     }
00219 
00221     inline EListIterator<E, prev, next> operator--(int)
00222     {
00223         EListIterator<E, prev, next> it = *this;
00224         m_ptr = m_ptr->*prev;
00225         return it;
00226     }
00227 
00228 private:
00230     E* m_ptr;
00231 };
00232 
00233 
00235 template<
00236     typename L,
00237     typename E,
00238     int L::*numElem,
00239     E* L::*first,
00240     E* L::*last,
00241     E* E::*next,
00242     E* E::*prev
00243 >
00244 class EList
00245 {
00246 public:
00248     typedef EListIterator<E, prev, next> iterator;
00249 
00251     static inline void init(L* pList)
00252     {
00253         pList->*first = 0;
00254         pList->*last = 0;
00255         pList->*numElem = 0;
00256     }
00257 
00259     static inline int size(const L* pList) { return (pList->*numElem); }
00260 
00262     static inline bool empty(const L* pList) { return (pList->*first == 0); }
00263 
00265     static inline E* front(const L* pList) { return pList->*first; }
00266 
00268     static inline E* back(const L* pList)   { return pList->*last; }
00269 
00271     static inline iterator pushBack(L* pList, E* elem)
00272     {
00273         elem->*next = 0;
00274         elem->*prev = pList->*last;
00275         if (pList->*last)
00276             pList->*last = pList->*last->*next = elem;
00277         else
00278             pList->*last = pList->*first = elem;
00279 
00280         (pList->*numElem)++;
00281         return iterator(elem);
00282     }
00283 
00285     static inline iterator pushFront(L* pList, E* elem)
00286     {
00287         elem->*next = pList->*first;
00288         elem->*prev = 0;
00289 
00290         if (pList->*first)
00291             pList->*first = pList->*first->*prev = elem;
00292         else
00293             pList->*first = pList->*last = elem;
00294 
00295         (pList->*numElem)++;
00296 
00297         return iterator(elem);
00298     }
00299 
00301     static inline iterator insertBefore(L* pList, E* elem, E* pNext)
00302     {
00303         E* pPrev;
00304 
00305         if (pNext)
00306             pPrev = pNext->*prev;
00307         else
00308             pPrev = 0;
00309 
00310         elem->*next = pNext;
00311         elem->*prev = pPrev;
00312 
00313         if (pNext)
00314             pNext->*prev = elem;
00315         else
00316             pList->*last = elem;
00317         if (pPrev)
00318             pPrev->*next = elem;
00319         else
00320             pList->*first = elem;
00321 
00322         (pList->*numElem)++;
00323         return iterator(elem);
00324     }
00325 
00327     static inline iterator insertBefore(L* pList, E* elem, const iterator& itNext)
00328     {
00329         return insertBefore(pList, elem, (E*)(*itNext));
00330     }
00331 
00333     static inline iterator insertAfter(L* pList, E* elem, E* pPrev)
00334     {
00335         E* pNext;
00336 
00337         if (pPrev)
00338             pNext = pPrev->*next;
00339         else
00340             pNext = 0;
00341 
00342         elem->*next = pNext;
00343         elem->*prev = pPrev;
00344 
00345         if (pNext)
00346             pNext->*prev = elem;
00347         else
00348             pList->*last = elem;
00349         if (pPrev)
00350             pPrev->*next = elem;
00351         else
00352             pList->*first = elem;
00353 
00354         (pList->*numElem)++;
00355         return iterator(elem);
00356     }
00357 
00359     static inline iterator insertAfter(L* pList, E* elem, const iterator& itPrev)
00360     {
00361         return insertAfter(pList, elem, (E*)(*itPrev));
00362     }
00363 
00365     inline static void popFront(L* pList)
00366     {
00367         if (front(pList))
00368             remove(pList, front(pList));
00369     }
00370 
00372     inline static void popBack(L* pList)
00373     {
00374         if (back(pList))
00375             remove(pList, back(pList));
00376     }
00377 
00379     static inline iterator remove(L* pList, E* elem)
00380     {
00381         E* pPrev = elem->*prev;
00382         E* pNext = elem->*next;
00383         if (pPrev)
00384             pPrev->*next = pNext;
00385         else
00386             pList->*first = pNext;
00387         if (pNext)
00388             pNext->*prev = pPrev;
00389         else
00390             pList->*last = pPrev;
00391 
00392         (pList->*numElem)--;
00393         return iterator(pNext);
00394     }
00395 
00397     static inline iterator remove(L* pList, const iterator& it)
00398     {
00399         return remove(pList, (E*)(*it));
00400     }
00401 
00402     template<
00403         typename L_other,
00404         E* L_other::*other_first,
00405         E* L_other::*other_last,
00406         int L_other::*other_numElem
00407     >
00408     inline static void appendFrom( L* pList, L_other* pListOther )
00409     {
00410         if (!pListOther->*other_first)
00411             return;
00412 
00413         if (empty(pList))
00414         {
00415             pList->*first = pListOther->*other_first;
00416             pList->*last = pListOther->*other_last;
00417         } else
00418         {
00419             // link the pList->last element to other->first
00420             pList->*last->*next = pListOther->*other_first;
00421             pListOther->*other_first->*prev = pList->*last;
00422 
00423             // link the pList->last element to other->first
00424             pList->*last = pListOther->*other_first;
00425         };
00426 
00427         // add the size of the other pList
00428         pList->*numElem += pListOther->*other_numElem;
00429         // clear other pList
00430         pListOther->*other_numElem = 0;
00431         pListOther->*other_first = 0;
00432         pListOther->*other_last = 0;
00433     }
00434 
00436     static inline iterator begin(const L* pList) { return iterator(pList->*first); }
00437 
00439     static inline iterator end(const L* pList) { return iterator(); }
00440 
00442     static inline iterator rbegin(const L* pList) { return iterator(pList->*last); }
00443 
00445     static inline iterator rend(const L* pList) { return iterator(); }
00446 
00447     template<typename Func>
00448     static inline void forall(const L* pList, const Func& func)
00449     {
00450         for(iterator it = begin(pList);it.valid();it++)
00451         {
00452             func(*it);
00453         };
00454     }
00455 
00456     template<typename A1>
00457     static inline void forall_call(const L* pList, void (E::*func)( A1 ), const A1& a1)
00458     {
00459         for(iterator it = begin(pList);it.valid();it++)
00460         {
00461             ((*it)->*func)(a1);
00462         };
00463     }
00464 
00466     inline EList(L* pList) : m_pList(pList) {};
00467 
00468     inline void init() { init(m_pList); };
00469 
00470     inline int size() const { return size(m_pList); };
00471     inline bool empty() const { return empty(m_pList); };
00472 
00473     inline E* front() const { return front(m_pList); };
00474     inline E* back() const { return back(m_pList); };
00475 
00476     inline iterator pushBack(E* elem) { return pushBack(m_pList, elem); };
00477     inline iterator pushFront(E* elem) { return pushFront(m_pList, elem); };
00478 
00479     inline iterator insertBefore(E* elem, E* pNext) { return insertBefore(m_pList, elem, pNext); } ;
00480     inline iterator insertBefore(E* elem, const iterator& it) { return insertBefore(m_pList, elem, it); } ;
00481 
00482     inline iterator insertAfter(E* elem, E* pPrev) { return insertAfter(m_pList, elem, pPrev); } ;
00483     inline iterator insertAfter(E* elem, const iterator& it) { return insertAfter(m_pList, elem, it); } ;
00484 
00485     inline void popFront() { popFront(m_pList); };
00486     inline void popBack() { popBack(m_pList); };
00487 
00488     void operator<<(E* elem) { pushBack(elem); };
00489 
00490     inline iterator remove(E* elem) { return remove(m_pList, elem); };
00491     inline iterator remove(const iterator& it)  { return remove(m_pList, (E*)(*it)); };
00492 
00493     inline iterator begin() const { return begin(m_pList); };
00494     inline iterator end() const { return end(m_pList); };
00495     inline iterator rbegin() const { return rbegin(m_pList); };
00496     inline iterator rend() const { return rend(m_pList); };
00497 
00498 private:
00499     L* m_pList;
00500 };
00501 
00502 
00503 } // end of namespace ogdf
00504 
00505 #endif