#pragma once #include #include "gp/ring_list.hpp" namespace gp { class aggregator { struct virtual_allocator { virtual ~virtual_allocator() = default; virtual void* allocate(size_t) = 0; virtual bool deallocate(void*) = 0; virtual bool try_reallocate(void*, size_t) = 0; }; template class abstract_allocator final : public virtual_allocator{ alloc internal_representation; public: abstract_allocator(abstract_allocator& v) : internal_representation{v.internal_representation} {} abstract_allocator(alloc& v) : internal_representation{v} {} virtual ~abstract_allocator() override = default; virtual void* allocate(size_t sz) override { return internal_representation.allocate(sz); } virtual bool deallocate(void* ptr) override { return internal_representation.deallocate(ptr); } virtual bool try_reallocate(void* ptr, size_t sz) override { return internal_representation.try_reallocate(ptr, sz); } }; using local_container = ring_list; local_container contents; local_container::explorer mark; public: template aggregator(bootstrapper&& allocator) : contents{ new(allocator.allocate(sizeof(local_container::node))) local_container::node( new(allocator.allocate(sizeof(bootstrapper))) abstract_allocator(allocator) ), *this } , mark{contents.explore()} {} template bool insert(allocator&& value) { return contents.insert< abstract_allocator< std::remove_reference_t< allocator > > >(abstract_allocator(value)); } void* allocate(size_t sz) { auto cpy = mark; do{ if(auto allocated = (*mark).allocate(sz)) { return allocated; } ++mark; }while(cpy != mark); return nullptr; } bool deallocate(void* ptr) { auto cpy = mark; do{ if((*cpy).deallocate(ptr)) { return true; } --cpy; }while(cpy != mark); return false; } 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; } }; }