3#ifndef ENTT_META_CONTAINER_HPP
4#define ENTT_META_CONTAINER_HPP
13#include <unordered_map>
14#include <unordered_set>
16#include "../container/dense_map.hpp"
17#include "../container/dense_set.hpp"
20#include "type_traits.hpp"
27template<
typename,
typename =
void>
28struct fixed_size_sequence_container: std::true_type {};
30template<
typename Type>
31struct fixed_size_sequence_container<Type, std::void_t<decltype(&Type::clear)>>: std::false_type {};
33template<
typename Type>
34inline constexpr bool fixed_size_sequence_container_v = fixed_size_sequence_container<Type>::value;
36template<
typename,
typename =
void>
37struct key_only_associative_container: std::true_type {};
39template<
typename Type>
40struct key_only_associative_container<Type, std::void_t<typename Type::mapped_type>>: std::false_type {};
42template<
typename Type>
43inline constexpr bool key_only_associative_container_v = key_only_associative_container<Type>::value;
45template<
typename,
typename =
void>
46struct reserve_aware_container: std::false_type {};
48template<
typename Type>
49struct reserve_aware_container<Type, std::void_t<decltype(&Type::reserve)>>: std::true_type {};
51template<
typename Type>
52inline constexpr bool reserve_aware_container_v = reserve_aware_container<Type>::value;
61template<
typename Type>
63 static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>,
"Unexpected type");
71 static constexpr bool fixed_size = internal::fixed_size_sequence_container_v<Type>;
79 return static_cast<const Type *
>(container)->
size();
87 [[nodiscard]]
static bool clear([[maybe_unused]]
void *container) {
91 static_cast<Type *
>(container)->
clear();
102 [[nodiscard]]
static bool reserve([[maybe_unused]]
void *container, [[maybe_unused]]
const size_type sz) {
103 if constexpr(internal::reserve_aware_container_v<Type>) {
104 static_cast<Type *
>(container)->
reserve(sz);
117 [[nodiscard]]
static bool resize([[maybe_unused]]
void *container, [[maybe_unused]]
const size_type sz) {
118 if constexpr(
fixed_size || !std::is_default_constructible_v<typename Type::value_type>) {
121 static_cast<Type *
>(container)->
resize(sz);
134 return (container !=
nullptr) ?
iterator{area,
static_cast<Type *
>(container)->
begin()}
135 :
iterator{area,
static_cast<const Type *
>(as_const)->
begin()};
146 return (container !=
nullptr) ?
iterator{area,
static_cast<Type *
>(container)->
end()}
147 :
iterator{area,
static_cast<const Type *
>(as_const)->
end()};
162 [[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) {
167 return {area,
static_cast<Type *
>(container)->
insert(
169 (value !=
nullptr) ? *
static_cast<const typename Type::value_type *
>(value) : *
static_cast<const std::remove_reference_t<typename Type::const_reference> *
>(
cref))};
194template<
typename Type>
196 static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>,
"Unexpected type");
204 static constexpr bool key_only = internal::key_only_associative_container_v<Type>;
212 return static_cast<const Type *
>(container)->
size();
220 [[nodiscard]]
static bool clear(
void *container) {
221 static_cast<Type *
>(container)->
clear();
231 [[nodiscard]]
static bool reserve([[maybe_unused]]
void *container, [[maybe_unused]]
const size_type sz) {
232 if constexpr(internal::reserve_aware_container_v<Type>) {
233 static_cast<Type *
>(container)->
reserve(sz);
248 return (container !=
nullptr) ?
iterator{area, std::bool_constant<key_only>{},
static_cast<Type *
>(container)->
begin()}
249 :
iterator{area, std::bool_constant<key_only>{},
static_cast<const Type *
>(as_const)->
begin()};
260 return (container !=
nullptr) ?
iterator{area, std::bool_constant<key_only>{},
static_cast<Type *
>(container)->
end()}
261 :
iterator{area, std::bool_constant<key_only>{},
static_cast<const Type *
>(as_const)->
end()};
271 [[nodiscard]]
static bool insert(
void *container,
const void *key, [[maybe_unused]]
const void *value) {
273 return static_cast<Type *
>(container)->
insert(*
static_cast<const typename Type::key_type *
>(key)).second;
275 return static_cast<Type *
>(container)->emplace(*
static_cast<const typename Type::key_type *
>(key), *
static_cast<const typename Type::mapped_type *
>(value)).second;
286 return static_cast<Type *
>(container)->
erase(*
static_cast<const typename Type::key_type *
>(key));
298 return (container !=
nullptr) ?
iterator{area, std::bool_constant<key_only>{},
static_cast<Type *
>(container)->
find(*
static_cast<const typename Type::key_type *
>(key))}
299 :
iterator{area, std::bool_constant<key_only>{},
static_cast<const Type *
>(as_const)->
find(*
static_cast<const typename Type::key_type *
>(key))};
307template<
typename... Args>
316template<
typename Type, auto N>
324template<
typename... Args>
332template<
typename... Args>
340template<
typename... Args>
349template<
typename... Args>
357template<
typename... Args>
366template<
typename... Args>
374template<
typename... Args>
382template<
typename... Args>
Associative container for key-value pairs with unique keys.
Associative container for unique objects of a given type.
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, the object points to a const element.