8 #include "Core/Macro/Macro.h" 36 static constexpr
size_t LastBit = 1ULL << (8 *
sizeof(size_t) - 1);
45 return !(
next & LastBit);
53 Block* storage =
nullptr;
57 size_t free = InvalidOffset;
66 constexpr
static size_t InvalidOffset = std::numeric_limits<size_t>::max() - Block::LastBit;
68 using DataPointer = uint8_t*;
82 this->
Init(data, bytes);
92 MX_ASSERT(data !=
nullptr);
93 MX_ASSERT(bytes >=
sizeof(
Block));
95 this->storage =
reinterpret_cast<Block*
>(
data);
97 this->count = bytes /
sizeof(
Block);
99 Block* last = this->storage + count - 1;
101 for (
Block* begin = this->storage; begin != last; begin++, offset++)
103 begin->
next = offset;
105 last->
next = InvalidOffset;
114 void Transfer(DataPointer newData,
size_t newBytes)
116 if (this->storage ==
nullptr)
118 this->
Init(newData, newBytes);
122 size_t newCount = newBytes /
sizeof(
Block);
123 MX_ASSERT(newData !=
nullptr);
124 MX_ASSERT(this->count <= newCount);
126 std::memcpy(newData, this->storage, this->count *
sizeof(
Block));
139 this->storage = (
Block*)newData;
140 Block* last = this->storage + newCount - 1;
141 size_t offset = this->count + 1;
142 for(
Block* begin = this->storage + this->count; begin != last; begin++, offset++)
144 begin->
next = offset;
146 last->
next = this->free;
147 this->free = this->count;
148 this->count = newCount;
156 constexpr
size_t marked = InvalidOffset - 1;
157 size_t offset = this->free;
158 while (offset != InvalidOffset)
160 Block* block = this->storage + offset;
161 offset = block->
next;
162 block->
next = marked;
164 for (
Block* block = this->storage; block != this->storage + this->count; block++)
166 if (block->next != marked)
179 return this->storage;
187 template<
typename... Args>
188 [[nodiscard]] T*
Alloc(Args&&... args)
190 MX_ASSERT(this->free != InvalidOffset);
191 Block* res = this->storage + this->free;
193 this->free = res->
next;
195 return new (ptr) T(std::forward<Args>(args)...);
205 Block* block =
reinterpret_cast<Block*
>(object);
206 MX_ASSERT(block >= this->storage && block < this->storage + this->count);
207 block->
next = this->free;
208 this->free =
static_cast<size_t>(block - this->storage);
216 template<
typename... Args>
219 auto deleter = [
this](T* ptr) { this->
Free(ptr); };
220 using SmartPtr = std::unique_ptr<T, decltype(deleter)>;
221 return SmartPtr(this->
Alloc(std::forward<Args>(args)...), std::move(deleter));
228 void Dump(std::ostream& out)
const 230 for (
size_t i = 0; i < this->count *
sizeof(
Block); i++)
232 out << std::hex << (int)((DataPointer)this->storage)[i];
234 out << std::dec <<
"\n --- dumped " << this->count *
sizeof(
Block) <<
" bytes --- \n";
void Transfer(DataPointer newData, size_t newBytes)
Definition: PoolAllocator.h:114
~PoolAllocator()
Definition: PoolAllocator.h:154
T data
Definition: PoolAllocator.h:30
void Dump(std::ostream &out) const
Definition: PoolAllocator.h:228
DataPointer GetBase()
Definition: PoolAllocator.h:177
Definition: PoolAllocator.h:25
Definition: PoolAllocator.h:19
PoolAllocator()
Definition: PoolAllocator.h:73
PoolAllocator(DataPointer data, size_t bytes)
Definition: PoolAllocator.h:80
T * Alloc(Args &&... args)
Definition: PoolAllocator.h:188
size_t next
Definition: PoolAllocator.h:34
void Init(DataPointer data, size_t bytes)
Definition: PoolAllocator.h:90
auto StackAlloc(Args &&... args)
Definition: PoolAllocator.h:217
Definition: Application.cpp:49
void Free(T *object)
Definition: PoolAllocator.h:202