General Purpose library for Freestanding C++ and POSIX systems
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 

72 行
1.4 KiB

#pragma once
#include "gp/ring_list.hpp"
#include "gp/allocator/allocator.hpp"
#include <stddef.h>
namespace gp {
class aggregator : public allocator {
using local_container = ring_list<allocator, true>;
local_container contents;
local_container::explorer mark;
public:
template<typename bootstrapper>
aggregator(bootstrapper&& allocator_v)
: contents{
new(allocator_v.allocate(sizeof(local_container::node)))
local_container::node(
new(allocator_v.allocate(sizeof(bootstrapper))) std::remove_reference_t<bootstrapper>(gp::forward<bootstrapper&&>(allocator_v))
),
*this
}
, mark{contents.explore()}
{}
template<typename s_allocator>
bool insert(s_allocator&& value) {
return contents.insert<
std::remove_reference_t<
s_allocator
>
>(gp::forward<s_allocator>(value));
}
virtual void* allocate(size_t sz) {
auto cpy = mark;
do{
if(auto allocated = (*mark).allocate(sz))
{
return allocated;
}
++mark;
}while(cpy != mark);
return nullptr;
}
virtual bool deallocate(void* ptr) {
auto cpy = mark;
do{
if((*cpy).deallocate(ptr))
{
return true;
}
--cpy;
}while(cpy != mark);
return false;
}
virtual bool try_reallocate(void* ptr, size_t sz) {
auto cpy = mark;
do{
if((*cpy).try_reallocate(ptr, sz))
{
return true;
}
--cpy;
}while(cpy != mark);
return false;
}
};
}