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 <gch/small_vector.hpp>
9
10#include "sleipnir/util/symbol_exports.hpp"
11
12namespace slp {
13
19class SLEIPNIR_DLLEXPORT PoolResource {
20 public:
24 explicit PoolResource(size_t blocks_per_chunk)
25 : blocks_per_chunk{blocks_per_chunk} {}
26
28 PoolResource(const PoolResource&) = delete;
29
34
37
42
48 [[nodiscard]]
49 void* allocate(size_t bytes, [[maybe_unused]] size_t alignment =
50 alignof(std::max_align_t)) {
51 if (m_free_list.empty()) {
52 add_chunk(bytes);
53 }
54
55 auto ptr = m_free_list.back();
56 m_free_list.pop_back();
57 return ptr;
58 }
59
66 void* p, [[maybe_unused]] size_t bytes,
67 [[maybe_unused]] size_t alignment = alignof(std::max_align_t)) {
68 m_free_list.emplace_back(p);
69 }
70
77 bool is_equal(const PoolResource& other) const noexcept {
78 return this == &other;
79 }
80
85 return m_buffer.size() * blocks_per_chunk - m_free_list.size();
86 }
87
88 private:
89 gch::small_vector<std::unique_ptr<std::byte[]>> m_buffer;
90 gch::small_vector<void*> m_free_list;
91 size_t blocks_per_chunk;
92
97 void add_chunk(size_t bytes_per_block) {
98 m_buffer.emplace_back(new std::byte[bytes_per_block * blocks_per_chunk]);
99 for (int i = blocks_per_chunk - 1; i >= 0; --i) {
100 m_free_list.emplace_back(m_buffer.back().get() + bytes_per_block * i);
101 }
102 }
103};
104
108template <typename T>
110 public:
112 using value_type = T;
113
117 explicit constexpr PoolAllocator(PoolResource* r) : m_memory_resource{r} {}
118
120 constexpr PoolAllocator(const PoolAllocator<T>&) = default;
121
125 constexpr PoolAllocator<T>& operator=(const PoolAllocator<T>&) = default;
126
131 [[nodiscard]]
132 constexpr T* allocate(size_t n) {
133 return static_cast<T*>(m_memory_resource->allocate(n));
134 }
135
140 constexpr void deallocate(T* p, size_t n) {
141 m_memory_resource->deallocate(p, n);
142 }
143
144 private:
145 PoolResource* m_memory_resource;
146};
147
149SLEIPNIR_DLLEXPORT PoolResource& global_pool_resource();
150
154template <typename T>
155PoolAllocator<T> global_pool_allocator() {
156 return PoolAllocator<T>{&global_pool_resource()};
157}
158
159} // namespace slp
Definition intrusive_shared_ptr.hpp:27
Definition pool.hpp:109
constexpr PoolAllocator(const PoolAllocator< T > &)=default
Copy constructor.
constexpr PoolAllocator(PoolResource *r)
Definition pool.hpp:117
constexpr void deallocate(T *p, size_t n)
Definition pool.hpp:140
constexpr PoolAllocator< T > & operator=(const PoolAllocator< T > &)=default
T value_type
The type of object in the pool.
Definition pool.hpp:112
constexpr T * allocate(size_t n)
Definition pool.hpp:132
Definition pool.hpp:19
PoolResource(size_t blocks_per_chunk)
Definition pool.hpp:24
PoolResource(PoolResource &&)=default
Move constructor.
void * allocate(size_t bytes, size_t alignment=alignof(std::max_align_t))
Definition pool.hpp:49
bool is_equal(const PoolResource &other) const noexcept
Definition pool.hpp:77
PoolResource(const PoolResource &)=delete
Copy constructor.
size_t blocks_in_use() const noexcept
Definition pool.hpp:84
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:65