// Copyright (c) Wojciech Figat. All rights reserved.
#include "Allocation.h"
///
/// Allocator that uses pages for stack-based allocs without freeing memory during it's lifetime.
///
class ArenaAllocator
{
private:
struct Page
{
void* Memory;
Page* Next;
uint32 Offset, Size;
};
int32 _pageSize;
Page* _first = nullptr;
public:
ArenaAllocator(int32 pageSizeBytes = 1024 * 1024) // 1 MB by default
: _pageSize(pageSizeBytes)
{
}
~ArenaAllocator()
{
Free();
}
// Allocates a chunk of unitialized memory.
void* Allocate(uint64 size, uint64 alignment = 1);
// Frees all memory allocations within allocator.
void Free();
// Creates a new object within the arena allocator.
template
inline T* New(Args&&...args)
{
T* ptr = (T*)Allocate(sizeof(T));
new(ptr) T(Forward(args)...);
return ptr;
}
// Invokes destructor on values in an array and clears it.
template
static void ClearDelete(Array& collection)
{
Value* ptr = collection.Get();
for (int32 i = 0; i < collection.Count(); i++)
Memory::DestructItem(ptr[i]);
collection.Clear();
}
// Invokes destructor on values in a dictionary and clears it.
template
static void ClearDelete(Dictionary& collection)
{
for (auto it = collection.Begin(); it.IsNotEnd(); ++it)
Memory::DestructItem(it->Value);
collection.Clear();
}
};