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