#include <cstdint>
#include <vector>

template<typename Tp>
class FixedAllocator {
    PageAllocator page_allocator_;
    std::uint64_t page_size_ = 0;
    std::uint64_t curP = 0;
    void* pageM = nullptr;
    std::vector<void*> freeM;

 public:
    explicit FixedAllocator(std::uint64_t page_size) :
    page_allocator_(page_size), page_size_(page_size),
    curP(page_size) {}
    Tp* Allocate() {
        Tp* p = nullptr;
        if (freeM.size() > 0) {
            p = reinterpret_cast<Tp*>(freeM[freeM.size() - 1]);
            freeM.pop_back();
            return p;
        }
        if (curP >= page_size_) {
            curP = 0;
            pageM = page_allocator_.Allocate();
        }
        p = reinterpret_cast<Tp*>(reinterpret_cast<char*>(pageM) + curP);
        ++curP;
        return p;
    }
    void Deallocate(Tp* p) {
        freeM.push_back(p);
    }
    const PageAllocator& InnerAllocator() const noexcept {
        return page_allocator_;
    }
};