3#ifndef ENTT_META_CONTAINER_HPP
4#define ENTT_META_CONTAINER_HPP
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"
16#include "type_traits.hpp"
23template<
typename Type>
26template<
typename Type>
27requires is_complete_v<stl::tuple_size<Type>>
28struct sequence_container_extent<Type>:
integral_constant<stl::tuple_size_v<Type>> {};
30template<
typename Type>
31inline constexpr stl::size_t sequence_container_extent_v = sequence_container_extent<Type>::value;
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(); };
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>());
62template<cvref_unqualified Type>
70 static constexpr stl::size_t
extent = internal::sequence_container_extent_v<Type>;
78 return static_cast<const Type *
>(container)->
size();
86 [[nodiscard]]
static bool clear([[maybe_unused]]
void *container) {
87 if constexpr(
requires(Type elem) { elem.clear(); }) {
88 static_cast<Type *
>(container)->
clear();
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);
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);
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()};
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); }) {
155 return {area,
static_cast<Type *
>(container)->
insert(
157 (value !=
nullptr) ? *
static_cast<const Type::value_type *
>(value) : *
static_cast<const stl::remove_reference_t<typename Type::const_reference> *
>(
cref))};
171 if constexpr(
requires(Type elem,
typename Type::const_iterator
iter) { elem.erase(
iter); }) {
184template<cvref_unqualified Type>
192 static constexpr bool key_only = !
requires {
typename Type::mapped_type; };
200 return static_cast<const Type *
>(container)->
size();
208 [[nodiscard]]
static bool clear(
void *container) {
209 static_cast<Type *
>(container)->
clear();
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);
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()};
250 [[nodiscard]]
static bool insert(
void *container,
const void *key, [[maybe_unused]]
const void *value) {
252 return static_cast<Type *
>(container)->
insert(*
static_cast<const Type::key_type *
>(key)).second;
254 return static_cast<Type *
>(container)->emplace(*
static_cast<const Type::key_type *
>(key), *
static_cast<const Type::mapped_type *
>(value)).second;
265 return static_cast<Type *
>(container)->
erase(*
static_cast<const Type::key_type *
>(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))};
286template<
internal::meta_sequence_container_like Type>
293template<
internal::meta_associative_container_like Type>
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.
@ cref
Const aliasing mode, const reference.