|
Blender
V2.59
|
00001 /* 00002 * $Id: SG_DList.h 35082 2011-02-22 19:30:37Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00034 #ifndef __SG_DLIST 00035 #define __SG_DLIST 00036 00037 #include <stdlib.h> 00038 00039 #ifdef WITH_CXX_GUARDEDALLOC 00040 #include "MEM_guardedalloc.h" 00041 #endif 00042 00046 class SG_DList 00047 { 00048 protected : 00049 SG_DList* m_flink; 00050 SG_DList* m_blink; 00051 00052 public: 00053 template<typename T> class iterator 00054 { 00055 private: 00056 SG_DList& m_head; 00057 T* m_current; 00058 public: 00059 typedef iterator<T> _myT; 00060 iterator(SG_DList& head) : m_head(head), m_current(NULL) {} 00061 ~iterator() {} 00062 00063 void begin() 00064 { 00065 m_current = (T*)m_head.Peek(); 00066 } 00067 void back() 00068 { 00069 m_current = (T*)m_head.Back(); 00070 } 00071 bool end() 00072 { 00073 return (m_current == (T*)m_head.Self()); 00074 } 00075 bool add_back(T* item) 00076 { 00077 return m_current->AddBack(item); 00078 } 00079 T* operator*() 00080 { 00081 return m_current; 00082 } 00083 _myT& operator++() 00084 { 00085 // no check of NULL! make sure you don't try to increment beyond end 00086 m_current = (T*)m_current->Peek(); 00087 return *this; 00088 } 00089 _myT& operator--() 00090 { 00091 // no check of NULL! make sure you don't try to increment beyond end 00092 m_current = (T*)m_current->Back(); 00093 return *this; 00094 } 00095 }; 00096 00097 template<typename T> class const_iterator 00098 { 00099 private: 00100 const SG_DList& m_head; 00101 const T* m_current; 00102 public: 00103 typedef const_iterator<T> _myT; 00104 const_iterator(const SG_DList& head) : m_head(head), m_current(NULL) {} 00105 ~const_iterator() {} 00106 00107 void begin() 00108 { 00109 m_current = (const T*)m_head.Peek(); 00110 } 00111 void back() 00112 { 00113 m_current = (const T*)m_head.Back(); 00114 } 00115 bool end() 00116 { 00117 return (m_current == (const T*)m_head.Self()); 00118 } 00119 const T* operator*() 00120 { 00121 return m_current; 00122 } 00123 _myT& operator++() 00124 { 00125 // no check of NULL! make sure you don't try to increment beyond end 00126 m_current = (const T*)m_current->Peek(); 00127 return *this; 00128 } 00129 _myT& operator--() 00130 { 00131 // no check of NULL! make sure you don't try to increment beyond end 00132 m_current = (const T*)m_current->Back(); 00133 return *this; 00134 } 00135 }; 00136 00137 SG_DList() 00138 { 00139 m_flink = m_blink = this; 00140 } 00141 SG_DList(const SG_DList& other) 00142 { 00143 m_flink = m_blink = this; 00144 } 00145 virtual ~SG_DList() 00146 { 00147 Delink(); 00148 } 00149 00150 inline bool Empty() // Check for empty queue 00151 { 00152 return ( m_flink == this ); 00153 } 00154 bool AddBack( SG_DList *item ) // Add to the back 00155 { 00156 if (!item->Empty()) 00157 return false; 00158 item->m_blink = m_blink; 00159 item->m_flink = this; 00160 m_blink->m_flink = item; 00161 m_blink = item; 00162 return true; 00163 } 00164 bool AddFront( SG_DList *item ) // Add to the back 00165 { 00166 if (!item->Empty()) 00167 return false; 00168 item->m_flink = m_flink; 00169 item->m_blink = this; 00170 m_flink->m_blink = item; 00171 m_flink = item; 00172 return true; 00173 } 00174 SG_DList *Remove() // Remove from the front 00175 { 00176 if (Empty()) 00177 { 00178 return NULL; 00179 } 00180 SG_DList* item = m_flink; 00181 m_flink = item->m_flink; 00182 m_flink->m_blink = this; 00183 item->m_flink = item->m_blink = item; 00184 return item; 00185 } 00186 bool Delink() // Remove from the middle 00187 { 00188 if (Empty()) 00189 return false; 00190 m_blink->m_flink = m_flink; 00191 m_flink->m_blink = m_blink; 00192 m_flink = m_blink = this; 00193 return true; 00194 } 00195 inline SG_DList *Peek() // Look at front without removing 00196 { 00197 return m_flink; 00198 } 00199 inline SG_DList *Back() // Look at front without removing 00200 { 00201 return m_blink; 00202 } 00203 inline SG_DList *Self() 00204 { 00205 return this; 00206 } 00207 inline const SG_DList *Peek() const // Look at front without removing 00208 { 00209 return (const SG_DList*)m_flink; 00210 } 00211 inline const SG_DList *Back() const // Look at front without removing 00212 { 00213 return (const SG_DList*)m_blink; 00214 } 00215 inline const SG_DList *Self() const 00216 { 00217 return this; 00218 } 00219 00220 00221 #ifdef WITH_CXX_GUARDEDALLOC 00222 public: 00223 void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:SG_DList"); } 00224 void operator delete( void *mem ) { MEM_freeN(mem); } 00225 #endif 00226 }; 00227 00232 template<typename T> class SG_DListHead : public SG_DList 00233 { 00234 public: 00235 typedef SG_DListHead<T> _myT; 00236 SG_DListHead() : SG_DList() {} 00237 SG_DListHead(const _myT& other) : SG_DList() 00238 { 00239 // copy the list, assuming objects of type T 00240 const_iterator<T> eit(other); 00241 T* elem; 00242 for (eit.begin(); !eit.end(); ++eit) { 00243 elem = (*eit)->GetReplica(); 00244 AddBack(elem); 00245 } 00246 } 00247 virtual ~SG_DListHead() {} 00248 T* Remove() 00249 { 00250 return static_cast<T*>(SG_DList::Remove()); 00251 } 00252 00253 }; 00254 00255 #endif //__SG_DLIST 00256