30template <
typename Tindex>
31using AllocationResult = std::pair<void *, Tindex>;
49template <
typename TBaseType,
typename TTag, TBaseType TEnd, TBaseType TInval
id>
51 using BaseType = TBaseType;
53 constexpr PoolID() =
default;
54 constexpr PoolID(
const PoolID &) =
default;
55 constexpr PoolID(PoolID &&) =
default;
59 constexpr PoolID &operator =(
const PoolID &rhs) { this->value = rhs.
value;
return *
this; }
60 constexpr PoolID &operator =(PoolID &&rhs) { this->value = std::move(rhs.
value);
return *
this; }
63 constexpr TBaseType base()
const noexcept {
return this->value; }
65 static constexpr PoolID
Begin() {
return PoolID{}; }
66 static constexpr PoolID
End() {
return PoolID{
static_cast<TBaseType
>(TEnd)}; }
67 static constexpr PoolID
Invalid() {
return PoolID{
static_cast<TBaseType
>(TInvalid)}; }
69 constexpr auto operator++() { ++this->value;
return this; }
70 constexpr auto operator+(
const std::integral
auto &val)
const {
return this->value + val; }
71 constexpr auto operator-(
const std::integral
auto &val)
const {
return this->value - val; }
72 constexpr auto operator%(
const std::integral
auto &val)
const {
return this->value % val; }
74 constexpr bool operator==(
const PoolID<TBaseType, TTag, TEnd, TInvalid> &rhs)
const {
return this->value == rhs.
value; }
75 constexpr auto operator<=>(
const PoolID<TBaseType, TTag, TEnd, TInvalid> &rhs)
const {
return this->value <=> rhs.
value; }
77 constexpr bool operator==(
const size_t &rhs)
const {
return this->value == rhs; }
78 constexpr auto operator<=>(
const size_t &rhs)
const {
return this->value <=> rhs; }
84template <
typename T>
requires std::is_base_of_v<PoolIDBase, T>
85constexpr auto operator+(
const std::integral
auto &val,
const T &pool_id) {
return pool_id + val; }
86template <
typename Te,
typename Tp>
requires std::is_enum_v<Te> && std::is_base_of_v<PoolIDBase, Tp>
140template <
class Titem,
typename Tindex,
size_t Tgrowth_step, PoolType Tpool_type = PoolType::Normal,
bool Tcache = false>
141requires std::is_base_of_v<PoolIDBase, Tindex>
144 static constexpr size_t MAX_SIZE = Tindex::End().base();
146 using IndexType = Tindex;
147 using BitmapStorage = size_t;
148 static constexpr size_t BITMAP_SIZE = std::numeric_limits<BitmapStorage>::digits;
172 inline Titem *
Get(
size_t index)
175 return this->data[index];
185 return index < this->first_unused && this->
Get(index) !=
nullptr;
195 bool ret = this->items <=
MAX_SIZE - n;
197 this->checked = ret ? n : 0;
207 struct PoolIterator {
208 typedef T value_type;
210 typedef T &reference;
211 typedef size_t difference_type;
212 typedef std::forward_iterator_tag iterator_category;
214 explicit PoolIterator(
size_t index) : index(index)
216 this->ValidateIndex();
219 bool operator==(
const PoolIterator &other)
const {
return this->index == other.index; }
220 T * operator*()
const {
return T::Get(this->index); }
221 PoolIterator & operator++() { this->index++; this->ValidateIndex();
return *
this; }
227 while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++;
228 if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
237 struct IterateWrapper {
239 IterateWrapper(
size_t from = 0) : from(from) {}
242 bool empty() {
return this->begin() == this->end(); }
249 template <
class T,
class F>
250 struct PoolIteratorFiltered {
251 typedef T value_type;
253 typedef T &reference;
254 typedef size_t difference_type;
255 typedef std::forward_iterator_tag iterator_category;
257 explicit PoolIteratorFiltered(
size_t index, F filter) : index(index), filter(filter)
259 this->ValidateIndex();
262 bool operator==(
const PoolIteratorFiltered &other)
const {
return this->index == other.index; }
263 T * operator*()
const {
return T::Get(this->index); }
264 PoolIteratorFiltered & operator++() { this->index++; this->ValidateIndex();
return *
this; }
271 while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++;
272 if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
280 template <
class T,
class F>
281 struct IterateWrapperFiltered {
284 IterateWrapperFiltered(
size_t from, F filter) : from(from), filter(filter) {}
287 bool empty() {
return this->begin() == this->end(); }
294 template <struct Pool<Titem, Tindex, Tgrowth_step, Tpool_type, Tcache> *Tpool>
305 typedef struct Pool<Titem, Tindex, Tgrowth_step, Tpool_type, Tcache>
Pool;
308 inline void *
operator new(size_t) =
delete;
316 inline void operator delete(
void *p,
size_t size)
318 if (p ==
nullptr)
return;
319 Titem *pn =
static_cast<Titem *
>(p);
320 assert(pn == Tpool->Get(Pool::GetRawIndex(pn->index)));
321 Tpool->FreeItem(size, Pool::GetRawIndex(pn->index));
325 inline void *
operator new(
size_t size, Tindex
index) =
delete;
328 inline void *
operator new(size_t,
void *ptr) =
delete;
336 template <
typename T = Titem,
typename... Targs>
337 requires std::is_base_of_v<Titem, T>
340 auto [
data,
index] = Tpool->GetNew(
sizeof(
T));
341 return ::new (
data)
T(
index, std::forward<Targs&&>(args)...);
350 template <
typename T = Titem,
typename... Targs>
351 requires std::is_base_of_v<Titem, T>
354 auto [
data, _] = Tpool->GetNew(
sizeof(
T),
index.base());
355 return ::new (
data)
T(
index, std::forward<Targs&&>(args)...);
367 return Tpool->CanAllocate(n);
376 return Tpool->cleaning;
386 return Tpool->IsValidID(GetRawIndex(
index));
397 return Tpool->Get(GetRawIndex(
index));
408 return GetRawIndex(
index) < Tpool->first_unused ? Tpool->Get(GetRawIndex(
index)) :
nullptr;
418 return Tpool->first_unused;
461 std::allocator<uint8_t> allocator{};
467 AllocationResult<Tindex>
GetNew(
size_t size);
468 AllocationResult<Tindex>
GetNew(
size_t size,
size_t index);
472 static constexpr size_t GetRawIndex(
size_t index) {
return index; }
473 template <
typename T>
requires std::is_base_of_v<PoolIDBase, T>
474 static constexpr size_t GetRawIndex(
const T &index) {
return index.base(); }
@ Invalid
Invalid town production effect.
@ Begin
Used for iteration.
#define T
Climate temperate.
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)
Subtract 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.
EnumBitSet< PoolType, uint8_t > PoolTypes
Bitset of PoolType elements.
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()
Ensure the destructor of the sub classes are called as well.
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.
TBaseType value
The bare storage.
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.