3#ifndef ENTT_META_CONTAINER_HPP
4#define ENTT_META_CONTAINER_HPP
14#include <unordered_map>
15#include <unordered_set>
17#include "../container/dense_map.hpp"
18#include "../container/dense_set.hpp"
19#include "../core/type_traits.hpp"
23#include "type_traits.hpp"
30template<
typename Type,
typename =
void>
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>> {};
36template<
typename Type>
37inline constexpr std::size_t sequence_container_extent_v = sequence_container_extent<Type>::value;
39template<
typename,
typename =
void>
40struct key_only_associative_container: std::true_type {};
42template<
typename Type>
43struct key_only_associative_container<Type, std::void_t<typename Type::mapped_type>>: std::false_type {};
45template<
typename Type>
46inline constexpr bool key_only_associative_container_v = key_only_associative_container<Type>::value;
48template<
typename,
typename =
void>
49struct reserve_aware_container: std::false_type {};
51template<
typename Type>
52struct reserve_aware_container<Type, std::void_t<decltype(&Type::reserve)>>: std::true_type {};
54template<
typename Type>
55inline constexpr bool reserve_aware_container_v = reserve_aware_container<Type>::value;
64template<
typename Type>
66 static_assert(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>,
"Unexpected type");
74 static constexpr std::size_t
extent = internal::sequence_container_extent_v<Type>;
84 return static_cast<const Type *
>(container)->
size();
92 [[nodiscard]]
static bool clear([[maybe_unused]]
void *container) {
94 static_cast<Type *
>(container)->
clear();
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);
122 [[nodiscard]]
static bool resize([[maybe_unused]]
void *container, [[maybe_unused]]
const size_type sz) {
124 static_cast<Type *
>(container)->
resize(sz);
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()};
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) {
161 return {area,
static_cast<Type *
>(container)->
insert(
163 (value !=
nullptr) ? *
static_cast<const typename Type::value_type *
>(value) : *
static_cast<const std::remove_reference_t<typename Type::const_reference> *
>(
cref))};
190template<
typename Type>
192 static_assert(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>,
"Unexpected type");
200 static constexpr bool key_only = internal::key_only_associative_container_v<Type>;
208 return static_cast<const Type *
>(container)->
size();
216 [[nodiscard]]
static bool clear(
void *container) {
217 static_cast<Type *
>(container)->
clear();
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);
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()};
258 [[nodiscard]]
static bool insert(
void *container,
const void *key, [[maybe_unused]]
const void *value) {
260 return static_cast<Type *
>(container)->
insert(*
static_cast<const typename Type::key_type *
>(key)).second;
262 return static_cast<Type *
>(container)->emplace(*
static_cast<const typename Type::key_type *
>(key), *
static_cast<const typename Type::mapped_type *
>(value)).second;
273 return static_cast<Type *
>(container)->
erase(*
static_cast<const typename Type::key_type *
>(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))};
294template<
typename... Args>
303template<
typename Type, auto N>
311template<
typename... Args>
319template<
typename... Args>
327template<
typename... Args>
336template<
typename... Args>
344template<
typename... Args>
353template<
typename... Args>
361template<
typename... Args>
369template<
typename... Args>
Associative container for key-value pairs with unique keys.
Associative container for unique objects of a given type.
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.
@ cref
Const aliasing mode, const reference.
constexpr std::size_t meta_dynamic_extent
Used to identicate that a sequence container has not a fixed size.