Go to the documentation of this file.
35 #include "../../Primitives/interface/BasicTypes.h"
36 #include "../../Primitives/interface/MemoryAllocator.h"
37 #include "../../Platforms/Basic/interface/DebugUtilities.hpp"
55 m_pAllocator{&Allocator}
60 m_pDataStart {Other.m_pDataStart },
61 m_pCurrPtr {Other.m_pCurrPtr },
62 m_ReservedSize {Other.m_ReservedSize },
63 m_CurrAlignment{Other.m_CurrAlignment},
64 m_pAllocator {Other.m_pAllocator }
66 , m_DbgCurrAllocation{Other.m_DbgCurrAllocation}
67 , m_DbgAllocations{std::move(Other.m_DbgAllocations)}
81 if (m_pDataStart !=
nullptr && m_pAllocator !=
nullptr)
83 m_pAllocator->
Free(m_pDataStart);
90 void* Ptr = m_pDataStart;
97 m_pAllocator =
nullptr;
106 void AddSpace(
size_t size,
size_t alignment) noexcept
108 VERIFY(m_pDataStart ==
nullptr,
"Memory has already been allocated");
114 if (m_CurrAlignment == 0)
116 VERIFY(m_ReservedSize == 0,
"This is expected to be a very first time the space is added");
117 m_CurrAlignment =
sizeof(
void*);
120 if (alignment > m_CurrAlignment)
123 m_ReservedSize += alignment - m_CurrAlignment;
125 m_CurrAlignment = alignment;
127 size =
AlignUp(size, alignment);
128 m_ReservedSize += size;
131 m_DbgAllocations.emplace_back(size, alignment, m_ReservedSize);
135 template <
typename T>
138 AddSpace(
sizeof(T) * count,
alignof(T));
144 AddSpace<Char>(strlen(str) + 1);
150 AddSpace<String::value_type>(str.length() + 1);
155 VERIFY(m_pDataStart ==
nullptr,
"Memory has already been allocated");
156 VERIFY(m_ReservedSize == 0,
"Space has been added to the allocator and will be overriden");
157 m_ReservedSize = size;
163 VERIFY(m_pDataStart ==
nullptr,
"Memory has already been allocated");
164 VERIFY(m_pAllocator !=
nullptr,
"Allocator must not be null");
166 m_ReservedSize =
AlignUp(m_ReservedSize,
sizeof(
void*));
167 if (m_ReservedSize > 0)
169 m_pDataStart =
reinterpret_cast<uint8_t*
>(m_pAllocator->
Allocate(m_ReservedSize,
"Raw memory for linear allocator", __FILE__, __LINE__));
170 VERIFY(m_pDataStart ==
AlignUp(m_pDataStart,
sizeof(
void*)),
"Memory pointer must be at least sizeof(void*)-aligned");
172 m_pCurrPtr = m_pDataStart;
174 m_CurrAlignment =
sizeof(
void*);
177 NODISCARD
void*
Allocate(
size_t size,
size_t alignment)
179 VERIFY(size == 0 || m_pDataStart !=
nullptr,
"Memory has not been allocated");
185 size =
AlignUp(size, alignment);
188 VERIFY(m_DbgCurrAllocation < m_DbgAllocations.size(),
"Allocation number exceed the number of allocations that were originally reserved.");
189 const auto& CurrAllocation = m_DbgAllocations[m_DbgCurrAllocation++];
190 VERIFY(CurrAllocation.size == size,
"Allocation size (", size,
") does not match the initially requested size (", CurrAllocation.size,
")");
191 VERIFY(CurrAllocation.alignment == alignment,
"Allocation alignment (", alignment,
") does not match the initially requested alignment (", CurrAllocation.alignment,
")");
194 VERIFY(
AlignUp(m_pCurrPtr, m_CurrAlignment) == m_pCurrPtr,
"Current pointer is not aligned as expected");
195 m_pCurrPtr =
AlignUp(m_pCurrPtr, alignment);
196 m_CurrAlignment = alignment;
198 VERIFY(m_pCurrPtr + size <= m_pDataStart + CurrAllocation.reserved_size,
199 "Allocation size exceeds the initially reserved space. This is likely a bug.");
201 auto* ptr = m_pCurrPtr;
204 VERIFY(m_pCurrPtr <= m_pDataStart + m_ReservedSize,
"Allocation size exceeds the reserved space");
209 template <
typename T>
212 return reinterpret_cast<T*
>(
Allocate(
sizeof(T) * count,
alignof(T)));
215 template <
typename T,
typename... Args>
218 T* Ptr = Allocate<T>();
219 new (Ptr) T{std::forward<Args>(args)...};
223 template <
typename T,
typename... Args>
226 T* Ptr = Allocate<T>(count);
227 for (
size_t i = 0; i < count; ++i)
229 new (Ptr + i) T{args...};
234 template <
typename T>
235 NODISCARD T*
Copy(
const T& Src)
237 return Construct<T>(Src);
240 template <
typename T>
243 T* Dst = Allocate<T>(count);
244 for (
size_t i = 0; i < count; ++i)
246 new (Dst + i) T{Src[i]};
256 auto* Ptr =
reinterpret_cast<Char*
>(
Allocate(strlen(Str) + 1, 1));
259 const auto* pDataEnd =
reinterpret_cast<Char*
>(m_pDataStart) + m_ReservedSize;
260 while (*Str != 0 && Dst < pDataEnd)
267 UNEXPECTED(
"Not enough space reserved for the string");
280 VERIFY(m_pDataStart !=
nullptr,
"Memory has not been allocated");
281 return static_cast<size_t>(m_pCurrPtr - m_pDataStart);
286 return m_ReservedSize;
292 m_pDataStart =
nullptr;
293 m_pCurrPtr =
nullptr;
296 m_pAllocator =
nullptr;
299 m_DbgCurrAllocation = 0;
300 m_DbgAllocations.clear();
304 uint8_t* m_pDataStart =
nullptr;
305 uint8_t* m_pCurrPtr =
nullptr;
306 size_t m_ReservedSize = 0;
307 size_t m_CurrAlignment = 0;
308 IMemoryAllocator* m_pAllocator =
nullptr;
311 size_t m_DbgCurrAllocation = 0;
312 struct DbgAllocationInfo
315 const size_t alignment;
316 const size_t reserved_size;
318 DbgAllocationInfo(
size_t _size,
size_t _alignment,
size_t _reserved_size) :
320 alignment{_alignment},
321 reserved_size{_reserved_size}
325 std::vector<DbgAllocationInfo> m_DbgAllocations;
Implementation of a linear allocator on a fixed-size memory page.
Definition: FixedLinearAllocator.hpp:45
NODISCARD void * Allocate(size_t size, size_t alignment)
Definition: FixedLinearAllocator.hpp:177
NODISCARD T * Allocate(size_t count=1)
Definition: FixedLinearAllocator.hpp:210
NODISCARD size_t GetCurrentSize() const
Definition: FixedLinearAllocator.hpp:278
char Char
Definition: BasicTypes.h:64
FixedLinearAllocator(IMemoryAllocator &Allocator) noexcept
Definition: FixedLinearAllocator.hpp:54
~FixedLinearAllocator()
Definition: FixedLinearAllocator.hpp:74
#define UNEXPECTED(...)
Definition: DebugUtilities.hpp:77
NODISCARD void * ReleaseOwnership() noexcept
Definition: FixedLinearAllocator.hpp:95
FixedLinearAllocator(FixedLinearAllocator &&Other) noexcept
Definition: FixedLinearAllocator.hpp:58
NODISCARD T * ConstructArray(size_t count, const Args &... args)
Definition: FixedLinearAllocator.hpp:224
NODISCARD size_t GetReservedSize() const
Definition: FixedLinearAllocator.hpp:284
NODISCARD Char * CopyString(const char *Str)
Definition: FixedLinearAllocator.hpp:251
FixedLinearAllocator(const FixedLinearAllocator &)=delete
void Reserve()
Definition: FixedLinearAllocator.hpp:161
void AddSpace(size_t size, size_t alignment) noexcept
Definition: FixedLinearAllocator.hpp:106
NODISCARD void * Release()
Definition: FixedLinearAllocator.hpp:88
NODISCARD Char * CopyString(const std::string &Str)
Definition: FixedLinearAllocator.hpp:273
void AddSpaceForString(const Char *str) noexcept
Definition: FixedLinearAllocator.hpp:141
NODISCARD T * Construct(Args &&... args)
Definition: FixedLinearAllocator.hpp:216
bool IsPowerOfTwo(T val)
Definition: Align.hpp:41
NODISCARD T * CopyArray(const T *Src, size_t count)
Definition: FixedLinearAllocator.hpp:241
Base interface for a raw memory allocator.
Definition: MemoryAllocator.h:41
void Free()
Definition: FixedLinearAllocator.hpp:79
NODISCARD void * GetDataPtr() const noexcept
Definition: FixedLinearAllocator.hpp:101
std::basic_string< Char > String
String variable.
Definition: BasicTypes.h:66
#define VERIFY_EXPR(...)
Definition: DebugUtilities.hpp:79
void AddSpaceForString(const String &str) noexcept
Definition: FixedLinearAllocator.hpp:147
#define VERIFY(...)
Definition: DebugUtilities.hpp:76
NODISCARD T * Copy(const T &Src)
Definition: FixedLinearAllocator.hpp:235
T2 ::type AlignUp(T1 val, T2 alignment)
Definition: Align.hpp:47
virtual void Free(void *Ptr)=0
Releases memory.
virtual void * Allocate(size_t Size, const Char *dbgDescription, const char *dbgFileName, const Int32 dbgLineNumber)=0
Allocates block of memory.
void AddSpace(size_t count=1) noexcept
Definition: FixedLinearAllocator.hpp:136
void Reserve(size_t size)
Definition: FixedLinearAllocator.hpp:153
FixedLinearAllocator & operator=(const FixedLinearAllocator &)=delete
The library uses Direct3D-style math:
Definition: AdvancedMath.hpp:37