Blender V2.61 - r43446

SG_DList.h

Go to the documentation of this file.
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