27template <
typename Tindex>
28using AllocationResult = std::pair<void *, Tindex>;
46template <
typename TBaseType,
typename TTag, TBaseType TEnd, TBaseType TInval
id>
48 using BaseType = TBaseType;
50 constexpr PoolID() =
default;
51 constexpr PoolID(
const PoolID &) =
default;
52 constexpr PoolID(PoolID &&) =
default;
54 explicit constexpr PoolID(
const TBaseType &value) : value(value) {}
56 constexpr PoolID &operator =(
const PoolID &rhs) { this->value = rhs.value;
return *
this; }
57 constexpr PoolID &operator =(PoolID &&rhs) { this->value = std::move(rhs.value);
return *
this; }
60 constexpr TBaseType base()
const noexcept {
return this->value; }
62 static constexpr PoolID
Begin() {
return PoolID{}; }
63 static constexpr PoolID
End() {
return PoolID{
static_cast<TBaseType
>(TEnd)}; }
64 static constexpr PoolID
Invalid() {
return PoolID{
static_cast<TBaseType
>(TInvalid)}; }
66 constexpr auto operator++() { ++this->value;
return this; }
67 constexpr auto operator+(
const std::integral
auto &val)
const {
return this->value + val; }
68 constexpr auto operator-(
const std::integral
auto &val)
const {
return this->value - val; }
69 constexpr auto operator%(
const std::integral
auto &val)
const {
return this->value % val; }
71 constexpr bool operator==(
const PoolID<TBaseType, TTag, TEnd, TInvalid> &rhs)
const {
return this->value == rhs.value; }
72 constexpr auto operator<=>(
const PoolID<TBaseType, TTag, TEnd, TInvalid> &rhs)
const {
return this->value <=> rhs.value; }
74 constexpr bool operator==(
const size_t &rhs)
const {
return this->value == rhs; }
75 constexpr auto operator<=>(
const size_t &rhs)
const {
return this->value <=> rhs; }
81template <
typename T>
requires std::is_base_of_v<PoolIDBase, T>
82constexpr auto operator+(
const std::integral
auto &val,
const T &pool_id) {
return pool_id + val; }
83template <
typename Te,
typename Tp>
requires std::is_enum_v<Te> && std::is_base_of_v<PoolIDBase, Tp>
100 static void Clean(PoolTypes);
135template <
class Titem,
typename Tindex,
size_t Tgrowth_step, PoolType Tpool_type = PoolType::Normal,
bool Tcache = false>
136requires std::is_base_of_v<PoolIDBase, Tindex>
139 static constexpr size_t MAX_SIZE = Tindex::End().base();
141 using IndexType = Tindex;
142 using BitmapStorage = size_t;
143 static constexpr size_t BITMAP_SIZE = std::numeric_limits<BitmapStorage>::digits;
167 inline Titem *
Get(
size_t index)
170 return this->data[index];
180 return index < this->first_unused && this->
Get(index) !=
nullptr;
190 bool ret = this->items <=
MAX_SIZE - n;
192 this->checked = ret ? n : 0;
202 struct PoolIterator {
203 typedef T value_type;
205 typedef T &reference;
206 typedef size_t difference_type;
207 typedef std::forward_iterator_tag iterator_category;
209 explicit PoolIterator(
size_t index) : index(index)
211 this->ValidateIndex();
214 bool operator==(
const PoolIterator &other)
const {
return this->index == other.index; }
215 T * operator*()
const {
return T::Get(this->index); }
216 PoolIterator & operator++() { this->index++; this->ValidateIndex();
return *
this; }
222 while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++;
223 if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
232 struct IterateWrapper {
234 IterateWrapper(
size_t from = 0) : from(from) {}
237 bool empty() {
return this->begin() == this->end(); }
244 template <
class T,
class F>
245 struct PoolIteratorFiltered {
246 typedef T value_type;
248 typedef T &reference;
249 typedef size_t difference_type;
250 typedef std::forward_iterator_tag iterator_category;
252 explicit PoolIteratorFiltered(
size_t index, F filter) : index(index), filter(filter)
254 this->ValidateIndex();
257 bool operator==(
const PoolIteratorFiltered &other)
const {
return this->index == other.index; }
258 T * operator*()
const {
return T::Get(this->index); }
259 PoolIteratorFiltered & operator++() { this->index++; this->ValidateIndex();
return *
this; }
266 while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++;
267 if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
275 template <
class T,
class F>
276 struct IterateWrapperFiltered {
279 IterateWrapperFiltered(
size_t from, F filter) : from(from), filter(filter) {}
282 bool empty() {
return this->begin() == this->end(); }
289 template <struct Pool<Titem, Tindex, Tgrowth_step, Tpool_type, Tcache> *Tpool>
300 typedef struct Pool<Titem, Tindex, Tgrowth_step, Tpool_type, Tcache>
Pool;
303 inline void *
operator new(size_t) =
delete;
311 inline void operator delete(
void *p,
size_t size)
313 if (p ==
nullptr)
return;
314 Titem *pn =
static_cast<Titem *
>(p);
315 assert(pn == Tpool->Get(Pool::GetRawIndex(pn->index)));
316 Tpool->FreeItem(size, Pool::GetRawIndex(pn->index));
320 inline void *
operator new(
size_t size, Tindex
index) =
delete;
323 inline void *
operator new(size_t,
void *ptr) =
delete;
331 template <
typename T = Titem,
typename... Targs>
332 requires std::is_base_of_v<Titem, T>
333 static inline T *
Create(Targs &&... args)
335 auto [
data,
index] = Tpool->GetNew(
sizeof(T));
336 return ::new (
data) T(
index, std::forward<Targs&&>(args)...);
345 template <
typename T = Titem,
typename... Targs>
346 requires std::is_base_of_v<Titem, T>
349 auto [
data, _] = Tpool->GetNew(
sizeof(T),
index.base());
350 return ::new (
data) T(
index, std::forward<Targs&&>(args)...);
362 return Tpool->CanAllocate(n);
371 return Tpool->cleaning;
381 return Tpool->IsValidID(GetRawIndex(
index));
392 return Tpool->Get(GetRawIndex(
index));
403 return GetRawIndex(
index) < Tpool->first_unused ? Tpool->Get(GetRawIndex(
index)) :
nullptr;
413 return Tpool->first_unused;
456 std::allocator<uint8_t> allocator{};
462 AllocationResult<Tindex>
GetNew(
size_t size);
463 AllocationResult<Tindex>
GetNew(
size_t size,
size_t index);
467 static constexpr size_t GetRawIndex(
size_t index) {
return index; }
468 template <
typename T>
requires std::is_base_of_v<PoolIDBase, T>
469 static constexpr size_t GetRawIndex(
const T &index) {
return index.base(); }
@ Begin
The lowest valid value.
@ Invalid
Invalid base price.
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.
constexpr enum_type operator-(enum_type e, int offset)
Sub integer.
constexpr enum_type operator+(enum_type e, int offset)
Add integer.
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.
Helper struct to cache 'freed' PoolItems so we do not need to allocate them again.
AllocCache * next
The next in our 'cache'.
PoolItem(Tindex index)
Construct the item.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static T * CreateAtIndex(Tindex index, Targs &&... args)
Creates a new T-object in the associated pool.
static size_t GetPoolSize()
Returns first unused index.
struct Pool< Titem, Tindex, Tgrowth_step, Tpool_type, Tcache > Pool
Type of the pool this item is going to be part of.
static Titem * Get(auto index)
Returns Titem with given index.
static size_t GetNumItems()
Returns number of valid items in the pool.
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 T * Create(Targs &&... args)
Creates a new T-object in the associated pool.
const Tindex index
Index of this pool item.
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.
static const size_t NO_FREE_ITEM
bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
size_t FindFirstFree()
Searches for first free index.
void CleanPool() override
Destroys all items in the pool and resets all member variables.
const std::string_view name
std::vector< EngineRenew * > data
AllocationResult< Tindex > AllocateItem(size_t size, size_t index)
Makes given index valid.
std::vector< BitmapStorage > used_bitmap
void ResizeFor(size_t index)
Resizes the pool so 'index' can be addressed.
static constexpr size_t MAX_SIZE
Titem * Get(size_t index)
Returns Titem with given index.
AllocationResult< Tindex > GetNew(size_t size)
Allocates new item.
void FreeItem(size_t size, size_t index)
Deallocates memory used by this index and marks item as free.
AllocationResult< Tindex > GetNew(size_t size, size_t index)
Allocates new item with given index.
bool CanAllocate(size_t n=1)
Tests whether we can allocate 'n' items.