42template <
typename TBaseType,
typename TTag, TBaseType TEnd, TBaseType TInval
id>
44 using BaseType = TBaseType;
46 constexpr PoolID() =
default;
50 explicit constexpr PoolID(
const TBaseType &value) : value(value) {}
52 constexpr PoolID &operator =(
const PoolID &rhs) { this->value = rhs.value;
return *
this; }
53 constexpr PoolID &operator =(
PoolID &&rhs) { this->value = std::move(rhs.value);
return *
this; }
56 constexpr TBaseType base()
const noexcept {
return this->value; }
59 static constexpr PoolID End() {
return PoolID{
static_cast<TBaseType
>(TEnd)}; }
62 constexpr auto operator++() { ++this->value;
return this; }
63 constexpr auto operator+(
const std::integral
auto &val)
const {
return this->value + val; }
64 constexpr auto operator-(
const std::integral
auto &val)
const {
return this->value - val; }
65 constexpr auto operator%(
const std::integral
auto &val)
const {
return this->value % val; }
70 constexpr bool operator==(
const size_t &rhs)
const {
return this->value == rhs; }
71 constexpr auto operator<=>(
const size_t &rhs)
const {
return this->value <=> rhs; }
77template <
typename T>
requires std::is_base_of_v<PoolIDBase, T>
78constexpr auto operator+(
const std::integral
auto &val,
const T &pool_id) {
return pool_id + val; }
79template <
typename Te,
typename Tp>
requires std::is_enum_v<Te> && std::is_base_of_v<PoolIDBase, Tp>
80constexpr auto operator+(
const Te &val,
const Tp &pool_id) {
return pool_id +
to_underlying(val); }
131template <
class Titem,
typename Tindex,
size_t Tgrowth_step, PoolType Tpool_type = PoolType::Normal,
bool Tcache = false>
132requires std::is_base_of_v<PoolIDBase, Tindex>
135 static constexpr size_t MAX_SIZE = Tindex::End().base();
137 using BitmapStorage = size_t;
138 static constexpr size_t BITMAP_SIZE = std::numeric_limits<BitmapStorage>::digits;
140 const char *
const name =
nullptr;
162 inline Titem *
Get(
size_t index)
165 return this->
data[index];
175 return index < this->first_unused && this->
Get(index) !=
nullptr;
185 bool ret = this->items <=
MAX_SIZE - n;
187 this->checked = ret ? n : 0;
198 typedef T value_type;
200 typedef T &reference;
201 typedef size_t difference_type;
202 typedef std::forward_iterator_tag iterator_category;
206 this->ValidateIndex();
209 bool operator==(
const PoolIterator &other)
const {
return this->index == other.index; }
210 T * operator*()
const {
return T::Get(this->index); }
211 PoolIterator & operator++() { this->index++; this->ValidateIndex();
return *
this; }
217 while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++;
218 if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
232 bool empty() {
return this->begin() == this->end(); }
239 template <
class T,
class F>
241 typedef T value_type;
243 typedef T &reference;
244 typedef size_t difference_type;
245 typedef std::forward_iterator_tag iterator_category;
249 this->ValidateIndex();
253 T * operator*()
const {
return T::Get(this->index); }
261 while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++;
262 if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
270 template <
class T,
class F>
277 bool empty() {
return this->begin() == this->end(); }
284 template <struct Pool<Titem, Tindex, Tgrowth_step, Tpool_type, Tcache> *Tpool>
289 typedef struct Pool<Titem, Tindex, Tgrowth_step, Tpool_type, Tcache>
Pool;
297 inline void *
operator new(
size_t size)
299 return Tpool->GetNew(size);
307 inline void operator delete(
void *p,
size_t size)
309 if (p ==
nullptr)
return;
310 Titem *pn =
static_cast<Titem *
>(p);
311 assert(pn == Tpool->Get(Pool::GetRawIndex(pn->index)));
312 Tpool->FreeItem(size, Pool::GetRawIndex(pn->index));
323 inline void *
operator new(
size_t size, Tindex
index)
325 return Tpool->GetNew(size,
index.base());
335 inline void *
operator new(size_t,
void *ptr)
337 for (
size_t i = 0; i < Tpool->first_unused; i++) {
344 assert(ptr != Tpool->data[i]);
359 return Tpool->CanAllocate(n);
368 return Tpool->cleaning;
378 return Tpool->IsValidID(GetRawIndex(
index));
389 return Tpool->Get(GetRawIndex(
index));
400 return GetRawIndex(
index) < Tpool->first_unused ? Tpool->Get(GetRawIndex(
index)) :
nullptr;
410 return Tpool->first_unused;
453 std::allocator<uint8_t> allocator{};
455 void *AllocateItem(
size_t size,
size_t index);
456 void ResizeFor(
size_t index);
457 size_t FindFirstFree();
459 void *GetNew(
size_t size);
460 void *GetNew(
size_t size,
size_t index);
462 void FreeItem(
size_t size,
size_t index);
464 static constexpr size_t GetRawIndex(
size_t index) {
return index; }
465 template <
typename T>
requires std::is_base_of_v<PoolIDBase, T>
466 static constexpr size_t GetRawIndex(
const T &index) {
return index.base(); }
Type (helpers) for enums.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
constexpr enum_type & operator++(enum_type &e)
Prefix increment.
@ Invalid
GRF is unusable with this version of OpenTTD.
PoolType
Various types of a pool.
@ NetworkClient
Network client pools.
@ NetworkAdmin
Network admin pool.
@ Normal
Normal pool containing game objects.
@ Data
NewGRF or other data, that is not reset together with normal pools.
std::vector< struct PoolBase * > PoolVector
Vector of pointers to PoolBase.
Base class for base of all pools.
const PoolType type
Type of this pool.
virtual void CleanPool()=0
Virtual method that deletes all items in the pool.
static PoolVector * GetPools()
Function used to access the vector of all pools.
PoolBase(PoolType pt)
Constructor registers this object in the pool vector.
static void Clean(PoolTypes)
Clean all pools of given type.
virtual ~PoolBase()
Destructor removes this object from the pool vector and deletes the vector itself if this was the las...
PoolBase(const PoolBase &other)
Dummy private copy constructor to prevent compilers from copying the structure, which fails due to Ge...
Non-templated base for PoolID for use with type trait queries.
Templated helper to make a PoolID a single POD value.
Helper struct to cache 'freed' PoolItems so we do not need to allocate them again.
AllocCache * next
The next in our 'cache'.
Base class for all PoolItems.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static size_t GetPoolSize()
Returns first unused index.
static Titem * Get(auto index)
Returns Titem with given index.
static size_t GetNumItems()
Returns number of valid items in the pool.
Tindex index
Index of this pool item.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
static Titem * GetIfValid(auto index)
Returns Titem with given index.
static void PostDestructor(size_t index)
Dummy function called after destructor of each member.
Iterator to iterate all valid T of a pool.
Iterator to iterate all valid T of a pool.
Base class for all pools.
const char *const name
Name of this pool.
size_t first_free
No item with index lower than this is free (doesn't say anything about this one!)
static const size_t NO_FREE_ITEM
Constant to indicate we can't allocate any more items.
bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
AllocCache * alloc_cache
Cache of freed pointers.
size_t first_unused
This and all higher indexes are free (doesn't say anything about first_unused-1 !)
void CleanPool() override
Virtual method that deletes all items in the pool.
std::vector< Titem * > data
Pointers to Titem.
std::vector< BitmapStorage > used_bitmap
Bitmap of used indices.
bool cleaning
True if cleaning pool (deleting all items)
size_t items
Number of used indexes (non-nullptr)
static constexpr size_t MAX_SIZE
Make template parameter accessible from outside.
Titem * Get(size_t index)
Returns Titem with given index.
bool CanAllocate(size_t n=1)
Tests whether we can allocate 'n' items.