EnTT 3.13.0
Loading...
Searching...
No Matches
container.hpp
1#ifndef ENTT_META_CONTAINER_HPP
2#define ENTT_META_CONTAINER_HPP
3
4#include <array>
5#include <deque>
6#include <iterator>
7#include <list>
8#include <map>
9#include <set>
10#include <type_traits>
11#include <unordered_map>
12#include <unordered_set>
13#include <vector>
14#include "../container/dense_map.hpp"
15#include "../container/dense_set.hpp"
16#include "context.hpp"
17#include "meta.hpp"
18#include "type_traits.hpp"
19
20namespace entt {
21
23namespace internal {
24
25template<typename, typename = void>
26struct fixed_size_sequence_container: std::true_type {};
27
28template<typename Type>
29struct fixed_size_sequence_container<Type, std::void_t<decltype(&Type::clear)>>: std::false_type {};
30
31template<typename Type>
32inline constexpr bool fixed_size_sequence_container_v = fixed_size_sequence_container<Type>::value;
33
34template<typename, typename = void>
35struct key_only_associative_container: std::true_type {};
36
37template<typename Type>
38struct key_only_associative_container<Type, std::void_t<typename Type::mapped_type>>: std::false_type {};
39
40template<typename Type>
41inline constexpr bool key_only_associative_container_v = key_only_associative_container<Type>::value;
42
43template<typename, typename = void>
44struct reserve_aware_container: std::false_type {};
45
46template<typename Type>
47struct reserve_aware_container<Type, std::void_t<decltype(&Type::reserve)>>: std::true_type {};
48
49template<typename Type>
50inline constexpr bool reserve_aware_container_v = reserve_aware_container<Type>::value;
51
52} // namespace internal
59template<typename Type>
61 static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>, "Unexpected type");
62
64 static constexpr bool fixed_size = internal::fixed_size_sequence_container_v<Type>;
65
70
76 [[nodiscard]] static size_type size(const void *container) {
77 return static_cast<const Type *>(container)->size();
78 }
79
85 [[nodiscard]] static bool clear([[maybe_unused]] void *container) {
86 if constexpr(fixed_size) {
87 return false;
88 } else {
89 static_cast<Type *>(container)->clear();
90 return true;
91 }
92 }
93
100 [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
101 if constexpr(internal::reserve_aware_container_v<Type>) {
102 static_cast<Type *>(container)->reserve(sz);
103 return true;
104 } else {
105 return false;
106 }
107 }
108
115 [[nodiscard]] static bool resize([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
116 if constexpr(fixed_size || !std::is_default_constructible_v<typename Type::value_type>) {
117 return false;
118 } else {
119 static_cast<Type *>(container)->resize(sz);
120 return true;
121 }
122 }
123
131 static iterator begin(const meta_ctx &area, void *container, const void *as_const) {
132 return container ? iterator{area, static_cast<Type *>(container)->begin()}
133 : iterator{area, static_cast<const Type *>(as_const)->begin()};
134 }
135
143 static iterator end(const meta_ctx &area, void *container, const void *as_const) {
144 return container ? iterator{area, static_cast<Type *>(container)->end()}
145 : iterator{area, static_cast<const Type *>(as_const)->end()};
146 }
147
160 [[nodiscard]] static iterator insert(const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const void *value, [[maybe_unused]] const void *cref, [[maybe_unused]] const iterator &it) {
161 if constexpr(fixed_size) {
162 return iterator{area};
163 } else {
164 auto *const non_const = any_cast<typename Type::iterator>(&it.base());
165 return {area, static_cast<Type *>(container)->insert(
166 non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()),
167 value ? *static_cast<const typename Type::value_type *>(value) : *static_cast<const std::remove_reference_t<typename Type::const_reference> *>(cref))};
168 }
169 }
170
178 [[nodiscard]] static iterator erase(const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const iterator &it) {
179 if constexpr(fixed_size) {
180 return iterator{area};
181 } else {
182 auto *const non_const = any_cast<typename Type::iterator>(&it.base());
183 return {area, static_cast<Type *>(container)->erase(non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()))};
184 }
185 }
186};
187
192template<typename Type>
194 static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>, "Unexpected type");
195
197 static constexpr bool key_only = internal::key_only_associative_container_v<Type>;
198
203
209 [[nodiscard]] static size_type size(const void *container) {
210 return static_cast<const Type *>(container)->size();
211 }
212
218 [[nodiscard]] static bool clear(void *container) {
219 static_cast<Type *>(container)->clear();
220 return true;
221 }
222
229 [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
230 if constexpr(internal::reserve_aware_container_v<Type>) {
231 static_cast<Type *>(container)->reserve(sz);
232 return true;
233 } else {
234 return false;
235 }
236 }
237
245 static iterator begin(const meta_ctx &area, void *container, const void *as_const) {
246 return container ? iterator{area, std::bool_constant<key_only>{}, static_cast<Type *>(container)->begin()}
247 : iterator{area, std::bool_constant<key_only>{}, static_cast<const Type *>(as_const)->begin()};
248 }
249
257 static iterator end(const meta_ctx &area, void *container, const void *as_const) {
258 return container ? iterator{area, std::bool_constant<key_only>{}, static_cast<Type *>(container)->end()}
259 : iterator{area, std::bool_constant<key_only>{}, static_cast<const Type *>(as_const)->end()};
260 }
261
269 [[nodiscard]] static bool insert(void *container, const void *key, [[maybe_unused]] const void *value) {
270 if constexpr(key_only) {
271 return static_cast<Type *>(container)->insert(*static_cast<const typename Type::key_type *>(key)).second;
272 } else {
273 return static_cast<Type *>(container)->emplace(*static_cast<const typename Type::key_type *>(key), *static_cast<const typename Type::mapped_type *>(value)).second;
274 }
275 }
276
283 [[nodiscard]] static size_type erase(void *container, const void *key) {
284 return static_cast<Type *>(container)->erase(*static_cast<const typename Type::key_type *>(key));
285 }
286
295 static iterator find(const meta_ctx &area, void *container, const void *as_const, const void *key) {
296 return container ? iterator{area, std::bool_constant<key_only>{}, static_cast<Type *>(container)->find(*static_cast<const typename Type::key_type *>(key))}
297 : iterator{area, std::bool_constant<key_only>{}, static_cast<const Type *>(as_const)->find(*static_cast<const typename Type::key_type *>(key))};
298 }
299};
300
305template<typename... Args>
306struct meta_sequence_container_traits<std::vector<Args...>>
307 : basic_meta_sequence_container_traits<std::vector<Args...>> {};
308
314template<typename Type, auto N>
315struct meta_sequence_container_traits<std::array<Type, N>>
316 : basic_meta_sequence_container_traits<std::array<Type, N>> {};
317
322template<typename... Args>
323struct meta_sequence_container_traits<std::list<Args...>>
324 : basic_meta_sequence_container_traits<std::list<Args...>> {};
325
330template<typename... Args>
331struct meta_sequence_container_traits<std::deque<Args...>>
332 : basic_meta_sequence_container_traits<std::deque<Args...>> {};
333
338template<typename... Args>
339struct meta_associative_container_traits<std::map<Args...>>
340 : basic_meta_associative_container_traits<std::map<Args...>> {};
341
347template<typename... Args>
348struct meta_associative_container_traits<std::unordered_map<Args...>>
349 : basic_meta_associative_container_traits<std::unordered_map<Args...>> {};
350
355template<typename... Args>
356struct meta_associative_container_traits<std::set<Args...>>
357 : basic_meta_associative_container_traits<std::set<Args...>> {};
358
364template<typename... Args>
365struct meta_associative_container_traits<std::unordered_set<Args...>>
366 : basic_meta_associative_container_traits<std::unordered_set<Args...>> {};
367
372template<typename... Args>
374 : basic_meta_associative_container_traits<dense_map<Args...>> {};
375
380template<typename... Args>
382 : basic_meta_associative_container_traits<dense_set<Args...>> {};
383
384} // namespace entt
385
386#endif
Associative container for key-value pairs with unique keys.
Associative container for unique objects of a given type.
std::size_t size_type
Unsigned integer type.
Definition meta.hpp:105
meta_iterator iterator
Meta iterator type.
Definition meta.hpp:107
Opaque meta context type.
Definition context.hpp:34
meta_iterator iterator
Meta iterator type.
Definition meta.hpp:37
std::size_t size_type
Unsigned integer type.
Definition meta.hpp:35
EnTT default namespace.
Definition dense_map.hpp:21
@ cref
Const aliasing mode, the object points to a const element.
General purpose implementation of meta associative container traits.
static iterator begin(const meta_ctx &area, void *container, const void *as_const)
Returns a possibly const iterator to the beginning.
static iterator find(const meta_ctx &area, void *container, const void *as_const, const void *key)
Finds an element with a given key.
static iterator end(const meta_ctx &area, void *container, const void *as_const)
Returns a possibly const iterator to the end.
static bool reserve(void *container, const size_type sz)
Increases the capacity of a container.
typename meta_associative_container::iterator iterator
Meta iterator type.
static constexpr bool key_only
True in case of key-only containers, false otherwise.
static size_type size(const void *container)
Returns the number of elements in a container.
typename meta_associative_container::size_type size_type
Unsigned integer type.
static bool clear(void *container)
Clears a container.
static bool insert(void *container, const void *key, const void *value)
Inserts an element into a container, if the key does not exist.
static size_type erase(void *container, const void *key)
Removes an element from a container.
General purpose implementation of meta sequence container traits.
Definition container.hpp:60
typename meta_sequence_container::size_type size_type
Unsigned integer type.
Definition container.hpp:67
typename meta_sequence_container::iterator iterator
Meta iterator type.
Definition container.hpp:69
static iterator begin(const meta_ctx &area, void *container, const void *as_const)
Returns a possibly const iterator to the beginning.
static size_type size(const void *container)
Returns the number of elements in a container.
Definition container.hpp:76
static iterator end(const meta_ctx &area, void *container, const void *as_const)
Returns a possibly const iterator to the end.
static iterator erase(const meta_ctx &area, void *container, const iterator &it)
Erases an element from a container.
static iterator insert(const meta_ctx &area, void *container, const void *value, const void *cref, const iterator &it)
Assigns one element to a container and constructs its object from a given opaque instance.
static bool resize(void *container, const size_type sz)
Resizes a container.
static bool reserve(void *container, const size_type sz)
Increases the capacity of a container.
static constexpr bool fixed_size
True in case of key-only containers, false otherwise.
Definition container.hpp:64
static bool clear(void *container)
Clears a container.
Definition container.hpp:85
Traits class template to be specialized to enable support for meta associative containers.
Traits class template to be specialized to enable support for meta sequence containers.