OpenTTD
pool_type.hpp
Go to the documentation of this file.
1 /* $Id: pool_type.hpp 26333 2014-02-11 20:34:48Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #ifndef POOL_TYPE_HPP
13 #define POOL_TYPE_HPP
14 
15 #include "smallvec_type.hpp"
16 #include "enum_type.hpp"
17 
19 enum PoolType {
20  PT_NONE = 0x00,
21  PT_NORMAL = 0x01,
22  PT_NCLIENT = 0x02,
23  PT_NADMIN = 0x04,
24  PT_DATA = 0x08,
25  PT_ALL = 0x0F,
26 };
28 
29 typedef SmallVector<struct PoolBase *, 4> PoolVector;
30 
32 struct PoolBase {
33  const PoolType type;
34 
39  static PoolVector *GetPools()
40  {
41  static PoolVector *pools = new PoolVector();
42  return pools;
43  }
44 
45  static void Clean(PoolType);
46 
51  PoolBase(PoolType pt) : type(pt)
52  {
53  *PoolBase::GetPools()->Append() = this;
54  }
55 
56  virtual ~PoolBase();
57 
61  virtual void CleanPool() = 0;
62 
63 private:
68  PoolBase(const PoolBase &other);
69 };
70 
82 template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size, PoolType Tpool_type = PT_NORMAL, bool Tcache = false, bool Tzero = true>
83 struct Pool : PoolBase {
84  /* Ensure Tmax_size is within the bounds of Tindex. */
85  assert_compile((uint64)(Tmax_size - 1) >> 8 * sizeof(Tindex) == 0);
86 
87  static const size_t MAX_SIZE = Tmax_size;
88 
89  const char * const name;
90 
91  size_t size;
92  size_t first_free;
93  size_t first_unused;
94  size_t items;
95 #ifdef OTTD_ASSERT
96  size_t checked;
97 #endif /* OTTD_ASSERT */
98  bool cleaning;
99 
100  Titem **data;
101 
102  Pool(const char *name);
103  virtual void CleanPool();
104 
111  inline Titem *Get(size_t index)
112  {
113  assert(index < this->first_unused);
114  return this->data[index];
115  }
116 
122  inline bool IsValidID(size_t index)
123  {
124  return index < this->first_unused && this->Get(index) != NULL;
125  }
126 
132  inline bool CanAllocate(size_t n = 1)
133  {
134  bool ret = this->items <= Tmax_size - n;
135 #ifdef OTTD_ASSERT
136  this->checked = ret ? n : 0;
137 #endif /* OTTD_ASSERT */
138  return ret;
139  }
140 
145  template <struct Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tpool_type, Tcache, Tzero> *Tpool>
146  struct PoolItem {
147  Tindex index;
148 
155  inline void *operator new(size_t size)
156  {
157  return Tpool->GetNew(size);
158  }
159 
165  inline void operator delete(void *p)
166  {
167  if (p == NULL) return;
168  Titem *pn = (Titem *)p;
169  assert(pn == Tpool->Get(pn->index));
170  Tpool->FreeItem(pn->index);
171  }
172 
181  inline void *operator new(size_t size, size_t index)
182  {
183  return Tpool->GetNew(size, index);
184  }
185 
194  inline void *operator new(size_t size, void *ptr)
195  {
196  for (size_t i = 0; i < Tpool->first_unused; i++) {
197  /* Don't allow creating new objects over existing.
198  * Even if we called the destructor and reused this memory,
199  * we don't know whether 'size' and size of currently allocated
200  * memory are the same (because of possible inheritance).
201  * Use { size_t index = item->index; delete item; new (index) item; }
202  * instead to make sure destructor is called and no memory leaks. */
203  assert(ptr != Tpool->data[i]);
204  }
205  return ptr;
206  }
207 
208 
216  static inline bool CanAllocateItem(size_t n = 1)
217  {
218  return Tpool->CanAllocate(n);
219  }
220 
225  static inline bool CleaningPool()
226  {
227  return Tpool->cleaning;
228  }
229 
235  static inline bool IsValidID(size_t index)
236  {
237  return Tpool->IsValidID(index);
238  }
239 
246  static inline Titem *Get(size_t index)
247  {
248  return Tpool->Get(index);
249  }
250 
257  static inline Titem *GetIfValid(size_t index)
258  {
259  return index < Tpool->first_unused ? Tpool->Get(index) : NULL;
260  }
261 
267  static inline size_t GetPoolSize()
268  {
269  return Tpool->first_unused;
270  }
271 
276  static inline size_t GetNumItems()
277  {
278  return Tpool->items;
279  }
280 
288  static inline void PostDestructor(size_t index) { }
289  };
290 
291 private:
292  static const size_t NO_FREE_ITEM = MAX_UVALUE(size_t);
293 
298  struct AllocCache {
301  };
302 
305 
306  void *AllocateItem(size_t size, size_t index);
307  void ResizeFor(size_t index);
308  size_t FindFirstFree();
309 
310  void *GetNew(size_t size);
311  void *GetNew(size_t size, size_t index);
312 
313  void FreeItem(size_t index);
314 };
315 
316 #define FOR_ALL_ITEMS_FROM(type, iter, var, start) \
317  for (size_t iter = start; var = NULL, iter < type::GetPoolSize(); iter++) \
318  if ((var = type::Get(iter)) != NULL)
319 
320 #define FOR_ALL_ITEMS(type, iter, var) FOR_ALL_ITEMS_FROM(type, iter, var, 0)
321 
322 #endif /* POOL_TYPE_HPP */
size_t first_unused
This and all higher indexes are free (doesn&#39;t say anything about first_unused-1 !) ...
Definition: pool_type.hpp:93
All pool types.
Definition: pool_type.hpp:25
DECLARE_ENUM_AS_BIT_SET(GenderEthnicity) enum CompanyManagerFaceVariable
Bitgroups of the CompanyManagerFace variable.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:257
Simple vector class that allows allocating an item without the need to copy this->data needlessly...
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
static PoolVector * GetPools()
Function used to access the vector of all pools.
Definition: pool_type.hpp:39
bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:122
Base class for base of all pools.
Definition: pool_type.hpp:32
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
AllocCache * alloc_cache
Cache of freed pointers.
Definition: pool_type.hpp:304
Simple vector template class.
Normal pool containing game objects.
Definition: pool_type.hpp:21
Type (helpers) for enums.
T * Append(uint to_add=1)
Append an item and return it.
Network client pools.
Definition: pool_type.hpp:22
static const size_t MAX_SIZE
Make template parameter accessible from outside.
Definition: pool_type.hpp:87
static void PostDestructor(size_t index)
Dummy function called after destructor of each member.
Definition: pool_type.hpp:288
static size_t GetPoolSize()
Returns first unused index.
Definition: pool_type.hpp:267
Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:111
static const size_t NO_FREE_ITEM
Constant to indicate we can&#39;t allocate any more items.
Definition: pool_type.hpp:292
PoolBase(PoolType pt)
Constructor registers this object in the pool vector.
Definition: pool_type.hpp:51
Helper struct to cache &#39;freed&#39; PoolItems so we do not need to allocate them again.
Definition: pool_type.hpp:298
bool cleaning
True if cleaning pool (deleting all items)
Definition: pool_type.hpp:98
NewGRF or other data, that is not reset together with normal pools.
Definition: pool_type.hpp:24
Titem ** data
Pointer to array of pointers to Titem.
Definition: pool_type.hpp:100
size_t items
Number of used indexes (non-NULL)
Definition: pool_type.hpp:94
#define MAX_UVALUE(type)
The largest value that can be entered in a variable.
Definition: stdafx.h:515
AllocCache * next
The next in our &#39;cache&#39;.
Definition: pool_type.hpp:300
Base class for all PoolItems.
Definition: pool_type.hpp:146
Base class for all pools.
Definition: pool_type.hpp:83
size_t first_free
No item with index lower than this is free (doesn&#39;t say anything about this one!) ...
Definition: pool_type.hpp:92
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
Definition: pool_type.hpp:225
PoolType
Various types of a pool.
Definition: pool_type.hpp:19
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:276
No pool is selected.
Definition: pool_type.hpp:20
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:216
bool CanAllocate(size_t n=1)
Tests whether we can allocate &#39;n&#39; items.
Definition: pool_type.hpp:132
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
size_t size
Current allocated size.
Definition: pool_type.hpp:91
SmallVector< struct PoolBase *, 4 > PoolVector
Vector of pointers to PoolBase.
Definition: pool_type.hpp:29
Network admin pool.
Definition: pool_type.hpp:23
const char *const name
Name of this pool.
Definition: pool_type.hpp:89
const PoolType type
Type of this pool.
Definition: pool_type.hpp:33
virtual void CleanPool()
Virtual method that deletes all items in the pool.