1#ifndef ENTT_META_CONTAINER_HPP
2#define ENTT_META_CONTAINER_HPP
11#include <unordered_map>
12#include <unordered_set>
14#include "../container/dense_map.hpp"
15#include "../container/dense_set.hpp"
18#include "type_traits.hpp"
25template<
typename,
typename =
void>
26struct fixed_size_sequence_container: std::true_type {};
28template<
typename Type>
29struct fixed_size_sequence_container<Type, std::void_t<decltype(&Type::clear)>>: std::false_type {};
31template<
typename Type>
32inline constexpr bool fixed_size_sequence_container_v = fixed_size_sequence_container<Type>::value;
34template<
typename,
typename =
void>
35struct key_only_associative_container: std::true_type {};
37template<
typename Type>
38struct key_only_associative_container<Type, std::void_t<typename Type::mapped_type>>: std::false_type {};
40template<
typename Type>
41inline constexpr bool key_only_associative_container_v = key_only_associative_container<Type>::value;
43template<
typename,
typename =
void>
44struct reserve_aware_container: std::false_type {};
46template<
typename Type>
47struct reserve_aware_container<Type, std::void_t<decltype(&Type::reserve)>>: std::true_type {};
49template<
typename Type>
50inline constexpr bool reserve_aware_container_v = reserve_aware_container<Type>::value;
59template<
typename Type>
61 static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>,
"Unexpected type");
64 static constexpr bool fixed_size = internal::fixed_size_sequence_container_v<Type>;
77 return static_cast<const Type *
>(container)->
size();
85 [[nodiscard]]
static bool clear([[maybe_unused]]
void *container) {
89 static_cast<Type *
>(container)->
clear();
100 [[nodiscard]]
static bool reserve([[maybe_unused]]
void *container, [[maybe_unused]]
const size_type sz) {
101 if constexpr(internal::reserve_aware_container_v<Type>) {
102 static_cast<Type *
>(container)->
reserve(sz);
115 [[nodiscard]]
static bool resize([[maybe_unused]]
void *container, [[maybe_unused]]
const size_type sz) {
116 if constexpr(
fixed_size || !std::is_default_constructible_v<typename Type::value_type>) {
119 static_cast<Type *
>(container)->
resize(sz);
132 return container ?
iterator{area,
static_cast<Type *
>(container)->
begin()}
133 :
iterator{area,
static_cast<const Type *
>(as_const)->
begin()};
144 return container ?
iterator{area,
static_cast<Type *
>(container)->
end()}
145 :
iterator{area,
static_cast<const Type *
>(as_const)->
end()};
160 [[nodiscard]]
static iterator insert(
const meta_ctx &area, [[maybe_unused]]
void *container, [[maybe_unused]]
const void *value, [[maybe_unused]]
const void *
cref, [[maybe_unused]]
const iterator &it) {
164 auto *
const non_const = any_cast<typename Type::iterator>(&it.base());
165 return {area,
static_cast<Type *
>(container)->
insert(
166 non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()),
167 value ? *
static_cast<const typename Type::value_type *
>(value) : *
static_cast<const std::remove_reference_t<typename Type::const_reference> *
>(
cref))};
182 auto *
const non_const = any_cast<typename Type::iterator>(&it.base());
183 return {area,
static_cast<Type *
>(container)->
erase(non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()))};
192template<
typename Type>
194 static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>,
"Unexpected type");
197 static constexpr bool key_only = internal::key_only_associative_container_v<Type>;
210 return static_cast<const Type *
>(container)->
size();
218 [[nodiscard]]
static bool clear(
void *container) {
219 static_cast<Type *
>(container)->
clear();
229 [[nodiscard]]
static bool reserve([[maybe_unused]]
void *container, [[maybe_unused]]
const size_type sz) {
230 if constexpr(internal::reserve_aware_container_v<Type>) {
231 static_cast<Type *
>(container)->
reserve(sz);
246 return container ?
iterator{area, std::bool_constant<key_only>{},
static_cast<Type *
>(container)->
begin()}
247 :
iterator{area, std::bool_constant<key_only>{},
static_cast<const Type *
>(as_const)->
begin()};
258 return container ?
iterator{area, std::bool_constant<key_only>{},
static_cast<Type *
>(container)->
end()}
259 :
iterator{area, std::bool_constant<key_only>{},
static_cast<const Type *
>(as_const)->
end()};
269 [[nodiscard]]
static bool insert(
void *container,
const void *key, [[maybe_unused]]
const void *value) {
271 return static_cast<Type *
>(container)->
insert(*
static_cast<const typename Type::key_type *
>(key)).second;
273 return static_cast<Type *
>(container)->emplace(*
static_cast<const typename Type::key_type *
>(key), *
static_cast<const typename Type::mapped_type *
>(value)).second;
284 return static_cast<Type *
>(container)->
erase(*
static_cast<const typename Type::key_type *
>(key));
296 return container ?
iterator{area, std::bool_constant<key_only>{},
static_cast<Type *
>(container)->
find(*
static_cast<const typename Type::key_type *
>(key))}
297 :
iterator{area, std::bool_constant<key_only>{},
static_cast<const Type *
>(as_const)->
find(*
static_cast<const typename Type::key_type *
>(key))};
305template<
typename... Args>
314template<
typename Type, auto N>
322template<
typename... Args>
330template<
typename... Args>
338template<
typename... Args>
347template<
typename... Args>
355template<
typename... Args>
364template<
typename... Args>
372template<
typename... Args>
380template<
typename... Args>
Associative container for key-value pairs with unique keys.
Associative container for unique objects of a given type.
@ cref
Const aliasing mode, the object points to a const element.