20 template <
typename... ARGS>
21 T* create(ARGS&&... args)
23 if (mPointers.empty())
25 auto& new_block = mBlocks.emplace_back(std::make_unique<mem_proxy[]>(BLOCK_SIZE));
26 for (
size_t i = 0; i < BLOCK_SIZE; ++i)
27 mPointers.push_back(&new_block[i]);
29 auto result = std::construct_at(
reinterpret_cast<T*
>(mPointers.back()), std::forward<ARGS>(args)...);
37 mPointers.push_back(std::launder(
reinterpret_cast<mem_proxy*
>(ptr)));
46 size_t capacity()
const noexcept {
return mBlocks.size() * BLOCK_SIZE; }
47 size_t capacity_in_bytes()
const noexcept {
return capacity() *
sizeof(mem_proxy); }
48 size_t free_elements()
const noexcept {
return mPointers.size(); }
49 size_t allocated_elements()
const noexcept {
return capacity() - free_elements(); }
54 struct alignas(alignof(T)) mem_proxy {
unsigned char mem[
sizeof(T)]; };
55 std::vector<mem_proxy*> mPointers;
56 std::vector<std::unique_ptr<mem_proxy[]>> mBlocks;