#pragma once
#include <vector>
#include <utility>

template<typename Tp>
class FixedAllocator {
    PageAllocator page_allocator_;

 public:
    explicit FixedAllocator(std::uint64_t page_size)
    : page_allocator_(page_size) {
        pg_size = page_size;
    }

    Tp* Allocate() {
        for (uint64_t i = 0; i < z.size(); i++) {
            if (z[i].second < pg_size) {
                z[i].second++;
                return z[i].first;
            }
        }
        z.emplace_back(static_cast<Tp*>(page_allocator_.Allocate()), 1);
        return z.back().first;
    }

    void Deallocate(Tp* p) {
        auto ind = getindex(p);
        if (ind != -1) {
            z[ind].second--;
        }
    }

    const PageAllocator& InnerAllocator() const noexcept {
        return page_allocator_;
    }

 private:
    std::vector<std::pair<Tp*, uint64_t>> z;

    uint64_t pg_size;

    int64_t getindex(Tp* p) {
        for (uint64_t i = 0; i < z.size(); i++)
            if (z[i].first == p)
                return i;
        return -1;
    }
};