General Purpose library for Freestanding C++ and POSIX systems
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 

95 řádky
1.5 KiB

#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;
fel::buffer<char> data;
size_t last;
size_t count;
public:
arena()
:last(0)
,count(0)
,data(fel::buffer<char>(nullptr,nullptr))
{}
template<typename T = typename std::enable_if<fel::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=fel::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;
}
}
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(fel::has_allocator_interface<page_allocator>::value)
{
allocator.deallocate(&data[0]);
}
}
};
}