/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2021, Danny Robson */ #pragma once #if 0 && __has_include() #include #else #include #endif #include #include namespace std::pmr { class memory_resource { public: memory_resource () = default; memory_resource (memory_resource const&) = default; memory_resource& operator= (memory_resource const&) = default; virtual ~memory_resource () = default; [[nodiscard]] void* allocate ( std::size_t bytes, std::size_t alignment = alignof (std::max_align_t) ) { return do_allocate (bytes, alignment); } void deallocate( void* p, std::size_t bytes, std::size_t alignment = alignof(std::max_align_t) ) { return do_deallocate (p, bytes, alignment); } bool is_equal (memory_resource const &rhs) const noexcept { return do_is_equal (rhs); } private: virtual void *do_allocate (std::size_t bytes, std::size_t alignment) = 0; virtual void do_deallocate (void *p, std::size_t bytes, std::size_t alignment) = 0; virtual bool do_is_equal (memory_resource const&) const noexcept = 0; }; } /////////////////////////////////////////////////////////////////////////////// namespace cruft::alloc { /// An unbounded contiguous allocator that operates on chunks, similar to /// a deque. /// /// It's useful as a means to keep unknown sized allocations in roughly /// the same memory region. /// /// This class models std::pmr::memory_resource. class chunked : public std::pmr::memory_resource { public: static constexpr std::size_t DEFAULT_CHUNK_SIZE = 4096; explicit chunked (std::size_t initial_size); chunked (std::size_t initial_size, std::size_t chunk_size); ~chunked () noexcept; private: void* do_allocate ( std::size_t bytes, std::size_t alignment = alignof (std::max_align_t) ) override; void do_deallocate ( void *p, std::size_t bytes, std::size_t alignment = alignof (std::max_align_t) ) override; bool do_is_equal (memory_resource const&) const noexcept override; std::size_t m_chunk; struct allocation_t { std::size_t size; allocation_t* next; }; union node { std::byte *data; allocation_t *node; }; struct arena { std::byte *head; node remain; }; std::vector m_data; }; }