#include <memory>
#include <iostream>
#include <vector>
#include <stack>
template<typename Tp>
class FixedAllocator {
PageAllocator* page_allocator_;
std::stack<Tp*>* free_memory_blocks;
std::uint64_t page_size;

 public:
explicit FixedAllocator(std::uint64_t page_size) : page_size(page_size) {
this->page_allocator_ = new PageAllocator(page_size * sizeof(Tp));
this->free_memory_blocks = new std::stack<Tp*>();
}
Tp* Allocate() {
if (!this->free_memory_blocks->size()) {
Tp* new_memory = reinterpret_cast<Tp*>(this->page_allocator_->Allocate());
for (size_t i = 0; i < page_size; ++i) {
this->free_memory_blocks->push(new_memory + i);
}

Tp* free_memory = this->free_memory_blocks->top();
this->free_memory_blocks->pop();
return free_memory;
} else {
Tp* free_memory = this->free_memory_blocks->top();
this->free_memory_blocks->pop();
return free_memory;
}
}
void Deallocate(Tp* p) {
this->free_memory_blocks->push(p);
}
const PageAllocator& InnerAllocator() const noexcept {
return *this->page_allocator_;
}
~FixedAllocator() {
delete page_allocator_;
delete free_memory_blocks;
}
};