EnTT 4.0.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 "../core/concepts.hpp"
7#include "../core/type_traits.hpp"
8#include "../stl/concepts.hpp"
9#include "../stl/cstddef.hpp"
10#include "../stl/iterator.hpp"
11#include "../stl/type_traits.hpp"
12#include "../stl/utility.hpp"
13#include "context.hpp"
14#include "fwd.hpp"
15#include "meta.hpp"
16#include "type_traits.hpp"
17
18namespace entt {
19
21namespace internal {
22
23template<typename Type>
24struct sequence_container_extent: integral_constant<meta_dynamic_extent> {};
25
26template<typename Type>
27requires is_complete_v<stl::tuple_size<Type>>
28struct sequence_container_extent<Type>: integral_constant<stl::tuple_size_v<Type>> {};
29
30template<typename Type>
31inline constexpr stl::size_t sequence_container_extent_v = sequence_container_extent<Type>::value;
32
33template<typename Type>
34concept meta_sequence_container_like = requires(Type elem) {
35 typename Type::value_type;
36 typename Type::iterator;
37 requires entt::stl::forward_iterator<typename Type::iterator>;
38 { elem.begin() } -> stl::same_as<typename Type::iterator>;
39 { elem.end() } -> stl::same_as<typename Type::iterator>;
40 requires !requires { typename Type::key_type; };
41 requires !requires { elem.substr(); };
42};
43
44template<typename Type>
45concept meta_associative_container_like = requires(Type value) {
46 typename Type::key_type;
47 typename Type::value_type;
48 typename Type::iterator;
49 requires entt::stl::forward_iterator<typename Type::iterator>;
50 { value.begin() } -> stl::same_as<typename Type::iterator>;
51 { value.end() } -> stl::same_as<typename Type::iterator>;
52 value.find(stl::declval<typename Type::key_type>());
53};
54
55} // namespace internal
57
62template<cvref_unqualified Type>
68
70 static constexpr stl::size_t extent = internal::sequence_container_extent_v<Type>;
71
77 [[nodiscard]] static size_type size(const void *container) {
78 return static_cast<const Type *>(container)->size();
79 }
80
86 [[nodiscard]] static bool clear([[maybe_unused]] void *container) {
87 if constexpr(requires(Type elem) { elem.clear(); }) {
88 static_cast<Type *>(container)->clear();
89 return true;
90 } else {
91 return false;
92 }
93 }
94
101 [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
102 if constexpr(requires(Type elem) { elem.reserve(sz); }) {
103 static_cast<Type *>(container)->reserve(sz);
104 return true;
105 } else {
106 return false;
107 }
108 }
109
116 [[nodiscard]] static bool resize([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
117 if constexpr(stl::is_default_constructible_v<typename Type::value_type> && requires(Type elem) { elem.resize(sz); }) {
118 static_cast<Type *>(container)->resize(sz);
119 return true;
120 } else {
121 return false;
122 }
123 }
124
134 static iterator iter(const meta_ctx &area, void *container, const void *as_const, const bool end) {
135 return (container == nullptr)
136 ? iterator{area, end ? static_cast<const Type *>(as_const)->cend() : static_cast<const Type *>(as_const)->cbegin()}
137 : iterator{area, end ? static_cast<Type *>(container)->end() : static_cast<Type *>(container)->begin()};
138 }
139
152 [[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) {
153 if constexpr(requires(Type elem, typename Type::const_iterator iter, Type::value_type instance) { elem.insert(iter, instance); }) {
154 auto *const non_const = any_cast<typename Type::iterator>(&it.base());
155 return {area, static_cast<Type *>(container)->insert(
156 non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()),
157 (value != nullptr) ? *static_cast<const Type::value_type *>(value) : *static_cast<const stl::remove_reference_t<typename Type::const_reference> *>(cref))};
158 } else {
159 return iterator{};
160 }
161 }
162
170 [[nodiscard]] static iterator erase([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const iterator &it) {
171 if constexpr(requires(Type elem, typename Type::const_iterator iter) { elem.erase(iter); }) {
172 auto *const non_const = any_cast<typename Type::iterator>(&it.base());
173 return {area, static_cast<Type *>(container)->erase(non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()))};
174 } else {
175 return iterator{};
176 }
177 }
178};
179
184template<cvref_unqualified Type>
190
192 static constexpr bool key_only = !requires { typename Type::mapped_type; };
193
199 [[nodiscard]] static size_type size(const void *container) {
200 return static_cast<const Type *>(container)->size();
201 }
202
208 [[nodiscard]] static bool clear(void *container) {
209 static_cast<Type *>(container)->clear();
210 return true;
211 }
212
219 [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
220 if constexpr(requires(Type elem) { elem.reserve(sz); }) {
221 static_cast<Type *>(container)->reserve(sz);
222 return true;
223 } else {
224 return false;
225 }
226 }
227
237 static iterator iter(const meta_ctx &area, void *container, const void *as_const, const bool end) {
238 return (container == nullptr)
239 ? iterator{area, stl::bool_constant<key_only>{}, end ? static_cast<const Type *>(as_const)->cend() : static_cast<const Type *>(as_const)->cbegin()}
240 : iterator{area, stl::bool_constant<key_only>{}, end ? static_cast<Type *>(container)->end() : static_cast<Type *>(container)->begin()};
241 }
242
250 [[nodiscard]] static bool insert(void *container, const void *key, [[maybe_unused]] const void *value) {
251 if constexpr(key_only) {
252 return static_cast<Type *>(container)->insert(*static_cast<const Type::key_type *>(key)).second;
253 } else {
254 return static_cast<Type *>(container)->emplace(*static_cast<const Type::key_type *>(key), *static_cast<const Type::mapped_type *>(value)).second;
255 }
256 }
257
264 [[nodiscard]] static size_type erase(void *container, const void *key) {
265 return static_cast<Type *>(container)->erase(*static_cast<const Type::key_type *>(key));
266 }
267
276 static iterator find(const meta_ctx &area, void *container, const void *as_const, const void *key) {
277 return (container != nullptr) ? iterator{area, stl::bool_constant<key_only>{}, static_cast<Type *>(container)->find(*static_cast<const Type::key_type *>(key))}
278 : iterator{area, stl::bool_constant<key_only>{}, static_cast<const Type *>(as_const)->find(*static_cast<const Type::key_type *>(key))};
279 }
280};
281
286template<internal::meta_sequence_container_like Type>
288
293template<internal::meta_associative_container_like Type>
295
296} // namespace entt
297
298#endif
stl::size_t size_type
Unsigned integer type.
Definition meta.hpp:114
meta_iterator iterator
Meta iterator type.
Definition meta.hpp:116
stl::size_t size_type
Unsigned integer type.
Definition meta.hpp:53
meta_iterator iterator
Meta iterator type.
Definition meta.hpp:55
EnTT default namespace.
Definition dense_map.hpp:25
stl::integral_constant< decltype(Value), Value > integral_constant
Wraps a static constant.
stl::remove_const_t< Type > any_cast(const basic_any< Len, Align > &data) noexcept
Performs type-safe access to the contained object.
Definition any.hpp:545
@ cref
Const aliasing mode, const reference.
Definition fwd.hpp:21
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.
meta_associative_container::size_type size_type
Unsigned integer 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.
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.
meta_associative_container::iterator iterator
Meta iterator type.
General purpose implementation of meta sequence container traits.
Definition container.hpp:63
static size_type size(const void *container)
Returns the number of elements in a container.
Definition container.hpp:77
meta_sequence_container::size_type size_type
Unsigned integer type.
Definition container.hpp:65
meta_sequence_container::iterator iterator
Meta iterator type.
Definition container.hpp:67
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 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 stl::size_t extent
Number of elements, or meta_dynamic_extent if dynamic.
Definition container.hpp:70
static bool clear(void *container)
Clears a container.
Definition container.hpp:86
Traits class template to be specialized to enable support for meta associative containers.
Opaque meta context type.
Definition context.hpp:30
Traits class template to be specialized to enable support for meta sequence containers.