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, size_t Tmax_size, PoolType Tpool_type, bool Tcache, bool Tzero> \
26 type Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tpool_type, Tcache, Tzero>
55 assert(index >= this->size);
56 assert(index < Tmax_size);
58 size_t new_size = std::min(Tmax_size,
Align(index + 1, Tgrowth_step));
60 this->data =
ReallocT(this->data, new_size);
61 MemSetT(this->data + this->size, 0, new_size - this->size);
63 this->size = new_size;
72 size_t index = this->first_free;
74 for (; index < this->first_unused; index++) {
75 if (this->data[index] ==
nullptr)
return index;
78 if (index < this->size) {
82 assert(index == this->size);
83 assert(this->first_unused == this->size);
85 if (index < Tmax_size) {
86 this->ResizeFor(index);
90 assert(this->items == Tmax_size);
104 assert(this->data[index] ==
nullptr);
106 this->first_unused = std::max(this->first_unused, index + 1);
110 if (Tcache && this->alloc_cache !=
nullptr) {
111 assert(
sizeof(Titem) == size);
112 item = (Titem *)this->alloc_cache;
113 this->alloc_cache = this->alloc_cache->next;
117 memset((
void *)item, 0,
sizeof(Titem));
120 item = (Titem *)CallocT<byte>(size);
122 item = (Titem *)MallocT<byte>(size);
124 this->data[index] = item;
125 item->index = (Tindex)(uint)index;
137 size_t index = this->FindFirstFree();
140 assert(this->checked != 0);
143 if (index == NO_FREE_ITEM) {
144 FatalError(
"{}: no more free items", this->name);
147 this->first_free = index + 1;
148 return this->AllocateItem(size, index);
160 if (index >= Tmax_size) {
161 SlErrorCorruptFmt(
"{} index {} out of range ({})", this->name, index, Tmax_size);
164 if (index >= this->size) this->ResizeFor(index);
166 if (this->data[index] !=
nullptr) {
167 SlErrorCorruptFmt(
"{} index {} already in use", this->name, index);
170 return this->AllocateItem(size, index);
181 assert(index < this->size);
182 assert(this->data[index] !=
nullptr);
184 AllocCache *ac = (AllocCache *)this->data[index];
185 ac->next = this->alloc_cache;
186 this->alloc_cache = ac;
188 free(this->data[index]);
190 this->data[index] =
nullptr;
191 this->first_free = std::min(this->first_free, index);
193 if (!this->cleaning) Titem::PostDestructor(index);
199 this->cleaning =
true;
200 for (
size_t i = 0; i < this->first_unused; i++) {
203 assert(this->items == 0);
205 this->first_unused = this->first_free = this->size = 0;
206 this->data =
nullptr;
207 this->cleaning =
false;
210 while (this->alloc_cache !=
nullptr) {
211 AllocCache *ac = this->alloc_cache;
212 this->alloc_cache = ac->next;
218 #undef DEFINE_POOL_METHOD
225 #define INSTANTIATE_POOL_METHODS(name) \
226 template void * name ## Pool::GetNew(size_t size); \
227 template void * name ## Pool::GetNew(size_t size, size_t index); \
228 template void name ## Pool::FreeItem(size_t index); \
229 template void name ## Pool::CleanPool();