#pragma once
#include <vector>
template<typename Tp>
class FixedAllocator {
 public:
    explicit FixedAllocator(std::uint64_t page_size) :
    page_allocator(page_size),
        page_size(page_size) {
        memory = page_allocator.Allocate();
        for (size_t i = 0; i < page_size; i++)
            free_memory.push_back(static_cast<Tp*>(memory));
    }

    Tp* Allocate() {
        if (free_memory.empty()) {
            memory = page_allocator.Allocate();

            for (size_t i = 0; i < page_size; i++)
                free_memory.push_back(static_cast<Tp*>(memory));
        }

        Tp* tmp = free_memory.back();
        free_memory.pop_back();
        return tmp;
    }

    void Deallocate(Tp* p) {
        free_memory.push_back(p);
    }

    const PageAllocator& InnerAllocator() const noexcept {
        return page_allocator;
    }

 protected:
    PageAllocator page_allocator;
    std::uint64_t page_size;
    std::vector<Tp*> free_memory;
    void* memory;
};