4#ifndef IT_D4NP_MEMORYPOOL_POOL_MEMORY_RESOURCE_HPP_
5#define IT_D4NP_MEMORYPOOL_POOL_MEMORY_RESOURCE_HPP_
41#if defined(__has_include)
42#if __has_include(<memory_resource>)
43#include <memory_resource>
51#if defined(__cpp_lib_memory_resource) && __cpp_lib_memory_resource >= 201603L
52#define PBR_MEMORY_POOL_HAS_PMR 1
54#define PBR_MEMORY_POOL_HAS_PMR 0
58#if PBR_MEMORY_POOL_HAS_PMR
63namespace it::d4np::memorypool {
95class PoolMemoryResource :
public std::pmr::memory_resource {
106 explicit PoolMemoryResource(Pool& pool,
107 std::pmr::memory_resource* upstream = std::pmr::get_default_resource()) noexcept
108 : pool_(&pool), upstream_(upstream) {}
111 [[nodiscard]] Pool& pool() const noexcept {
116 [[nodiscard]] std::pmr::memory_resource* upstream_resource() const noexcept {
131 void* do_allocate(std::size_t bytes, std::size_t alignment)
override {
132 if (routes_to_pool(bytes, alignment)) {
133 void*
const block = pool_->try_allocate();
134 if (block ==
nullptr) {
135 throw std::bad_alloc{};
139 return upstream_->allocate(bytes, alignment);
149 void do_deallocate(
void* ptr, std::size_t bytes, std::size_t alignment)
override {
150 if (routes_to_pool(bytes, alignment)) {
151 pool_->deallocate(ptr);
154 upstream_->deallocate(ptr, bytes, alignment);
158 [[nodiscard]]
bool do_is_equal(
const std::pmr::memory_resource& other)
const noexcept override {
159 const auto*
const rhs =
dynamic_cast<const PoolMemoryResource*
>(&other);
160 return rhs !=
nullptr && rhs->pool_ == pool_ && rhs->upstream_ == upstream_;
166 [[nodiscard]]
bool routes_to_pool(std::size_t bytes, std::size_t alignment)
const noexcept {
167 return bytes <= pool_->block_size() && alignment <=
alignof(std::max_align_t);
171 std::pmr::memory_resource* upstream_;
C++17 RAII wrapper around the C memory pool.