- #pragma once
- #include "gp_config.hpp"
- #include "gp/buffer.hpp"
- #include <type_traits>
- #include <gp/algorithm/tmp_manip.hpp>
- #include "gp/math/integer_math.hpp"
- #include "gp/algorithm/min_max.hpp"
-
- namespace gp {
- template<typename page_allocator = int>
- class arena {
- page_allocator allocator;
- gp::buffer<char> data;
- size_t next;
- size_t count;
- public:
- arena()
- : next(0)
- , count(0)
- , data(gp::buffer<char>(nullptr,nullptr))
- {}
-
- arena(size_t sz)
- : next(0)
- , count(0)
- , data(nullptr,nullptr)
- {
- if constexpr (gp::has_allocator_interface<page_allocator>::value)
- {
- 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)
- : next(0)
- , count(0)
- , data(pos,pos+sz)
- {}
-
- void* allocate(size_t sz)
- {
- size_t align = gp::min((1 << gp::math::log2(sz)), 16);
- size_t padding = align - (reinterpret_cast<uintptr_t>(data.begin().data + next)) % align;
-
- auto ret=data.begin()+padding+next;
- if(data.contains(ret))
- {
- count++;
- next+=padding+sz;
- return ret.data;
- }
- 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;
- }
- next=0;
- }
- return true;
- }
- return false;
- }
-
- ~arena()
- {
- if constexpr(gp::has_allocator_interface<page_allocator>::value)
- {
- allocator.deallocate(&data[0]);
- }
- }
- };
- }
|