Blender  V2.59
SG_DList.h
Go to the documentation of this file.
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