#pragma once

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

public:
    explicit FixedAllocator(std::uint64_t page_size) :
        block_size_(page_size),
        page_allocator_(PageAllocator(page_size * sizeof(Tp))) {}
    Tp* Allocate() {
        if (count_ == 0) {
            Tp* tmp = (Tp*)page_allocator_.Allocate();
            for (std::uint64_t i = 0; i < block_size_; i++) {
                pages_.push_back(tmp);
                tmp++;
            }
            count_ = block_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_;
    }
};