#pragma once

#include "iostream"
#include "vector"

template<typename Tp>
class FixedAllocator {
 public:
    explicit FixedAllocator(std::uint64_t page_size)
            : page_allocator(page_size)
            , page_size(page_size)
            {}

    Tp *Allocate() {
        if (memory.empty()) {
            Tp *t = static_cast<Tp *>(page_allocator.Allocate());
            for (size_t i = 0; i < page_size; ++i) {
                t += i;
                memory.push_back(t);
            }
        }
        Tp *result = memory.back();
        memory.erase(memory.end() - 1);
        return result;
    }

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

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

 private:
    PageAllocator page_allocator;
    size_t page_size;
    std::vector<Tp *> memory;
};