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
00040 Pool(const char *name);
00041 void CleanPool();
00042
00049 FORCEINLINE Titem *Get(size_t index)
00050 {
00051 assert(index < this->first_unused);
00052 return this->data[index];
00053 }
00054
00060 FORCEINLINE bool IsValidID(size_t index)
00061 {
00062 return index < this->first_unused && this->Get(index) != NULL;
00063 }
00064
00070 FORCEINLINE bool CanAllocate(size_t n = 1)
00071 {
00072 return this->items <= Tmax_size - n;
00073 }
00074
00079 template <struct Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tcache, Tzero> *Tpool>
00080 struct PoolItem {
00081 Tindex index;
00082
00089 FORCEINLINE void *operator new(size_t size)
00090 {
00091 return Tpool->GetNew(size);
00092 }
00093
00099 FORCEINLINE void operator delete(void *p)
00100 {
00101 Titem *pn = (Titem *)p;
00102 assert(pn == Tpool->Get(pn->index));
00103 Tpool->FreeItem(pn->index);
00104 }
00105
00114 FORCEINLINE void *operator new(size_t size, size_t index)
00115 {
00116 return Tpool->GetNew(size, index);
00117 }
00118
00127 FORCEINLINE void *operator new(size_t size, void *ptr)
00128 {
00129 for (size_t i = 0; i < Tpool->first_unused; i++) {
00130
00131
00132
00133
00134
00135
00136 assert(ptr != Tpool->data[i]);
00137 }
00138 return ptr;
00139 }
00140
00141
00149 static FORCEINLINE bool CanAllocateItem(size_t n = 1)
00150 {
00151 return Tpool->CanAllocate(n);
00152 }
00153
00158 static FORCEINLINE bool CleaningPool()
00159 {
00160 return Tpool->cleaning;
00161 }
00162
00168 static FORCEINLINE bool IsValidID(size_t index)
00169 {
00170 return Tpool->IsValidID(index);
00171 }
00172
00179 static FORCEINLINE Titem *Get(size_t index)
00180 {
00181 return Tpool->Get(index);
00182 }
00183
00190 static FORCEINLINE Titem *GetIfValid(size_t index)
00191 {
00192 return index < Tpool->first_unused ? Tpool->Get(index) : NULL;
00193 }
00194
00200 static FORCEINLINE size_t GetPoolSize()
00201 {
00202 return Tpool->first_unused;
00203 }
00204
00209 static FORCEINLINE size_t GetNumItems()
00210 {
00211 return Tpool->items;
00212 }
00213
00221 static FORCEINLINE void PostDestructor(size_t index) { }
00222 };
00223
00224 private:
00225 static const size_t NO_FREE_ITEM = MAX_UVALUE(size_t);
00226
00231 struct AllocCache {
00233 AllocCache *next;
00234 };
00235
00237 AllocCache *alloc_cache;
00238
00239 void *AllocateItem(size_t size, size_t index);
00240 void ResizeFor(size_t index);
00241 size_t FindFirstFree();
00242
00243 void *GetNew(size_t size);
00244 void *GetNew(size_t size, size_t index);
00245
00246 void FreeItem(size_t index);
00247 };
00248
00249 #define FOR_ALL_ITEMS_FROM(type, iter, var, start) \
00250 for (size_t iter = start; var = NULL, iter < type::GetPoolSize(); iter++) \
00251 if ((var = type::Get(iter)) != NULL)
00252
00253 #define FOR_ALL_ITEMS(type, iter, var) FOR_ALL_ITEMS_FROM(type, iter, var, 0)
00254
00255 #endif