include/Tree/FIFO.hpp

Go to the documentation of this file.
00001 #ifndef hpp_CPP_FIFO_CPP_hpp
00002 #define hpp_CPP_FIFO_CPP_hpp
00003 
00004 
00005 // Need realloc
00006 #include <malloc.h>
00007 // Need new operator too
00008 #include <new>
00009 
00010 #ifdef _MSC_VER
00011 #pragma warning (disable:4786)
00012 #endif
00013 
00015 namespace Stack
00016 {
00018     namespace PlainOldData
00019     {
00040         template <typename T> 
00041         class FIFO
00042         {
00043         public:
00045             inline FIFO() : array(NULL), currentSize(0), currentPos(0), allocatedSize(0)    { }
00047             inline FIFO(const FIFO & other) : array(NULL), currentSize(0), currentPos(0), allocatedSize(0) { *this = other; }
00049             ~FIFO() { Clear(); }
00050 
00051         // Interface
00052         public:
00054             inline void Reset() { currentSize = 0; allocatedSize = 0; currentPos = 0; array = NULL; }
00056             inline T & Pop()    { if (currentSize == 0) return defaultElement; T& ref = *(T*)&array[currentPos]; currentPos += sizeof(T); currentSize --; return ref; }
00058             inline void Push(const T & ref) 
00059             {
00060                 // Check if the object can be freed
00061                 if (currentSize == 0 && currentPos) Clear();
00062                 if (currentSize >= allocatedSize || currentPos >= (allocatedSize - currentSize) * sizeof(T))
00063                 {
00064                     // Need to realloc the data
00065                     if (allocatedSize == 0) allocatedSize = 2; else allocatedSize *= 2;
00066                     // This will not work with type other than POD
00067                     array = (uint8*)realloc(array, allocatedSize*sizeof(T));
00068                     if (array == NULL) { Reset(); return; }
00069                 }
00070                 // Copy the data
00071                 new(&array[currentSize * sizeof(T) + currentPos]) T(ref);
00072                 currentSize ++;
00073             }
00074 
00076             inline const FIFO& operator = ( const FIFO <T>& fifo)
00077             {
00078                 Clear();
00079 
00080                 for (size_t i = 0; i < fifo.currentSize; i++)
00081                     Push(*(T*)&fifo.array[i * sizeof(T) + fifo.currentPos]);
00082 
00083                 return *this;
00084             }
00085             
00087             inline size_t getSize() const { return currentSize; }
00091             inline bool Forget(const T& avoidDeleting) { return false;  }
00092 
00093         private:
00095             inline void Clear() { while (currentSize)   { currentSize --; T * pPtr = (T*)&array[currentSize * sizeof(T) + currentPos]; pPtr->~T(); }
00096                                   while (currentPos)    { currentPos -= sizeof(T); T * pPtr = (T*)&array[currentPos]; pPtr->~T(); }
00097                                     if (array != NULL) realloc(array, 0);   Reset(); }
00098         private:
00100             uint8 *                                                 array;
00102             size_t                                                  currentPos;
00104             size_t                                                  currentSize;
00106             size_t                                                  allocatedSize;
00110             static T                                                defaultElement;
00111         };
00112         template <typename T> T FIFO<T>::defaultElement = 0;
00113     }
00114 
00116     namespace WithClone
00117     {
00146         template <typename T> 
00147         class FIFO
00148         {
00149         private:
00150             enum { elementSize = sizeof(T*) };
00151         public:
00153             inline FIFO() : array(NULL), currentSize(0), currentPos(0), allocatedSize(0)    { }
00155             inline FIFO(const FIFO & other) : array(NULL), currentSize(0), currentPos(0), allocatedSize(0) { *this = other; }
00157             ~FIFO()     { Clear(); }
00158 
00159         // Interface
00160         public:
00162             inline void Reset() { currentSize = 0; allocatedSize = 0; currentPos = 0; array = NULL; }
00164             inline T * Pop()    { if (currentSize == 0) return NULL; T* ref = array[currentPos]; currentPos ++; currentSize --; return ref; }
00166             inline void Push(T * ref) 
00167             {
00168                 // Check if the object can be freed
00169                 if (currentSize == 0 && currentPos) Clear(ref);
00170                 if (currentSize >= allocatedSize)
00171                 {
00172                     // Need to realloc the data
00173                     if (allocatedSize == 0) allocatedSize = 2; else allocatedSize *= 2;
00174                     // This will not work with type other than POD
00175                     array = (T**)realloc(array, allocatedSize*elementSize);
00176                     if (array == NULL) { Reset(); return; }
00177                 }
00178                 // Copy the data
00179                 array[currentSize + currentPos] = ref;
00180                 currentSize ++;
00181             }
00182 
00184             inline const FIFO& operator = ( const FIFO <T>& fifo)
00185             {
00186                 Clear();
00187                 for (size_t i = 0; i < fifo.currentSize; i++) Push(fifo.array[i + fifo.currentPos]->clone());
00188                 return *this;
00189             }
00190             
00192             inline size_t getSize() const { return currentSize; }
00197             inline bool Forget(T* avoidDeleting = NULL) 
00198             {   bool isFound = false;
00199                 size_t pos = 0; while (pos < currentPos) { if (array[pos] == avoidDeleting) { array[pos] = NULL; isFound = true; break; } pos ++; }
00200                 return isFound; }
00201 
00202         private:
00206             inline void Clear(T * ref = NULL) 
00207             {   while (currentSize) { currentSize --; T * pPtr = array[currentSize + currentPos]; if (pPtr != ref) delete pPtr; }
00208                 while (currentPos)  { currentPos --; T * pPtr = array[currentPos]; if (pPtr != ref) delete pPtr; }
00209                 if (array != NULL) realloc(array, 0);   Reset(); }
00210         private:
00212             T **                                                    array;
00214             size_t                                                  currentPos;
00216             size_t                                                  currentSize;
00218             size_t                                                  allocatedSize;
00219         };
00220     }
00221 }
00222 
00223 
00224 #endif

(C) An X-Ryl669 project 2007

This document describes Unlimited Zooming Interface source code. UZI stands for Unlimited Zooming Interface, and source code license is