#pragma once
#include <vector>

template<typename Tp>
class FixedAllocator {
    PageAllocator page_allocator_;
    const std::uint64_t page_size_;
    std::uint64_t count_ = 0;
    std::vector<Tp*> pages_;

 public:
    explicit FixedAllocator(std::uint64_t page_size) :
        page_allocator_(PageAllocator(page_size * sizeof(Tp))),
        page_size_(page_size) {}
    Tp* Allocate() {
        if (count_ == 0) {
            Tp* tmp = reinterpret_cast<Tp*>(page_allocator_.Allocate());
            for (std::uint64_t i = 0; i < page_size_; i++) {
                pages_.push_back(tmp);
                tmp++;
            }
            count_ = page_size_;
        }
        Tp* p = pages_[--count_];
        pages_.pop_back();
        return p;
    }
    void Deallocate(Tp* p) {
        pages_.push_back(p);
        count_++;
    }
    const PageAllocator& InnerAllocator() const noexcept {
        return page_allocator_;
    }
};