jigdo API
Last update by Admin on 2010-05-23
util/ilist.hh
Go to the documentation of this file.00001 /* $Id: ilist.hh,v 1.1 2003/09/12 23:07:20 atterer Exp $ -*- C++ -*- 00002 __ _ 00003 |_) /| Copyright (C) 2003 | richard@ 00004 | \/¯| Richard Atterer | atterer.net 00005 ¯ '` ¯ 00006 This program is free software; you can redistribute it and/or modify it 00007 under the terms of the GNU General Public License, version 2. See the file 00008 COPYING for details. 00009 00010 */ 00020 #ifndef ILIST_HH 00021 #define ILIST_HH 00022 00023 #include <config.h> 00024 00025 #include <debug.hh> 00026 #include <log.hh> 00027 //______________________________________________________________________ 00028 00030 class IListBase { 00031 template<class T> friend class IList; 00032 public: 00033 IListBase() : iListBase_prev(0), iListBase_next(0) { 00034 //msg("IListBase %1", this); 00035 } 00036 ~IListBase() { 00037 //msg("~IListBase %1", this); 00038 iList_remove(); 00039 } 00041 void iList_remove() { 00042 if (iListBase_prev == 0) return; 00043 Paranoid(iListBase_next != 0); 00044 iListBase_prev->iListBase_next = iListBase_next; 00045 iListBase_next->iListBase_prev = iListBase_prev; 00046 iListBase_prev = iListBase_next = 0; 00047 } 00048 00049 private: 00050 IListBase* iListBase_prev; 00051 IListBase* iListBase_next; 00052 }; 00053 00055 template<class T> 00056 class IList { 00057 public: 00058 typedef unsigned size_type; 00059 typedef T value_type; 00060 class iterator; 00061 class const_iterator; 00062 friend class iterator; 00063 friend class const_iterator; 00064 typedef T& reference; 00065 typedef const T& const_reference; 00066 00067 IList() { e.iListBase_prev = e.iListBase_next = &e; } 00069 ~IList() { 00070 IListBase* p = e.iListBase_next; 00071 while (p != &e) { 00072 IListBase* q = p->iListBase_next; 00073 p->iListBase_prev = p->iListBase_next = 0; 00074 p = q; 00075 } 00076 e.iListBase_prev = e.iListBase_next = 0; 00077 } 00078 bool empty() const { return e.iListBase_next == &e; } 00079 void push_back(T& x) { 00080 //msg("IList::push_back %1", &x); 00081 00082 // Object must not already be a list member 00083 Assert(x.iListBase_prev == 0 && x.iListBase_next == 0); 00084 00085 x.iListBase_prev = e.iListBase_prev; 00086 x.iListBase_next = &e; 00087 x.iListBase_prev->iListBase_next = &x; 00088 x.iListBase_next->iListBase_prev = &x; 00089 } 00090 void push_front(T& x) { 00091 // Object must not already be a list member 00092 Assert(x.iListBase_prev == 0 && x.iListBase_next == 0); 00093 00094 x.iListBase_prev = &e; 00095 x.iListBase_next = e.iListBase_next; 00096 x.iListBase_prev->iListBase_next = &x; 00097 x.iListBase_next->iListBase_prev = &x; 00098 } 00099 00100 T& front() const { return *static_cast<T*>(e.iListBase_next); } 00101 T& back() const { return *static_cast<T*>(e.iListBase_prev); } 00102 00103 inline iterator begin() { 00104 return iterator(e.iListBase_next); } 00105 inline iterator end() { 00106 return iterator(&e); } 00107 inline const_iterator begin() const { 00108 return const_iterator(e.iListBase_next); } 00109 inline const_iterator end() const { 00110 return const_iterator(&e); } 00111 00112 private: 00113 // For the iterator class, which cannot be a friend of IListBase 00114 static inline IListBase* next(const IListBase* ilb) { 00115 return ilb->iListBase_next; } 00116 static inline IListBase* prev(const IListBase* ilb) { 00117 return ilb->iListBase_prev; } 00118 00119 IListBase e; 00120 }; 00121 00123 template<class T> 00124 class IList<T>::iterator { 00125 friend class const_iterator; 00126 public: 00127 iterator(IListBase* pp) : p(pp) { } 00128 iterator(const iterator& i) : p(i.p) { } 00129 iterator& operator=(const iterator& i) { p = i.p; return *this; } 00130 iterator& operator=(const const_iterator& i) { p = i.p; return *this; } 00131 00132 T& operator*() { return *getT(); } 00133 const T& operator*() const { return *getT(); } 00134 T* operator->() { return getT(); } 00135 const T* operator->() const { return getT(); } 00136 iterator& operator++() { p = IList<T>::next(p); return *this; } 00137 iterator& operator--() { p = IList<T>::prev(p); return *this; } 00138 bool operator==(const iterator i) const { return p == i.p; } 00139 bool operator!=(const iterator i) const { return p != i.p; } 00140 private: 00141 //T* getT() { return reinterpret_cast<T*>(p); } 00142 // Will not work if IListBase is an inaccessible base of T: 00143 T* getT() { return static_cast<T*>(p); } 00144 IListBase* p; 00145 }; 00146 00148 template<class T> 00149 class IList<T>::const_iterator { 00150 friend class iterator; 00151 public: 00152 const_iterator(IListBase* pp) : p(pp) { } 00153 const_iterator(const IListBase* pp) : p(pp) { } 00154 explicit const_iterator(const iterator& i) : p(i.p) { } 00155 const_iterator& operator=(const iterator& i) { p = i.p; return *this; } 00156 const_iterator(const const_iterator& i) : p(i.p) { } 00157 const_iterator& operator=(const const_iterator& i) { p = i.p; return *this; } 00158 00159 const T& operator*() const { return *getT(); } 00160 const T* operator->() const { return getT(); } 00161 const_iterator& operator++() { p = IList<T>::next(p); return *this; } 00162 const_iterator& operator--() { p = IList<T>::prev(p); return *this; } 00163 bool operator==(const const_iterator i) const { return p == i.p; } 00164 bool operator!=(const const_iterator i) const { return p != i.p; } 00165 private: 00166 //const T* getT() const { return reinterpret_cast<const T*>(p); } 00167 // Will not work if IListBase is an inaccessible base of T: 00168 const T* getT() const { return static_cast<const T*>(p); } 00169 const IListBase* p; 00170 }; 00171 00172 #endif
Generated on Tue Sep 23 14:27:41 2008 for jigdo by
