2#include "gaia/config/config.h"
6#include "gaia/mem/raw_data_holder.h"
12 struct AllocationInfo {
19 void (*dtor)(
void*, uint32_t);
26 GAIA_MSVC_WARNING_PUSH()
27 GAIA_MSVC_WARNING_DISABLE(4324)
32 template <uint32_t CapacityInBytes = 1024>
34 using alloc_info = detail::AllocationInfo;
37 detail::raw_data_holder<CapacityInBytes, 16> m_buffer;
41 uint32_t m_posPrev = 0;
43 uint32_t m_allocs = 0;
48 const auto bufferMemAddr = (uintptr_t)((uint8_t*)m_buffer);
49 m_posPrev = m_pos = padding<alignof(alloc_info)>(bufferMemAddr);
68 GAIA_NODISCARD T*
alloc(uint32_t cnt) {
69 constexpr auto sizeT = (uint32_t)
sizeof(T);
70 const auto addrBuff = (uintptr_t)((uint8_t*)m_buffer);
71 const auto addrAllocInfo = align<alignof(alloc_info)>(addrBuff + m_pos);
72 const auto addrAllocData = align<alignof(T)>(addrAllocInfo +
sizeof(alloc_info));
73 const auto off = (uint32_t)(addrAllocData - addrAllocInfo);
76 const bool isFull = (uint32_t)(addrAllocData - addrBuff) + sizeT * cnt >= CapacityInBytes;
77 if GAIA_UNLIKELY (isFull) {
78 GAIA_ASSERT(!isFull &&
"Allocation space exceeded on StackAllocator");
83 auto* pInfo = (alloc_info*)addrAllocInfo;
84 pInfo->prev = m_posPrev;
87 pInfo->dtor = [](
void* ptr, uint32_t cnt) {
88 core::call_dtor_n((T*)ptr, cnt);
92 auto* pData = (T*)addrAllocData;
93 core::call_ctor_raw_n(pData, cnt);
96 m_posPrev = (uint32_t)(addrAllocInfo - addrBuff);
98 m_pos = m_posPrev + pInfo->off + sizeT * cnt;
107 void free([[maybe_unused]]
void* pData, [[maybe_unused]] uint32_t cnt) {
108 GAIA_ASSERT(pData !=
nullptr);
109 GAIA_ASSERT(cnt > 0);
110 GAIA_ASSERT(m_allocs > 0);
112 const auto addrBuff = (uintptr_t)((uint8_t*)m_buffer);
115 const auto addrAllocInfo = addrBuff + m_posPrev;
116 auto* pInfo = (alloc_info*)addrAllocInfo;
117 const auto addrAllocData = addrAllocInfo + pInfo->off;
118 void* pInfoData = (
void*)addrAllocData;
119 GAIA_ASSERT(pData == pInfoData);
120 GAIA_ASSERT(pInfo->cnt == cnt);
121 pInfo->dtor(pInfoData, pInfo->cnt);
124 m_posPrev = pInfo->prev;
130 const auto addrBuff = (uintptr_t)((uint8_t*)m_buffer);
133 auto pos = m_posPrev;
134 while (m_allocs > 0) {
135 const auto addrAllocInfo = addrBuff + pos;
136 auto* pInfo = (alloc_info*)addrAllocInfo;
137 const auto addrAllocData = addrAllocInfo + pInfo->off;
138 pInfo->dtor((
void*)addrAllocData, pInfo->cnt);
144 GAIA_ASSERT(m_allocs == 0);
154 return CapacityInBytes;
158 GAIA_MSVC_WARNING_POP()
Stack allocator capable of instantiating any default-constructible object on stack....
Definition stack_allocator.h:33
void reset()
Frees all allocated objects from the buffer.
Definition stack_allocator.h:129
GAIA_NODISCARD T * alloc(uint32_t cnt)
Allocates objects inside the buffer. No default initialization is done so the object is returned in a...
Definition stack_allocator.h:68
void free(void *pData, uint32_t cnt)
Frees the last allocated object from the stack.
Definition stack_allocator.h:107
GAIA_NODISCARD constexpr uint32_t capacity()
Returns the fixed buffer capacity.
Definition stack_allocator.h:153