diff options
Diffstat (limited to 'src/common/Arena.hpp')
| -rw-r--r-- | src/common/Arena.hpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/common/Arena.hpp b/src/common/Arena.hpp new file mode 100644 index 0000000..b5e1eb7 --- /dev/null +++ b/src/common/Arena.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include <cstddef> +#include <cstdint> +#include <cassert> + +#include <vector> + + +class Arena { +public: + Arena(size_t size) : buffer(size) + { + } + + template<typename T> + size_t + Align() const + { + size_t alignment = alignof(T); + return (offset + alignment - 1) & ~(alignment - 1); + } + + template<typename T, typename... Args> + T& + Allocate(Args&&... args) + { + offset = Align<T>(); + assert(offset + sizeof(T) <= buffer.size() && "Arena out of memory"); + + T* ptr = new (&buffer[offset]) T(std::forward<Args>(args)...); + objects.emplace_back(ptr, [](void* p) { static_cast<T*>(p)->~T(); }); + + offset += sizeof(T); + return *ptr; + } + + void + Reset() + { + for (auto& [ptr, dtor] : objects) { + dtor(ptr); + } + objects.clear(); + offset = 0; + } + + + size_t offset = 0; + std::vector<uint8_t> buffer; + std::vector<std::pair<void*, void (*)(void*)>> objects; +}; + |
