pool_type.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef POOL_TYPE_HPP
00013 #define POOL_TYPE_HPP
00014
00025 template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size, bool Tcache = false, bool Tzero = true>
00026 struct Pool {
00027 static const size_t MAX_SIZE = Tmax_size;
00028
00029 const char * const name;
00030
00031 size_t size;
00032 size_t first_free;
00033 size_t first_unused;
00034 size_t items;
00035
00036 bool cleaning;
00037
00038 Titem **data;
00039
00041 Pool(const char *name);
00043 void CleanPool();
00044
00051 FORCEINLINE Titem *Get(size_t index)
00052 {
00053 assert(index < this->first_unused);
00054 return this->data[index];
00055 }
00056
00062 FORCEINLINE bool IsValidID(size_t index)
00063 {
00064 return index < this->first_unused && this->Get(index) != NULL;
00065 }
00066
00072 FORCEINLINE bool CanAllocate(size_t n = 1)
00073 {
00074 return this->items <= Tmax_size - n;
00075 }
00076
00081 template <struct Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tcache, Tzero> *Tpool>
00082 struct PoolItem {
00083 Tindex index;
00084
00091 FORCEINLINE void *operator new(size_t size)
00092 {
00093 return Tpool->GetNew(size);
00094 }
00095
00101 FORCEINLINE void operator delete(void *p)
00102 {
00103 Titem *pn = (Titem *)p;
00104 assert(pn == Tpool->Get(pn->index));
00105 Tpool->FreeItem(pn->index);
00106 }
00107
00116 FORCEINLINE void *operator new(size_t size, size_t index)
00117 {
00118 return Tpool->GetNew(size, index);
00119 }
00120
00129 FORCEINLINE void *operator new(size_t size, void *ptr)
00130 {
00131 for (size_t i = 0; i < Tpool->first_unused; i++) {
00132
00133
00134
00135
00136
00137
00138 assert(ptr != Tpool->data[i]);
00139 }
00140 return ptr;
00141 }
00142
00143
00151 static FORCEINLINE bool CanAllocateItem(size_t n = 1)
00152 {
00153 return Tpool->CanAllocate(n);
00154 }
00155
00160 static FORCEINLINE bool CleaningPool()
00161 {
00162 return Tpool->cleaning;
00163 }
00164
00170 static FORCEINLINE bool IsValidID(size_t index)
00171 {
00172 return Tpool->IsValidID(index);
00173 }
00174
00181 static FORCEINLINE Titem *Get(size_t index)
00182 {
00183 return Tpool->Get(index);
00184 }
00185
00192 static FORCEINLINE Titem *GetIfValid(size_t index)
00193 {
00194 return index < Tpool->first_unused ? Tpool->Get(index) : NULL;
00195 }
00196
00202 static FORCEINLINE size_t GetPoolSize()
00203 {
00204 return Tpool->first_unused;
00205 }
00206
00211 static FORCEINLINE size_t GetNumItems()
00212 {
00213 return Tpool->items;
00214 }
00215
00223 static FORCEINLINE void PostDestructor(size_t index) { }
00224 };
00225
00226 private:
00227 static const size_t NO_FREE_ITEM = MAX_UVALUE(size_t);
00228
00233 struct AllocCache {
00235 AllocCache *next;
00236 };
00237
00239 AllocCache *alloc_cache;
00240
00248 void *AllocateItem(size_t size, size_t index);
00249
00256 void ResizeFor(size_t index);
00257
00262 size_t FindFirstFree();
00263
00270 void *GetNew(size_t size);
00271
00279 void *GetNew(size_t size, size_t index);
00280
00287 void FreeItem(size_t index);
00288 };
00289
00290 #define FOR_ALL_ITEMS_FROM(type, iter, var, start) \
00291 for (size_t iter = start; var = NULL, iter < type::GetPoolSize(); iter++) \
00292 if ((var = type::Get(iter)) != NULL)
00293
00294 #define FOR_ALL_ITEMS(type, iter, var) FOR_ALL_ITEMS_FROM(type, iter, var, 0)
00295
00296 #endif