#include <vector>
using std::vector;
using std::uint64_t;

template<typename Tp>
class FixedAllocator {
 private:
    PageAllocator page_allocator_;
    vector<Tp*> blockMemory;
    uint64_t page_size;
    void* mem;
    void addMemory() {
        mem = page_allocator_.Allocate();
        for (size_t i = 0; i < page_size; ++i) {
            blockMemory.push_back(static_cast<Tp*>(mem));
        }
    }
 public:
    explicit FixedAllocator(uint64_t page_size) : page_allocator_(page_size), page_size(page_size) {
        addMemory();
    }
    Tp* Allocate() {
        if (blockMemory.empty()) {
            addMemory();
        }

        Tp* result = blockMemory.back();
        blockMemory.pop_back();
        return result;
    }
    void Deallocate(Tp* p) {
        blockMemory.push_back(p);
    }
    const PageAllocator& InnerAllocator() const noexcept {
        return page_allocator_;
    }
};