00001 #ifndef hpp_CPP_FIFO_CPP_hpp
00002 #define hpp_CPP_FIFO_CPP_hpp
00003
00004
00005
00006 #include <malloc.h>
00007
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
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
00061 if (currentSize == 0 && currentPos) Clear();
00062 if (currentSize >= allocatedSize || currentPos >= (allocatedSize - currentSize) * sizeof(T))
00063 {
00064
00065 if (allocatedSize == 0) allocatedSize = 2; else allocatedSize *= 2;
00066
00067 array = (uint8*)realloc(array, allocatedSize*sizeof(T));
00068 if (array == NULL) { Reset(); return; }
00069 }
00070
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
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
00169 if (currentSize == 0 && currentPos) Clear(ref);
00170 if (currentSize >= allocatedSize)
00171 {
00172
00173 if (allocatedSize == 0) allocatedSize = 2; else allocatedSize *= 2;
00174
00175 array = (T**)realloc(array, allocatedSize*elementSize);
00176 if (array == NULL) { Reset(); return; }
00177 }
00178
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