Sleipnir C++ API
Loading...
Searching...
No Matches
pool.hpp
1// Copyright (c) Sleipnir contributors
2
3#pragma once
4
5#include <cstddef>
6#include <memory>
7
8#include "sleipnir/util/small_vector.hpp"
9#include "sleipnir/util/symbol_exports.hpp"
10
11namespace slp {
12
20class SLEIPNIR_DLLEXPORT PoolResource {
21 public:
27 explicit PoolResource(size_t blocks_per_chunk)
28 : blocks_per_chunk{blocks_per_chunk} {}
29
33 PoolResource(const PoolResource&) = delete;
34
41
46
53
61 [[nodiscard]]
62 void* allocate(size_t bytes, [[maybe_unused]] size_t alignment =
63 alignof(std::max_align_t)) {
64 if (m_free_list.empty()) {
65 add_chunk(bytes);
66 }
67
68 auto ptr = m_free_list.back();
69 m_free_list.pop_back();
70 return ptr;
71 }
72
81 void* p, [[maybe_unused]] size_t bytes,
82 [[maybe_unused]] size_t alignment = alignof(std::max_align_t)) {
83 m_free_list.emplace_back(p);
84 }
85
92 bool is_equal(const PoolResource& other) const noexcept {
93 return this == &other;
94 }
95
101 size_t blocks_in_use() const noexcept {
102 return m_buffer.size() * blocks_per_chunk - m_free_list.size();
103 }
104
105 private:
106 small_vector<std::unique_ptr<std::byte[]>> m_buffer;
107 small_vector<void*> m_free_list;
108 size_t blocks_per_chunk;
109
116 void add_chunk(size_t bytes_per_block) {
117 m_buffer.emplace_back(new std::byte[bytes_per_block * blocks_per_chunk]);
118 for (int i = blocks_per_chunk - 1; i >= 0; --i) {
119 m_free_list.emplace_back(m_buffer.back().get() + bytes_per_block * i);
120 }
121 }
122};
123
129template <typename T>
131 public:
135 using value_type = T;
136
142 explicit constexpr PoolAllocator(PoolResource* r) : m_memory_resource{r} {}
143
147 constexpr PoolAllocator(const PoolAllocator<T>&) = default;
148
154 constexpr PoolAllocator<T>& operator=(const PoolAllocator<T>&) = default;
155
162 [[nodiscard]]
163 constexpr T* allocate(size_t n) {
164 return static_cast<T*>(m_memory_resource->allocate(n));
165 }
166
173 constexpr void deallocate(T* p, size_t n) {
174 m_memory_resource->deallocate(p, n);
175 }
176
177 private:
178 PoolResource* m_memory_resource;
179};
180
184SLEIPNIR_DLLEXPORT PoolResource& global_pool_resource();
185
191template <typename T>
192PoolAllocator<T> global_pool_allocator() {
193 return PoolAllocator<T>{&global_pool_resource()};
194}
195
196} // namespace slp
Definition pool.hpp:130
constexpr PoolAllocator(const PoolAllocator< T > &)=default
constexpr PoolAllocator(PoolResource *r)
Definition pool.hpp:142
constexpr void deallocate(T *p, size_t n)
Definition pool.hpp:173
constexpr PoolAllocator< T > & operator=(const PoolAllocator< T > &)=default
T value_type
Definition pool.hpp:135
constexpr T * allocate(size_t n)
Definition pool.hpp:163
Definition pool.hpp:20
PoolResource(size_t blocks_per_chunk)
Definition pool.hpp:27
PoolResource(PoolResource &&)=default
void * allocate(size_t bytes, size_t alignment=alignof(std::max_align_t))
Definition pool.hpp:62
bool is_equal(const PoolResource &other) const noexcept
Definition pool.hpp:92
PoolResource(const PoolResource &)=delete
size_t blocks_in_use() const noexcept
Definition pool.hpp:101
PoolResource & operator=(PoolResource &&)=default
PoolResource & operator=(const PoolResource &)=delete
void deallocate(void *p, size_t bytes, size_t alignment=alignof(std::max_align_t))
Definition pool.hpp:80