Skip to content

Commit 3b71902

Browse files
committed
entt: constrain allocator types
1 parent 7b46448 commit 3b71902

File tree

25 files changed

+97
-88
lines changed

25 files changed

+97
-88
lines changed

src/entt/container/dense_map.hpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "../config/config.h"
1818
#include "../core/bit.hpp"
1919
#include "../core/compressed_pair.hpp"
20+
#include "../core/concepts.hpp"
2021
#include "../core/iterator.hpp"
2122
#include "../core/memory.hpp"
2223
#include "../core/type_traits.hpp"
@@ -39,18 +40,16 @@ struct dense_map_node final {
3940
: next{pos},
4041
element{std::forward<Args>(args)...} {}
4142

42-
template<typename Allocator, typename... Args>
43-
dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
43+
template<typename... Args>
44+
dense_map_node(std::allocator_arg_t, const allocator_like auto &allocator, const std::size_t pos, Args &&...args)
4445
: next{pos},
4546
element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
4647

47-
template<typename Allocator>
48-
dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
48+
dense_map_node(std::allocator_arg_t, const allocator_like auto &allocator, const dense_map_node &other)
4949
: next{other.next},
5050
element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
5151

52-
template<typename Allocator>
53-
dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
52+
dense_map_node(std::allocator_arg_t, const allocator_like auto &allocator, dense_map_node &&other)
5453
: next{other.next},
5554
element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
5655

@@ -228,9 +227,8 @@ class dense_map_local_iterator final {
228227
* @tparam Type Mapped type of the associative container.
229228
* @tparam Hash Type of function to use to hash the keys.
230229
* @tparam KeyEqual Type of function to use to compare the keys for equality.
231-
* @tparam Allocator Type of allocator used to manage memory and elements.
232230
*/
233-
template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
231+
template<typename Key, typename Type, typename Hash, typename KeyEqual, allocator_like Allocator>
234232
class dense_map {
235233
static constexpr float default_threshold = 0.875f;
236234
static constexpr std::size_t minimum_capacity = 8u;
@@ -1020,7 +1018,7 @@ class dense_map {
10201018
/*! @cond ENTT_INTERNAL */
10211019
namespace std {
10221020

1023-
template<typename Key, typename Value, typename Allocator>
1021+
template<typename Key, typename Value, entt::allocator_like Allocator>
10241022
struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
10251023
: std::true_type {};
10261024

src/entt/container/dense_set.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,8 @@ class dense_set_local_iterator final {
190190
* @tparam Type Value type of the associative container.
191191
* @tparam Hash Type of function to use to hash the values.
192192
* @tparam KeyEqual Type of function to use to compare the values for equality.
193-
* @tparam Allocator Type of allocator used to manage memory and elements.
194193
*/
195-
template<typename Type, typename Hash, typename KeyEqual, typename Allocator>
194+
template<typename Type, typename Hash, typename KeyEqual, allocator_like Allocator>
196195
class dense_set {
197196
static constexpr float default_threshold = 0.875f;
198197
static constexpr std::size_t minimum_capacity = 8u;

src/entt/container/fwd.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <memory>
66
#include <utility>
77
#include <vector>
8+
#include "../core/concepts.hpp"
89

910
namespace entt {
1011

@@ -13,14 +14,14 @@ template<
1314
typename Type,
1415
typename = std::hash<Key>,
1516
typename = std::equal_to<>,
16-
typename = std::allocator<std::pair<const Key, Type>>>
17+
allocator_like = std::allocator<std::pair<const Key, Type>>>
1718
class dense_map;
1819

1920
template<
2021
typename Type,
2122
typename = std::hash<Type>,
2223
typename = std::equal_to<>,
23-
typename = std::allocator<Type>>
24+
allocator_like = std::allocator<Type>>
2425
class dense_set;
2526

2627
template<typename...>

src/entt/container/table.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,9 @@ class basic_table {
170170

171171
/**
172172
* @brief Constructs the underlying containers using a given allocator.
173-
* @tparam Allocator Type of allocator.
174173
* @param allocator A valid allocator.
175174
*/
176-
template<typename Allocator>
177-
explicit basic_table(const Allocator &allocator)
175+
explicit basic_table(const allocator_like auto &allocator)
178176
: payload{Container{allocator}...} {}
179177

180178
/**
@@ -424,7 +422,7 @@ class basic_table {
424422
/*! @cond ENTT_INTERNAL */
425423
namespace std {
426424

427-
template<typename... Container, typename Allocator>
425+
template<typename... Container, entt::allocator_like Allocator>
428426
struct uses_allocator<entt::basic_table<Container...>, Allocator>
429427
: std::bool_constant<(std::uses_allocator_v<Container, Allocator> && ...)> {};
430428

src/entt/core/memory.hpp

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <type_traits>
88
#include <utility>
99
#include "../config/config.h"
10+
#include "../core/concepts.hpp"
1011
#include "../stl/memory.hpp"
1112

1213
namespace entt {
@@ -17,7 +18,7 @@ namespace entt {
1718
* @param lhs A valid allocator.
1819
* @param rhs Another valid allocator.
1920
*/
20-
template<typename Allocator>
21+
template<allocator_like Allocator>
2122
constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
2223
if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
2324
lhs = rhs;
@@ -30,7 +31,7 @@ constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator
3031
* @param lhs A valid allocator.
3132
* @param rhs Another valid allocator.
3233
*/
33-
template<typename Allocator>
34+
template<allocator_like Allocator>
3435
constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
3536
if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
3637
lhs = std::move(rhs);
@@ -43,7 +44,7 @@ constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator
4344
* @param lhs A valid allocator.
4445
* @param rhs Another valid allocator.
4546
*/
46-
template<typename Allocator>
47+
template<allocator_like Allocator>
4748
constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
4849
if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
4950
using std::swap;
@@ -57,7 +58,7 @@ constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[ma
5758
* @brief Deleter for allocator-aware unique pointers (waiting for C++20).
5859
* @tparam Allocator Type of allocator used to manage memory and elements.
5960
*/
60-
template<typename Allocator>
61+
template<allocator_like Allocator>
6162
struct allocation_deleter: private Allocator {
6263
/*! @brief Allocator type. */
6364
using allocator_type = Allocator;
@@ -91,7 +92,7 @@ struct allocation_deleter: private Allocator {
9192
* @param args Parameters to use to construct the object.
9293
* @return A properly initialized unique pointer with a custom deleter.
9394
*/
94-
template<typename Type, typename Allocator, typename... Args>
95+
template<typename Type, allocator_like Allocator, typename... Args>
9596
constexpr auto allocate_unique(Allocator &allocator, Args &&...args) {
9697
static_assert(!std::is_array_v<Type>, "Array types are not supported");
9798

@@ -117,7 +118,7 @@ namespace internal {
117118

118119
template<typename Type>
119120
struct uses_allocator_construction {
120-
template<typename Allocator, typename... Params>
121+
template<allocator_like Allocator, typename... Params>
121122
static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept {
122123
if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
123124
return std::forward_as_tuple(std::forward<Params>(params)...);
@@ -138,31 +139,30 @@ template<typename Type, typename Other>
138139
struct uses_allocator_construction<std::pair<Type, Other>> {
139140
using type = std::pair<Type, Other>;
140141

141-
template<typename Allocator, typename First, typename Second>
142-
static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
142+
template<typename First, typename Second>
143+
static constexpr auto args(const allocator_like auto &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
143144
return std::make_tuple(
144145
std::piecewise_construct,
145146
std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
146147
std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
147148
}
148149

149-
template<typename Allocator>
150-
static constexpr auto args(const Allocator &allocator) noexcept {
150+
static constexpr auto args(const allocator_like auto &allocator) noexcept {
151151
return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
152152
}
153153

154-
template<typename Allocator, typename First, typename Second>
155-
static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept {
154+
template<typename First, typename Second>
155+
static constexpr auto args(const allocator_like auto &allocator, First &&first, Second &&second) noexcept {
156156
return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward<First>(first)), std::forward_as_tuple(std::forward<Second>(second)));
157157
}
158158

159-
template<typename Allocator, typename First, typename Second>
160-
static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) noexcept {
159+
template<typename First, typename Second>
160+
static constexpr auto args(const allocator_like auto &allocator, const std::pair<First, Second> &value) noexcept {
161161
return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
162162
}
163163

164-
template<typename Allocator, typename First, typename Second>
165-
static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) noexcept {
164+
template<typename First, typename Second>
165+
static constexpr auto args(const allocator_like auto &allocator, std::pair<First, Second> &&value) noexcept {
166166
return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second)));
167167
}
168168
};
@@ -177,14 +177,13 @@ struct uses_allocator_construction<std::pair<Type, Other>> {
177177
* create an object of a given type by means of uses-allocator construction.
178178
*
179179
* @tparam Type Type to return arguments for.
180-
* @tparam Allocator Type of allocator used to manage memory and elements.
181180
* @tparam Args Types of arguments to use to construct the object.
182181
* @param allocator The allocator to use.
183182
* @param args Parameters to use to construct the object.
184183
* @return The arguments needed to create an object of the given type.
185184
*/
186-
template<typename Type, typename Allocator, typename... Args>
187-
constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept {
185+
template<typename Type, typename... Args>
186+
constexpr auto uses_allocator_construction_args(const allocator_like auto &allocator, Args &&...args) noexcept {
188187
return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
189188
}
190189

@@ -195,14 +194,13 @@ constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args
195194
* means of uses-allocator construction.
196195
*
197196
* @tparam Type Type of object to create.
198-
* @tparam Allocator Type of allocator used to manage memory and elements.
199197
* @tparam Args Types of arguments to use to construct the object.
200198
* @param allocator The allocator to use.
201199
* @param args Parameters to use to construct the object.
202200
* @return A newly created object of the given type.
203201
*/
204-
template<typename Type, typename Allocator, typename... Args>
205-
constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
202+
template<typename Type, typename... Args>
203+
constexpr Type make_obj_using_allocator(const allocator_like auto &allocator, Args &&...args) {
206204
return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
207205
}
208206

@@ -213,15 +211,14 @@ constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...ar
213211
* means of uses-allocator construction at an uninitialized memory location.
214212
*
215213
* @tparam Type Type of object to create.
216-
* @tparam Allocator Type of allocator used to manage memory and elements.
217214
* @tparam Args Types of arguments to use to construct the object.
218215
* @param value Memory location in which to place the object.
219216
* @param allocator The allocator to use.
220217
* @param args Parameters to use to construct the object.
221218
* @return A pointer to the newly created object of the given type.
222219
*/
223-
template<typename Type, typename Allocator, typename... Args>
224-
constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
220+
template<typename Type, typename... Args>
221+
constexpr Type *uninitialized_construct_using_allocator(Type *value, const allocator_like auto &allocator, Args &&...args) {
225222
return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
226223
}
227224

src/entt/entity/fwd.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ enum class deletion_policy : std::uint8_t {
4747
template<cvref_unqualified Type, entity_like Entity = entity>
4848
struct component_traits;
4949

50-
template<entity_like Entity = entity, typename = std::allocator<Entity>>
50+
template<entity_like Entity = entity, allocator_like = std::allocator<Entity>>
5151
class basic_sparse_set;
5252

53-
template<typename Type, entity_like = entity, typename = std::allocator<Type>>
53+
template<typename Type, entity_like = entity, allocator_like = std::allocator<Type>>
5454
class basic_storage;
5555

5656
template<typename, typename>
@@ -59,13 +59,13 @@ class basic_sigh_mixin;
5959
template<typename, typename>
6060
class basic_reactive_mixin;
6161

62-
template<entity_like Entity = entity, typename = std::allocator<Entity>>
62+
template<entity_like Entity = entity, allocator_like = std::allocator<Entity>>
6363
class basic_registry;
6464

6565
template<typename, typename>
6666
class basic_view;
6767

68-
template<typename Type, typename = std::allocator<Type *>>
68+
template<typename Type, allocator_like = std::allocator<Type *>>
6969
class basic_runtime_view;
7070

7171
template<typename, typename, typename>
@@ -241,7 +241,7 @@ struct type_list_transform<owned_t<Type...>, Op> {
241241
* @tparam Entity A valid entity type.
242242
* @tparam Allocator Type of allocator used to manage memory and elements.
243243
*/
244-
template<typename Type, entity_like Entity = entity, typename Allocator = std::allocator<Type>>
244+
template<typename Type, entity_like Entity = entity, allocator_like Allocator = std::allocator<Type>>
245245
struct storage_type {
246246
/*! @brief Type-to-storage conversion result. */
247247
using type = ENTT_STORAGE(sigh_mixin, basic_storage<Type, Entity, Allocator>);
@@ -255,7 +255,7 @@ struct reactive final {};
255255
* @tparam Entity A valid entity type.
256256
* @tparam Allocator Type of allocator used to manage memory and elements.
257257
*/
258-
template<entity_like Entity, typename Allocator>
258+
template<entity_like Entity, allocator_like Allocator>
259259
struct storage_type<reactive, Entity, Allocator> {
260260
/*! @brief Type-to-storage conversion result. */
261261
using type = ENTT_STORAGE(reactive_mixin, basic_storage<reactive, Entity, Allocator>);
@@ -274,7 +274,7 @@ using storage_type_t = storage_type<Args...>::type;
274274
* @tparam Entity A valid entity type.
275275
* @tparam Allocator Type of allocator used to manage memory and elements.
276276
*/
277-
template<typename Type, entity_like Entity = entity, typename Allocator = std::allocator<std::remove_const_t<Type>>>
277+
template<typename Type, entity_like Entity = entity, allocator_like Allocator = std::allocator<std::remove_const_t<Type>>>
278278
struct storage_for {
279279
/*! @brief Type-to-storage conversion result. */
280280
using type = constness_as_t<storage_type_t<std::remove_const_t<Type>, Entity, Allocator>, Type>;

src/entt/entity/group.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <utility>
1111
#include "../config/config.h"
1212
#include "../core/algorithm.hpp"
13+
#include "../core/concepts.hpp"
1314
#include "../core/fwd.hpp"
1415
#include "../core/iterator.hpp"
1516
#include "../core/type_info.hpp"
@@ -205,8 +206,8 @@ class group_handler<Type, 0u, Get, Exclude> final: public group_descriptor {
205206
public:
206207
using common_type = Type;
207208

208-
template<typename Allocator, typename... GType, typename... EType>
209-
group_handler(const Allocator &allocator, std::tuple<GType &...> gpool, std::tuple<EType &...> epool)
209+
template<typename... GType, typename... EType>
210+
group_handler(const allocator_like auto &allocator, std::tuple<GType &...> gpool, std::tuple<EType &...> epool)
210211
: pools{std::apply([](auto &&...cpool) { return std::array<common_type *, Get>{&cpool...}; }, gpool)},
211212
filter{std::apply([](auto &&...cpool) { return std::array<common_type *, Exclude>{&cpool...}; }, epool)},
212213
elem{allocator} {

src/entt/entity/registry.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class registry_storage_iterator final {
131131
It it;
132132
};
133133

134-
template<typename Allocator>
134+
template<allocator_like Allocator>
135135
class registry_context {
136136
using alloc_traits = std::allocator_traits<Allocator>;
137137
using allocator_type = alloc_traits::template rebind_alloc<std::pair<const id_type, basic_any<0u>>>;
@@ -210,7 +210,7 @@ class registry_context {
210210
* @tparam Entity A valid entity type.
211211
* @tparam Allocator Type of allocator used to manage memory and elements.
212212
*/
213-
template<entity_like Entity, typename Allocator>
213+
template<entity_like Entity, allocator_like Allocator>
214214
class basic_registry {
215215
using base_type = basic_sparse_set<Entity, Allocator>;
216216
using alloc_traits = std::allocator_traits<Allocator>;

src/entt/entity/runtime_view.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <iterator>
77
#include <utility>
88
#include <vector>
9+
#include "../core/concepts.hpp"
910
#include "entity.hpp"
1011
#include "fwd.hpp"
1112

@@ -115,7 +116,7 @@ class runtime_view_iterator final {
115116
* @tparam Type Common base type.
116117
* @tparam Allocator Type of allocator used to manage memory and elements.
117118
*/
118-
template<typename Type, typename Allocator>
119+
template<typename Type, allocator_like Allocator>
119120
class basic_runtime_view {
120121
using alloc_traits = std::allocator_traits<Allocator>;
121122
static_assert(std::is_same_v<typename alloc_traits::value_type, Type *>, "Invalid value type");

src/entt/entity/sparse_set.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "../core/algorithm.hpp"
1414
#include "../core/any.hpp"
1515
#include "../core/bit.hpp"
16+
#include "../core/concepts.hpp"
1617
#include "../core/type_info.hpp"
1718
#include "../stl/iterator.hpp"
1819
#include "entity.hpp"
@@ -136,7 +137,7 @@ struct sparse_set_iterator final {
136137
* @tparam Entity A valid entity type.
137138
* @tparam Allocator Type of allocator used to manage memory and elements.
138139
*/
139-
template<entity_like Entity, typename Allocator>
140+
template<entity_like Entity, allocator_like Allocator>
140141
class basic_sparse_set {
141142
using alloc_traits = std::allocator_traits<Allocator>;
142143
static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>, "Invalid value type");

0 commit comments

Comments
 (0)