|
|
- #pragma once
-
- #include "gp/ring_list.hpp"
-
- #include <stddef.h>
-
- 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<typename alloc>
- 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<virtual_allocator, aggregator, false, true>;
-
- local_container contents;
- local_container::explorer mark;
-
- public:
- template<typename bootstrapper>
- 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<typename allocator>
- 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;
- }
- };
- }
|