|
|
- #pragma once
- #include "gp_config.hpp"
- #include "gp/buffer.hpp"
- #include <type_traits>
- #include <gp/algorithm/tmp_manip.hpp>
-
-
-
- namespace gp{
- template<typename page_allocator, size_t align = 1>
- class arena{
- page_allocator allocator;
- gp::buffer<char> data;
- size_t last;
- size_t count;
- public:
- arena()
- :last(0)
- ,count(0)
- ,data(gp::buffer<char>(nullptr,nullptr))
- {}
-
- template<typename T = typename std::enable_if<gp::has_allocator_interface<page_allocator>::value,int>::type>
- arena(size_t sz)
- :last(0)
- ,count(0)
- ,data(nullptr,nullptr)
- {
- if(sz!=0)
- {
- auto v=allocator.allocate(sz);
- if(v!=nullptr)
- {
- data=gp::buffer<char>(reinterpret_cast<char*>(v),reinterpret_cast<char*>(v)+sz);
- }
- }
- }
-
- arena(char* pos,size_t sz)
- :last(0)
- ,count(0)
- ,data(pos,pos+sz)
- {
- }
-
- void* allocate(size_t sz)
- {
- [[maybe_unused]]
- size_t mod = 0;
-
- if constexpr (align != 1)
- {
- mod = align - ((intptr_t)data.begin())%align;
- }
-
- auto ret=data.begin()+last+mod;
- if(data.contains(ret))
- {
- count++;
- last+=sz+mod;
- return &*(ret);
- }
- else
- {
- return nullptr;
- }
- }
-
- constexpr bool try_reallocate(void*, size_t) {
- return false;
- }
-
- bool deallocate(void* ptr)
- {
- if(data.contains((char*)ptr))
- {
- count--;
- if(count==0)
- {
- for(auto& i : data)
- {
- i=0;
- }
- last=0;
- }
- return true;
- }
- return false;
- }
-
- ~arena()
- {
- if constexpr(gp::has_allocator_interface<page_allocator>::value)
- {
- allocator.deallocate(&data[0]);
- }
- }
- };
- }
|