diff options
Diffstat (limited to 'src/common')
| -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; +}; +  | 
