00001 #ifndef SRC_INC_INTRUSIVE_LIST_HPP
00002 #define SRC_INC_INTRUSIVE_LIST_HPP
00003
00004 #include <boost/iterator/iterator_facade.hpp>
00005 #include <boost/concept_check.hpp>
00006
00007 namespace std
00008 {
00009
00010 template<class T>
00011 struct LinkableConcept
00012 {
00013 void constraints ()
00014 {
00015 srl->next = srl->prior;
00016 srl->prior = srl->next;
00017 srl->next = srl;
00018 }
00019
00020 T* srl;
00021 };
00022
00023 }
00024
00025 namespace GCpp
00026 {
00027
00028 template <class T>
00029 class IntrusiveListIterator : public boost::iterator_facade
00030 <
00031 IntrusiveListIterator<T>,
00032 T,
00033 boost::bidirectional_traversal_tag
00034 >
00035 {
00036 private:
00037 mutable T f_current;
00038
00039 void increment ()
00040 {
00041 f_current = f_current->next;
00042 }
00043
00044 void decrement ()
00045 {
00046 f_current = f_current->prior;
00047 }
00048
00049 bool equal (const IntrusiveListIterator<T>& p_other) const
00050 {
00051 return this->f_current == p_other.f_current;
00052 }
00053
00054 T& dereference () const
00055 {
00056 return f_current;
00057 }
00058
00059 friend class boost::iterator_core_access;
00060
00061 public:
00062 IntrusiveListIterator ()
00063 : f_current (0)
00064 {}
00065
00066 explicit IntrusiveListIterator (T p_item)
00067 : f_current (p_item)
00068 {}
00069 };
00070
00071 template <class T>
00072 class IntrusiveList
00073 {
00074 BOOST_CLASS_REQUIRE(T, std, LinkableConcept);
00075
00076 public:
00077 typedef IntrusiveListIterator<T*> iterator;
00078 typedef IntrusiveListIterator<const T*> const_iterator;
00079
00080 private:
00081 T* f_root;
00082 T* f_tail;
00083
00084 void remove_node (T* p_item)
00085 {
00086 bool fin (false);
00087
00088 if (f_root == p_item)
00089 {
00090 fin = true;
00091 f_root = f_root->next;
00092
00093 if (f_root)
00094 f_root->prior = 0;
00095 }
00096
00097 if (f_tail == p_item)
00098 {
00099 fin = true;
00100 f_tail = p_item->prior;
00101
00102 if (f_tail)
00103 f_tail->next = 0;
00104 }
00105
00106 if (not fin)
00107 {
00108 if (p_item->prior)
00109 p_item->prior->next = p_item->next;
00110
00111 if (p_item->next)
00112 p_item->next->prior = p_item->prior;
00113 }
00114 }
00115
00116 public:
00117 IntrusiveList ()
00118 : f_root (0),
00119 f_tail (0)
00120 {}
00121
00122 ~IntrusiveList ()
00123 {
00124 f_root = 0;
00125 f_tail = 0;
00126 }
00127
00128 bool empty () const
00129 {
00130 return f_root == 0;
00131 }
00132
00133 void push_back (T* p_item)
00134 {
00135 if (f_root == 0)
00136 {
00137 f_root = p_item;
00138 f_tail = p_item;
00139 p_item->next = 0;
00140 p_item->prior = 0;
00141 }
00142 else
00143 {
00144 f_tail->next = p_item;
00145 p_item->prior = f_tail;
00146 p_item->next = 0;
00147 f_tail = p_item;
00148 }
00149 }
00150
00151 iterator erase (iterator p_loc)
00152 {
00153 if (p_loc != end ())
00154 {
00155 T* cur (*p_loc);
00156 ++p_loc;
00157 remove_node (cur);
00158 }
00159
00160 return p_loc;
00161 }
00162
00163 void remove (T* p_item)
00164 {
00165 remove_node (p_item);
00166 }
00167
00168 void insert (iterator p_loc, T* p_item)
00169 {
00170 T* cur (*p_loc);
00171 p_item->next = cur;
00172
00173 if (cur)
00174 {
00175 if (cur->prior)
00176 cur->prior->next = p_item;
00177
00178 p_item->prior = cur->prior;
00179 cur->prior = p_item;
00180
00181 if (cur == f_root)
00182 {
00183 f_root = p_item;
00184 f_root->prior = 0;
00185 }
00186 }
00187 else
00188 {
00189 p_item->prior = f_tail;
00190
00191 if (f_tail)
00192 f_tail->next = p_item;
00193
00194 f_tail = p_item;
00195
00196 if (f_root == 0)
00197 f_root = p_item;
00198 }
00199 }
00200
00201 void clear ()
00202 {
00203 f_root = 0;
00204 f_tail = 0;
00205 }
00206
00207 size_t size ()
00208 {
00209 T* cur (f_root);
00210 size_t res (0);
00211
00212 while (cur)
00213 {
00214 ++res;
00215 cur = cur->next;
00216 }
00217
00218 return res;
00219 }
00220
00221 iterator begin ()
00222 {
00223 return iterator (f_root);
00224 }
00225
00226 const_iterator begin () const
00227 {
00228 return const_iterator (f_root);
00229 }
00230
00231 iterator end ()
00232 {
00233 return iterator ();
00234 }
00235
00236 const_iterator end () const
00237 {
00238 return const_iterator ();
00239 }
00240
00241 T* root () const
00242 {
00243 return f_root;
00244 }
00245
00246 T* tail () const
00247 {
00248 return f_tail;
00249 }
00250 };
00251
00252 }
00253
00254 #endif