EnTT 3.16.0
Loading...
Searching...
No Matches
container.hpp
1// IWYU pragma: always_keep
2
3#ifndef ENTT_META_CONTAINER_HPP
4#define ENTT_META_CONTAINER_HPP
5
6#include <array>
7#include <cstddef>
8#include <deque>
9#include <iterator>
10#include <list>
11#include <map>
12#include <set>
13#include <type_traits>
14#include <unordered_map>
15#include <unordered_set>
16#include <vector>
17#include "../container/dense_map.hpp"
18#include "../container/dense_set.hpp"
19#include "../core/type_traits.hpp"
20#include "context.hpp"
21#include "fwd.hpp"
22#include "meta.hpp"
23#include "type_traits.hpp"
24
25namespace entt {
26
28namespace internal {
29
30template<typename Type, typename = void>
31struct sequence_container_extent: integral_constant<meta_dynamic_extent> {};
32
33template<typename Type>
34struct sequence_container_extent<Type, std::enable_if_t<is_complete_v<std::tuple_size<Type>>>>: integral_constant<std::tuple_size_v<Type>> {};
35
36template<typename Type>
37inline constexpr std::size_t sequence_container_extent_v = sequence_container_extent<Type>::value;
38
39template<typename, typename = void>
40struct key_only_associative_container: std::true_type {};
41
42template<typename Type>
43struct key_only_associative_container<Type, std::void_t<typename Type::mapped_type>>: std::false_type {};
44
45template<typename Type>
46inline constexpr bool key_only_associative_container_v = key_only_associative_container<Type>::value;
47
48template<typename, typename = void>
49struct reserve_aware_container: std::false_type {};
50
51template<typename Type>
52struct reserve_aware_container<Type, std::void_t<decltype(&Type::reserve)>>: std::true_type {};
53
54template<typename Type>
55inline constexpr bool reserve_aware_container_v = reserve_aware_container<Type>::value;
56
57} // namespace internal
59
64template<typename Type>
66 static_assert(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>, "Unexpected type");
67
72
74 static constexpr std::size_t extent = internal::sequence_container_extent_v<Type>;
76 [[deprecated("use ::extent instead")]] static constexpr bool fixed_size = (extent != meta_dynamic_extent);
77
83 [[nodiscard]] static size_type size(const void *container) {
84 return static_cast<const Type *>(container)->size();
85 }
86
92 [[nodiscard]] static bool clear([[maybe_unused]] void *container) {
93 if constexpr(extent == meta_dynamic_extent) {
94 static_cast<Type *>(container)->clear();
95 return true;
96 } else {
97 return false;
98 }
99 }
100
107 [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
108 if constexpr(internal::reserve_aware_container_v<Type>) {
109 static_cast<Type *>(container)->reserve(sz);
110 return true;
111 } else {
112 return false;
113 }
114 }
115
122 [[nodiscard]] static bool resize([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
123 if constexpr((extent == meta_dynamic_extent) && std::is_default_constructible_v<typename Type::value_type>) {
124 static_cast<Type *>(container)->resize(sz);
125 return true;
126 } else {
127 return false;
128 }
129 }
130
140 static iterator iter(const meta_ctx &area, void *container, const void *as_const, const bool end) {
141 return (container == nullptr)
142 ? iterator{area, end ? static_cast<const Type *>(as_const)->cend() : static_cast<const Type *>(as_const)->cbegin()}
143 : iterator{area, end ? static_cast<Type *>(container)->end() : static_cast<Type *>(container)->begin()};
144 }
145
158 [[nodiscard]] static iterator insert([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const void *value, [[maybe_unused]] const void *cref, [[maybe_unused]] const iterator &it) {
159 if constexpr(extent == meta_dynamic_extent) {
160 auto *const non_const = any_cast<typename Type::iterator>(&it.base());
161 return {area, static_cast<Type *>(container)->insert(
162 non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()),
163 (value != nullptr) ? *static_cast<const typename Type::value_type *>(value) : *static_cast<const std::remove_reference_t<typename Type::const_reference> *>(cref))};
164 } else {
165 return iterator{};
166 }
167 }
168
176 [[nodiscard]] static iterator erase([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const iterator &it) {
177 if constexpr(extent == meta_dynamic_extent) {
178 auto *const non_const = any_cast<typename Type::iterator>(&it.base());
179 return {area, static_cast<Type *>(container)->erase(non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()))};
180 } else {
181 return iterator{};
182 }
183 }
184};
185
190template<typename Type>
192 static_assert(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>, "Unexpected type");
193
198
200 static constexpr bool key_only = internal::key_only_associative_container_v<Type>;
201
207 [[nodiscard]] static size_type size(const void *container) {
208 return static_cast<const Type *>(container)->size();
209 }
210
216 [[nodiscard]] static bool clear(void *container) {
217 static_cast<Type *>(container)->clear();
218 return true;
219 }
220
227 [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
228 if constexpr(internal::reserve_aware_container_v<Type>) {
229 static_cast<Type *>(container)->reserve(sz);
230 return true;
231 } else {
232 return false;
233 }
234 }
235
245 static iterator iter(const meta_ctx &area, void *container, const void *as_const, const bool end) {
246 return (container == nullptr)
247 ? iterator{area, std::bool_constant<key_only>{}, end ? static_cast<const Type *>(as_const)->cend() : static_cast<const Type *>(as_const)->cbegin()}
248 : iterator{area, std::bool_constant<key_only>{}, end ? static_cast<Type *>(container)->end() : static_cast<Type *>(container)->begin()};
249 }
250
258 [[nodiscard]] static bool insert(void *container, const void *key, [[maybe_unused]] const void *value) {
259 if constexpr(key_only) {
260 return static_cast<Type *>(container)->insert(*static_cast<const typename Type::key_type *>(key)).second;
261 } else {
262 return static_cast<Type *>(container)->emplace(*static_cast<const typename Type::key_type *>(key), *static_cast<const typename Type::mapped_type *>(value)).second;
263 }
264 }
265
272 [[nodiscard]] static size_type erase(void *container, const void *key) {
273 return static_cast<Type *>(container)->erase(*static_cast<const typename Type::key_type *>(key));
274 }
275
284 static iterator find(const meta_ctx &area, void *container, const void *as_const, const void *key) {
285 return (container != nullptr) ? iterator{area, std::bool_constant<key_only>{}, static_cast<Type *>(container)->find(*static_cast<const typename Type::key_type *>(key))}
286 : iterator{area, std::bool_constant<key_only>{}, static_cast<const Type *>(as_const)->find(*static_cast<const typename Type::key_type *>(key))};
287 }
288};
289
294template<typename... Args>
295struct meta_sequence_container_traits<std::vector<Args...>>
296 : basic_meta_sequence_container_traits<std::vector<Args...>> {};
297
303template<typename Type, auto N>
304struct meta_sequence_container_traits<std::array<Type, N>>
305 : basic_meta_sequence_container_traits<std::array<Type, N>> {};
306
311template<typename... Args>
312struct meta_sequence_container_traits<std::list<Args...>>
313 : basic_meta_sequence_container_traits<std::list<Args...>> {};
314
319template<typename... Args>
320struct meta_sequence_container_traits<std::deque<Args...>>
321 : basic_meta_sequence_container_traits<std::deque<Args...>> {};
322
327template<typename... Args>
328struct meta_associative_container_traits<std::map<Args...>>
329 : basic_meta_associative_container_traits<std::map<Args...>> {};
330
336template<typename... Args>
337struct meta_associative_container_traits<std::unordered_map<Args...>>
338 : basic_meta_associative_container_traits<std::unordered_map<Args...>> {};
339
344template<typename... Args>
345struct meta_associative_container_traits<std::set<Args...>>
346 : basic_meta_associative_container_traits<std::set<Args...>> {};
347
353template<typename... Args>
354struct meta_associative_container_traits<std::unordered_set<Args...>>
355 : basic_meta_associative_container_traits<std::unordered_set<Args...>> {};
356
361template<typename... Args>
364
369template<typename... Args>
372
373} // namespace entt
374
375#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:97
meta_iterator iterator
Meta iterator type.
Definition meta.hpp:99
Opaque meta context type.
Definition context.hpp:34
meta_iterator iterator
Meta iterator type.
Definition meta.hpp:38
std::size_t size_type
Unsigned integer type.
Definition meta.hpp:36
EnTT default namespace.
Definition dense_map.hpp:22
std::integral_constant< decltype(Value), Value > integral_constant
Wraps a static constant.
std::remove_const_t< Type > any_cast(const basic_any< Len, Align > &data) noexcept
Performs type-safe access to the contained object.
Definition any.hpp:547
@ cref
Const aliasing mode, const reference.
Definition fwd.hpp:21
constexpr std::size_t meta_dynamic_extent
Used to identicate that a sequence container has not a fixed size.
Definition fwd.hpp:31
General purpose implementation of meta associative container traits.
static iterator find(const meta_ctx &area, void *container, const void *as_const, const void *key)
Finds an element with a given key.
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 iterator iter(const meta_ctx &area, void *container, const void *as_const, const bool end)
Returns a possibly const iterator to the beginning or the end.
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:65
typename meta_sequence_container::size_type size_type
Unsigned integer type.
Definition container.hpp:69
typename meta_sequence_container::iterator iterator
Meta iterator type.
Definition container.hpp:71
static size_type size(const void *container)
Returns the number of elements in a container.
Definition container.hpp:83
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 fixed size containers, false otherwise.
Definition container.hpp:76
static iterator iter(const meta_ctx &area, void *container, const void *as_const, const bool end)
Returns a possibly const iterator to the beginning or the end.
static constexpr std::size_t extent
Number of elements, or meta_dynamic_extent if dynamic.
Definition container.hpp:74
static bool clear(void *container)
Clears a container.
Definition container.hpp:92
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.