pool_type.hpp

Go to the documentation of this file.
00001 /* $Id: pool_type.hpp 18045 2009-11-11 21:15:58Z rubidium $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
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         /* Don't allow creating new objects over existing.
00133          * Even if we called the destructor and reused this memory,
00134          * we don't know whether 'size' and size of currently allocated
00135          * memory are the same (because of possible inheritance).
00136          * Use { size_t index = item->index; delete item; new (index) item; }
00137          * instead to make sure destructor is called and no memory leaks. */
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 /* POOL_TYPE_HPP */

Generated on Fri Dec 31 17:15:30 2010 for OpenTTD by  doxygen 1.6.1