#include <vector>

template<typename Tp>
class FixedAllocator {
 public:
  explicit FixedAllocator(std::uint64_t page_size = 0):
    page_allocator_(page_size * sizeof(Tp)), page_size_(page_size) {}
  Tp* Allocate() {
    if (this->memory_cell_.empty()) {
      Tp *pointer = static_cast<Tp *>(this->page_allocator_.Allocate());
      this->memory_cell_.push_back(pointer);
      for (int i = 0; i < this->page_size_ - 1; ++i) {
        ++pointer;
        this->memory_cell_.push_back(pointer);
      }
    }
    Tp* out = this->memory_cell_[this->page_size_];
    this->memory_cell_.pop_back();
    return out;
  }
  void Deallocate(Tp* pointer) {
    this->memory_cell_.push_back(pointer);
  }

  [[nodiscard]] const PageAllocator& InnerAllocator() const noexcept {
    return this->page_allocator_;
  }

 private:
  PageAllocator page_allocator_;
  std::uint64_t page_size_;
  std::vector<Tp *> memory_cell_;
};