My Project
sql_plist.h
00001 #ifndef SQL_PLIST_H
00002 #define SQL_PLIST_H
00003 /* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
00004 
00005    This program is free software; you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; version 2 of the License.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012    GNU General Public License for more details.
00013 
00014    You should have received a copy of the GNU General Public License
00015    along with this program; if not, write to the Free Software Foundation,
00016    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
00017 
00018 
00019 #include <my_global.h>
00020 
00021 template <typename T, typename L>
00022 class I_P_List_iterator;
00023 class I_P_List_null_counter;
00024 template <typename T> class I_P_List_no_push_back;
00025 
00026 
00064 template <typename T, typename B,
00065           typename C = I_P_List_null_counter,
00066           typename I = I_P_List_no_push_back<T> >
00067 class I_P_List : public C, public I
00068 {
00069   T *m_first;
00070 
00071   /*
00072     Do not prohibit copying of I_P_List object to simplify their usage in
00073     backup/restore scenarios. Note that performing any operations on such
00074     is a bad idea.
00075   */
00076 public:
00077   I_P_List() : I(&m_first), m_first(NULL) {};
00078   inline void empty()      { m_first= NULL; C::reset(); I::set_last(&m_first); }
00079   inline bool is_empty() const { return (m_first == NULL); }
00080   inline void push_front(T* a)
00081   {
00082     *B::next_ptr(a)= m_first;
00083     if (m_first)
00084       *B::prev_ptr(m_first)= B::next_ptr(a);
00085     else
00086       I::set_last(B::next_ptr(a));
00087     m_first= a;
00088     *B::prev_ptr(a)= &m_first;
00089     C::inc();
00090   }
00091   inline void push_back(T *a)
00092   {
00093     T **last= I::get_last();
00094     *B::next_ptr(a)= *last;
00095     *last= a;
00096     *B::prev_ptr(a)= last;
00097     I::set_last(B::next_ptr(a));
00098     C::inc();
00099   }
00100   inline void insert_after(T *pos, T *a)
00101   {
00102     if (pos == NULL)
00103       push_front(a);
00104     else
00105     {
00106       *B::next_ptr(a)= *B::next_ptr(pos);
00107       *B::prev_ptr(a)= B::next_ptr(pos);
00108       *B::next_ptr(pos)= a;
00109       if (*B::next_ptr(a))
00110       {
00111         T *old_next= *B::next_ptr(a);
00112         *B::prev_ptr(old_next)= B::next_ptr(a);
00113       }
00114       else
00115         I::set_last(B::next_ptr(a));
00116       C::inc();
00117     }
00118   }
00119   inline void remove(T *a)
00120   {
00121     T *next= *B::next_ptr(a);
00122     if (next)
00123       *B::prev_ptr(next)= *B::prev_ptr(a);
00124     else
00125       I::set_last(*B::prev_ptr(a));
00126     **B::prev_ptr(a)= next;
00127     C::dec();
00128   }
00129   inline T* front() { return m_first; }
00130   inline const T *front() const { return m_first; }
00131   inline T* pop_front()
00132   {
00133     T *result= front();
00134 
00135     if (result)
00136       remove(result);
00137 
00138     return result;
00139   }
00140   void swap(I_P_List<T, B, C> &rhs)
00141   {
00142     swap_variables(T *, m_first, rhs.m_first);
00143     I::swap(rhs);
00144     if (m_first)
00145       *B::prev_ptr(m_first)= &m_first;
00146     else
00147       I::set_last(&m_first);
00148     if (rhs.m_first)
00149       *B::prev_ptr(rhs.m_first)= &rhs.m_first;
00150     else
00151       I::set_last(&rhs.m_first);
00152     C::swap(rhs);
00153   }
00154   typedef B Adapter;
00155   typedef I_P_List<T, B, C, I> Base;
00156   typedef I_P_List_iterator<T, Base> Iterator;
00157   typedef I_P_List_iterator<const T, Base> Const_Iterator;
00158 #ifndef _lint
00159   friend class I_P_List_iterator<T, Base>;
00160   friend class I_P_List_iterator<const T, Base>;
00161 #endif
00162 };
00163 
00164 
00169 template <typename T, typename L>
00170 class I_P_List_iterator
00171 {
00172   const L *list;
00173   T *current;
00174 public:
00175   I_P_List_iterator(const L &a)
00176     : list(&a), current(a.m_first) {}
00177   I_P_List_iterator(const L &a, T* current_arg)
00178     : list(&a), current(current_arg) {}
00179   inline void init(const L &a)
00180   {
00181     list= &a;
00182     current= a.m_first;
00183   }
00184   inline T* operator++(int)
00185   {
00186     T *result= current;
00187     if (result)
00188       current= *L::Adapter::next_ptr(current);
00189     return result;
00190   }
00191   inline T* operator++()
00192   {
00193     current= *L::Adapter::next_ptr(current);
00194     return current;
00195   }
00196   inline void rewind()
00197   {
00198     current= list->m_first;
00199   }
00200 };
00201 
00202 
00208 template <typename T, T* T::*next, T** T::*prev>
00209 struct I_P_List_adapter
00210 {
00211   static inline T **next_ptr(T *el) { return &(el->*next); }
00212   static inline const T* const* next_ptr(const T *el) { return &(el->*next); }
00213   static inline T ***prev_ptr(T *el) { return &(el->*prev); }
00214 };
00215 
00216 
00222 class I_P_List_null_counter
00223 {
00224 protected:
00225   void reset() {}
00226   void inc() {}
00227   void dec() {}
00228   void swap(I_P_List_null_counter &rhs) {}
00229 };
00230 
00231 
00237 class I_P_List_counter
00238 {
00239   uint m_counter;
00240 protected:
00241   I_P_List_counter() : m_counter (0) {}
00242   void reset() {m_counter= 0;}
00243   void inc() {m_counter++;}
00244   void dec() {m_counter--;}
00245   void swap(I_P_List_counter &rhs)
00246   { swap_variables(uint, m_counter, rhs.m_counter); }
00247 public:
00248   uint elements() const { return m_counter; }
00249 };
00250 
00251 
00257 template <typename T> class I_P_List_no_push_back
00258 {
00259 protected:
00260   I_P_List_no_push_back(T **a) {};
00261   void set_last(T **a) {}
00262   /*
00263     T** get_last() const method is intentionally left unimplemented
00264     in order to prohibit usage of push_back() method in lists which
00265     use this policy.
00266   */
00267   void swap(I_P_List_no_push_back<T> &rhs) {}
00268 };
00269 
00270 
00276 template <typename T> class I_P_List_fast_push_back
00277 {
00278   T **m_last;
00279 protected:
00280   I_P_List_fast_push_back(T **a) : m_last(a) { };
00281   void set_last(T **a) { m_last= a; }
00282   T** get_last() const { return m_last; }
00283   void swap(I_P_List_fast_push_back<T> &rhs)
00284   { swap_variables(T**, m_last, rhs.m_last); }
00285 };
00286 
00287 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines