template<typename Tp>
class FixedAllocator {
    PageAllocator page_allocator_;
    std::uint64_t page_size_ = 0;
    std::uint64_t curPos = 0;
    void* pageMem = nullptr;
    std::vector<void*> freeMem;

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