7
7
#include < array>
8
8
#include < cstddef>
9
9
#include < type_traits>
10
+ #include < memory>
10
11
11
12
namespace dice ::template_library {
12
13
@@ -23,79 +24,6 @@ namespace dice::template_library {
23
24
* Importantly, it is **not** the arena chunk size, rather it is the size of elements being placed into the arena.
24
25
* The chunk size itself as well as the maximum capacity cannot be configured, they are automatically determined by boost::pool.
25
26
*/
26
- template <size_t ...bucket_sizes>
27
- struct pool ;
28
-
29
- /* *
30
- * `std`-style allocator that allocates into an underlying pool.
31
- * The bucket size used for allocation is `sizeof(T) * n_elems`.
32
- *
33
- * @tparam T type to be allocated
34
- * @tparam bucket_sizes same as for `pool<bucket_sizes...>`
35
- */
36
- template <typename T, size_t ...bucket_sizes>
37
- struct pool_allocator {
38
- using value_type = T;
39
- using pointer = T *;
40
- using const_pointer = T const *;
41
- using void_pointer = void *;
42
- using const_void_pointer = void const *;
43
- using size_type = size_t ;
44
- using difference_type = std::ptrdiff_t ;
45
-
46
- using propagate_on_container_copy_assignment = std::true_type;
47
- using propagate_on_container_move_assignment = std::true_type;
48
- using propagate_on_container_swap = std::true_type;
49
- using is_always_equal = std::false_type;
50
-
51
- template <typename U>
52
- struct rebind {
53
- using other = pool_allocator<U, bucket_sizes...>;
54
- };
55
-
56
- private:
57
- template <typename , size_t ...>
58
- friend struct pool_allocator ;
59
-
60
- pool<bucket_sizes...> *pool_;
61
-
62
- public:
63
- explicit pool_allocator (pool<bucket_sizes...> &parent_pool) noexcept
64
- : pool_{&parent_pool} {
65
- }
66
-
67
- pool_allocator (pool_allocator const &other) noexcept = default ;
68
- pool_allocator (pool_allocator &&other) noexcept = default ;
69
- pool_allocator &operator =(pool_allocator const &other) noexcept = default ;
70
- pool_allocator &operator =(pool_allocator &&other) noexcept = default ;
71
- ~pool_allocator () noexcept = default ;
72
-
73
- template <typename U>
74
- pool_allocator (pool_allocator<U, bucket_sizes...> const &other) noexcept
75
- : pool_{other.pool_ } {
76
- }
77
-
78
- pointer allocate (size_t n) {
79
- return static_cast <pointer>(pool_->allocate (sizeof (T) * n));
80
- }
81
-
82
- void deallocate (pointer ptr, size_t n) {
83
- pool_->deallocate (ptr, sizeof (T) * n);
84
- }
85
-
86
- pool_allocator select_on_container_copy_construction () const {
87
- return pool_allocator{*pool_};
88
- }
89
-
90
- friend void swap (pool_allocator &lhs, pool_allocator &rhs) noexcept {
91
- using std::swap;
92
- swap (lhs.pool_ , rhs.pool_ );
93
- }
94
-
95
- bool operator ==(pool_allocator const &other) const noexcept = default ;
96
- bool operator !=(pool_allocator const &other) const noexcept = default ;
97
- };
98
-
99
27
template <size_t ...bucket_sizes>
100
28
struct pool {
101
29
static_assert (sizeof ...(bucket_sizes) > 0 ,
@@ -106,9 +34,6 @@ namespace dice::template_library {
106
34
using size_type = size_t ;
107
35
using difference_type = std::ptrdiff_t ;
108
36
109
- template <typename T>
110
- using allocator_type = pool_allocator<T, bucket_sizes...>;
111
-
112
37
private:
113
38
// note: underlying allocator can not be specified via template parameter
114
39
// because that would be of very limited usefulness, as boost::pool requires the allocation/deallocation functions
@@ -188,18 +113,87 @@ namespace dice::template_library {
188
113
void deallocate (void *data, size_t n_bytes) {
189
114
return deallocate_impl<0 , bucket_sizes...>(data, n_bytes);
190
115
}
116
+ };
117
+
118
+ /* *
119
+ * `std`-style allocator that allocates into an underlying pool.
120
+ * The bucket size used for allocation is `sizeof(T) * n_elems`.
121
+ *
122
+ * @tparam T type to be allocated
123
+ * @tparam bucket_sizes same as for `pool<bucket_sizes...>`
124
+ */
125
+ template <typename T, size_t ...bucket_sizes>
126
+ struct pool_allocator {
127
+ using value_type = T;
128
+ using pointer = T *;
129
+ using const_pointer = T const *;
130
+ using void_pointer = void *;
131
+ using const_void_pointer = void const *;
132
+ using size_type = size_t ;
133
+ using difference_type = std::ptrdiff_t ;
191
134
135
+ using propagate_on_container_copy_assignment = std::true_type;
136
+ using propagate_on_container_move_assignment = std::true_type;
137
+ using propagate_on_container_swap = std::true_type;
138
+ using is_always_equal = std::false_type;
139
+
140
+ template <typename U>
141
+ struct rebind {
142
+ using other = pool_allocator<U, bucket_sizes...>;
143
+ };
144
+
145
+ private:
146
+ template <typename , size_t ...>
147
+ friend struct pool_allocator ;
148
+
149
+ std::shared_ptr<pool<bucket_sizes...>> pool_;
150
+
151
+ public:
192
152
/* *
193
- * Retrieve an (`std`-style) allocator that allocates on `*this` pool.
194
- *
195
- * @warning the pool (`*this`) must always outlive the returned `pool_allocator`
196
- * @tparam T the type that should be allocated by the returned allocator
197
- * @return `std`-style allocator for this pool
153
+ * Creates a pool_allocator with a default constructed pool
198
154
*/
199
- template <typename T = std::byte>
200
- [[nodiscard]] allocator_type<T> get_allocator () noexcept {
201
- return pool_allocator<T, bucket_sizes...>{*this };
155
+ pool_allocator ()
156
+ : pool_{std::make_shared<pool<bucket_sizes...>>()} {
202
157
}
158
+
159
+ explicit pool_allocator (std::shared_ptr<pool<bucket_sizes...>> underlying_pool)
160
+ : pool_{std::move (underlying_pool)} {
161
+ }
162
+
163
+ pool_allocator (pool_allocator const &other) noexcept = default ;
164
+ pool_allocator (pool_allocator &&other) noexcept = default ;
165
+ pool_allocator &operator =(pool_allocator const &other) noexcept = default ;
166
+ pool_allocator &operator =(pool_allocator &&other) noexcept = default ;
167
+ ~pool_allocator () noexcept = default ;
168
+
169
+ template <typename U>
170
+ pool_allocator (pool_allocator<U, bucket_sizes...> const &other) noexcept
171
+ : pool_{other.pool_ } {
172
+ }
173
+
174
+ [[nodiscard]] std::shared_ptr<pool<bucket_sizes...>> const &underlying_pool () const noexcept {
175
+ return pool_;
176
+ }
177
+
178
+ pointer allocate (size_t n) {
179
+ return static_cast <pointer>(pool_->allocate (sizeof (T) * n));
180
+ }
181
+
182
+ void deallocate (pointer ptr, size_t n) {
183
+ pool_->deallocate (ptr, sizeof (T) * n);
184
+ }
185
+
186
+ pool_allocator select_on_container_copy_construction () const {
187
+ return pool_allocator{pool_};
188
+ }
189
+
190
+ friend void swap (pool_allocator &lhs, pool_allocator &rhs) noexcept {
191
+ using std::swap;
192
+ swap (lhs.pool_ , rhs.pool_ );
193
+ }
194
+
195
+ bool operator ==(pool_allocator const &other) const noexcept = default ;
196
+ bool operator !=(pool_allocator const &other) const noexcept = default ;
203
197
};
204
198
205
199
} // namespace dice::template_library
0 commit comments