#ifndef MANDEL_ARENA_H #define MANDEL_ARENA_H #include #include #include #include namespace mnd { namespace util { template class Arena { struct Chunk { char data[sizeof(T) * chunkSize]; int used = 0; bool full(void) const { return used == chunkSize; } template T* allocate(Args&&... args) { return new(reinterpret_cast(&data[(used++) * sizeof(T)])) T(std::forward(args)...); } ~Chunk(void) { for (int i = used - 1; i >= 0; i--) { reinterpret_cast(&data[i * sizeof(T)])->~T(); } } }; std::vector> chunks; public: Arena(void) = default; Arena(const Arena&) = delete; Arena(Arena&&) = default; ~Arena(void) { for (auto it = chunks.rbegin(); it != chunks.rend(); ++it) { *it = nullptr; } } Arena& operator=(const Arena&) = delete; Arena& operator=(Arena&&) = default; Chunk& lastChunk(void) { return *chunks[chunks.size() - 1]; } template T* allocate(Args&&... args) { if (chunks.empty() || lastChunk().full()) { chunks.push_back(std::make_unique()); } return lastChunk().allocate(std::forward(args)...); } }; } } #endif // MANDEL_ARENA_H