#include <stack>

using std::uint64_t;
using std::stack;
template<typename Tp>

class FixedAllocator {
    const uint64_t page_size_;
    PageAllocator page_allocator_;
    stack<Tp*> free_chunks;

public:
    explicit FixedAllocator(uint64_t page_size)
        : page_size_(page_size),
        page_allocator_(page_size * sizeof(Tp)) {
        Tp* chunks = static_cast<Tp*>(page_allocator_.Allocate());
        uint64_t i = 0;
        while (i < page_size_) {
            free_chunks.push(chunks + i);
            i++;
        }
    }
    void Deallocate(Tp* p) { free_chunks.push(p); }
    const PageAllocator& InnerAllocator() const noexcept {
        return page_allocator_;
    }
    Tp* Allocate() {
        if (free_chunks.empty()) {
            Tp* chunks = static_cast<Tp*>(page_allocator_.Allocate());
            for (uint64_t i = 0; i < page_size_; i++)
                free_chunks.push(chunks + i);
        }
        Tp* chunk = free_chunks.top();
        free_chunks.pop();
        return chunk;
    }
};