#pragma once
#include <vector>

template<typename Tp>
class FixedAllocator {
 private:
    PageAllocator page_allocator_;
    Tp *page;
    std::vector<Tp *> pool;
    std::uint64_t page_size_;
    size_t pos{};

 public:
    explicit FixedAllocator(std::uint64_t page_size) :
            page_allocator_(page_size),
            page_size_(page_size) {
        page = (Tp *)page_allocator_.Allocate();
    }

    Tp *Allocate() {
        if (pool.empty()) {
            if (page_size_ <= pos) {
                pos = 0;
                page = (Tp *)page_allocator_.Allocate();
            }
            pos++;
            return page + pos - 1;
        }
        Tp* r = pool[pool.size() - 1];
        pool.pop_back();
        return r;

    }
    void Deallocate(Tp *p) {
        pool.emplace_back(p);
    }
    [[nodiscard]] const PageAllocator &InnerAllocator() const noexcept {
        return page_allocator_;
    }
};