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;
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);
137template <
class Titem,
typename Tindex,
size_t Tgrowth_step, PoolType Tpool_type = PoolType::Normal,
bool Tcache = false>
138requires std::is_base_of_v<PoolIDBase, Tindex>
141 static constexpr size_t MAX_SIZE = Tindex::End().base();
143 using IndexType = Tindex;
144 using BitmapStorage = size_t;
145 static constexpr size_t BITMAP_SIZE = std::numeric_limits<BitmapStorage>::digits;
169 inline Titem *
Get(
size_t index)
172 return this->data[index];
182 return index < this->first_unused && this->
Get(index) !=
nullptr;
192 bool ret = this->items <=
MAX_SIZE - n;
194 this->checked = ret ? n : 0;
204 struct PoolIterator {
205 typedef T value_type;
207 typedef T &reference;
208 typedef size_t difference_type;
209 typedef std::forward_iterator_tag iterator_category;
211 explicit PoolIterator(
size_t index) : index(index)
213 this->ValidateIndex();
216 bool operator==(
const PoolIterator &other)
const {
return this->index == other.index; }
217 T * operator*()
const {
return T::Get(this->index); }
218 PoolIterator & operator++() { this->index++; this->ValidateIndex();
return *
this; }
224 while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++;
225 if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
234 struct IterateWrapper {
236 IterateWrapper(
size_t from = 0) : from(from) {}
239 bool empty() {
return this->begin() == this->end(); }
246 template <
class T,
class F>
247 struct PoolIteratorFiltered {
248 typedef T value_type;
250 typedef T &reference;
251 typedef size_t difference_type;
252 typedef std::forward_iterator_tag iterator_category;
254 explicit PoolIteratorFiltered(
size_t index, F filter) : index(index), filter(filter)
256 this->ValidateIndex();
259 bool operator==(
const PoolIteratorFiltered &other)
const {
return this->index == other.index; }
260 T * operator*()
const {
return T::Get(this->index); }
261 PoolIteratorFiltered & operator++() { this->index++; this->ValidateIndex();
return *
this; }
268 while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++;
269 if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
277 template <
class T,
class F>
278 struct IterateWrapperFiltered {
281 IterateWrapperFiltered(
size_t from, F filter) : from(from), filter(filter) {}
284 bool empty() {
return this->begin() == this->end(); }
291 template <struct Pool<Titem, Tindex, Tgrowth_step, Tpool_type, Tcache> *Tpool>
302 typedef struct Pool<Titem, Tindex, Tgrowth_step, Tpool_type, Tcache>
Pool;
305 inline void *
operator new(size_t) =
delete;
313 inline void operator delete(
void *p,
size_t size)
315 if (p ==
nullptr)
return;
316 Titem *pn =
static_cast<Titem *
>(p);
317 assert(pn == Tpool->Get(Pool::GetRawIndex(pn->index)));
318 Tpool->FreeItem(size, Pool::GetRawIndex(pn->index));
322 inline void *
operator new(
size_t size, Tindex
index) =
delete;
325 inline void *
operator new(size_t,
void *ptr) =
delete;
333 template <
typename T = Titem,
typename... Targs>
334 requires std::is_base_of_v<Titem, T>
337 auto [
data,
index] = Tpool->GetNew(
sizeof(
T));
338 return ::new (
data)
T(
index, std::forward<Targs&&>(args)...);
347 template <
typename T = Titem,
typename... Targs>
348 requires std::is_base_of_v<Titem, T>
351 auto [
data, _] = Tpool->GetNew(
sizeof(
T),
index.base());
352 return ::new (
data)
T(
index, std::forward<Targs&&>(args)...);
364 return Tpool->CanAllocate(n);
373 return Tpool->cleaning;
383 return Tpool->IsValidID(GetRawIndex(
index));
394 return Tpool->Get(GetRawIndex(
index));
405 return GetRawIndex(
index) < Tpool->first_unused ? Tpool->Get(GetRawIndex(
index)) :
nullptr;
415 return Tpool->first_unused;
458 std::allocator<uint8_t> allocator{};
464 AllocationResult<Tindex>
GetNew(
size_t size);
465 AllocationResult<Tindex>
GetNew(
size_t size,
size_t index);
469 static constexpr size_t GetRawIndex(
size_t index) {
return index; }
470 template <
typename T>
requires std::is_base_of_v<PoolIDBase, T>
471 static constexpr size_t GetRawIndex(
const T &index) {
return index.base(); }
@ Begin
The lowest valid value.
@ Invalid
Invalid base price.
#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.
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.