My Project
|
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