intrusive_list.hpp

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 } // namespace std
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 } // namespace GCpp
00253 
00254 #endif /* SRC_INC_INTRUSIVE_LIST_HPP */

Generated on Thu Dec 27 14:01:59 2007 for GC++ by  doxygen 1.5.4