#include <stack>

template<typename Tp>
class FixedAllocator {
    PageAllocator* page_allocator_;
    std::uint64_t page_size;
    std::stack <Tp*> pools;

 public:
    explicit FixedAllocator(std::uint64_t page_size) {
        this->page_allocator_ = new PageAllocator(sizeof(Tp) *page_size);
        this->page_size = page_size;
    }
    Tp* Allocate() {
        if (pools.empty()) {
            Tp* temp = \
            reinterpret_cast<Tp *>(this->page_allocator_->Allocate());
            for (size_t i = 0; i < this->page_size; i++) {
                this->pools.push(&temp[i]);
            }
            delete temp;
            auto res = this->pools.top();
            this->pools.pop();
            return res;
        } else {
            auto res = this->pools.top();
            this->pools.pop();
            return res;
        }
    }
    void Deallocate(Tp* p) {
        delete p;
        this->pools.push(p);
    }
    const PageAllocator& InnerAllocator() const noexcept {
        return *page_allocator_;
    }
    ~FixedAllocator() {
        delete page_allocator_;
        while (!pools.empty()) {
        delete pools.top();
        pools.pop();
        }
    }
};