16#include "../error_func.h"
18#include "../saveload/saveload_error.hpp"
24#define DEFINE_POOL_METHOD(type) \
25 template <class Titem, typename Tindex, size_t Tgrowth_step, PoolType Tpool_type, bool Tcache> \
26 requires std::is_base_of_v<PoolIDBase, Tindex> \
27 type Pool<Titem, Tindex, Tgrowth_step, Tpool_type, Tcache>
37 assert(index >= this->data.size());
38 assert(index < MAX_SIZE);
40 size_t old_size = this->data.size();
41 size_t new_size = std::min(MAX_SIZE,
Align(index + 1, Tgrowth_step));
43 this->data.resize(new_size);
44 this->used_bitmap.resize(
Align(new_size, BITMAP_SIZE) / BITMAP_SIZE);
45 if (old_size % BITMAP_SIZE != 0) {
47 this->used_bitmap[old_size / BITMAP_SIZE] &= ~((~static_cast<BitmapStorage>(0)) << (old_size % BITMAP_SIZE));
49 if (new_size % BITMAP_SIZE != 0) {
51 this->used_bitmap[new_size / BITMAP_SIZE] |= (~static_cast<BitmapStorage>(0)) << (new_size % BITMAP_SIZE);
61 for (
auto it = std::next(std::begin(this->used_bitmap), this->first_free / BITMAP_SIZE); it != std::end(this->used_bitmap); ++it) {
62 BitmapStorage available = ~(*it);
63 if (available == 0)
continue;
64 return std::distance(std::begin(this->used_bitmap), it) * BITMAP_SIZE +
FindFirstBit(available);
67 assert(this->first_unused == this->data.size());
69 if (this->first_unused < MAX_SIZE) {
70 this->ResizeFor(this->first_unused);
71 return this->first_unused;
74 assert(this->first_unused == MAX_SIZE);
88 assert(this->data[index] ==
nullptr);
90 this->first_unused = std::max(this->first_unused, index + 1);
94 if (Tcache && this->alloc_cache !=
nullptr) {
95 assert(
sizeof(Titem) == size);
96 item =
reinterpret_cast<Titem *
>(this->alloc_cache);
97 this->alloc_cache = this->alloc_cache->next;
99 item =
reinterpret_cast<Titem *
>(this->allocator.allocate(size));
101 this->data[index] = item;
102 SetBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
104 item->index =
static_cast<Tindex
>(
static_cast<Tindex::BaseType
>(index));
116 size_t index = this->FindFirstFree();
119 assert(this->checked != 0);
122 if (index == NO_FREE_ITEM) {
123 FatalError(
"{}: no more free items", this->name);
126 this->first_free = index + 1;
127 return this->AllocateItem(size, index);
139 if (index >= MAX_SIZE) {
140 SlErrorCorruptFmt(
"{} index {} out of range ({})", this->name, index, MAX_SIZE);
143 if (index >= this->data.size()) this->ResizeFor(index);
145 if (this->data[index] !=
nullptr) {
146 SlErrorCorruptFmt(
"{} index {} already in use", this->name, index);
149 return this->AllocateItem(size, index);
161 assert(index < this->data.size());
162 assert(this->data[index] !=
nullptr);
164 AllocCache *ac =
reinterpret_cast<AllocCache *
>(this->data[index]);
165 ac->next = this->alloc_cache;
166 this->alloc_cache = ac;
168 this->allocator.deallocate(
reinterpret_cast<uint8_t*
>(this->data[index]), size);
170 this->data[index] =
nullptr;
171 this->first_free = std::min(this->first_free, index);
173 if (!this->cleaning) {
174 ClrBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
175 Titem::PostDestructor(index);
182 this->cleaning =
true;
183 for (
size_t i = 0; i < this->first_unused; i++) {
186 assert(this->items == 0);
188 this->data.shrink_to_fit();
189 this->used_bitmap.clear();
190 this->used_bitmap.shrink_to_fit();
191 this->first_unused = this->first_free = 0;
192 this->cleaning =
false;
195 while (this->alloc_cache !=
nullptr) {
196 AllocCache *ac = this->alloc_cache;
197 this->alloc_cache = ac->next;
198 this->allocator.deallocate(
reinterpret_cast<uint8_t*
>(ac),
sizeof(Titem));
203#undef DEFINE_POOL_METHOD
210#define INSTANTIATE_POOL_METHODS(name) \
211 template void * name ## Pool::GetNew(size_t size); \
212 template void * name ## Pool::GetNew(size_t size, size_t index); \
213 template void name ## Pool::FreeItem(size_t size, size_t index); \
214 template void name ## Pool::CleanPool();
Functions related to bit mathematics.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr uint8_t FindFirstBit(T x)
Search the first set bit in a value.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
constexpr T Align(const T x, uint n)
Return the smallest multiple of n equal or greater than x.
#define DEFINE_POOL_METHOD(type)
Helper for defining the method's signature.
Definition of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle,...