1 #ifndef ENTT_META_CONTAINER_HPP
2 #define ENTT_META_CONTAINER_HPP
8 #include <unordered_map>
9 #include <unordered_set>
11 #include "../container/dense_map.hpp"
12 #include "../container/dense_set.hpp"
14 #include "type_traits.hpp"
25 template<
typename,
typename =
void>
26 struct is_dynamic_sequence_container: std::false_type {};
28 template<
typename Type>
29 struct is_dynamic_sequence_container<Type, std::void_t<decltype(&Type::reserve)>>: std::true_type {};
31 template<
typename,
typename =
void>
32 struct is_key_only_meta_associative_container: std::true_type {};
34 template<
typename Type>
35 struct is_key_only_meta_associative_container<Type, std::void_t<typename Type::mapped_type>>: std::false_type {};
37 template<
typename Type>
38 struct basic_meta_sequence_container_traits {
40 using size_type = std::size_t;
42 [[nodiscard]]
static size_type size(
const any &container) ENTT_NOEXCEPT {
43 return any_cast<const Type &>(container).size();
46 [[nodiscard]]
static bool resize([[maybe_unused]]
any &container, [[maybe_unused]] size_type sz) {
47 if constexpr(is_dynamic_sequence_container<Type>::value) {
48 if(
auto *
const cont = any_cast<Type>(&container); cont) {
57 [[nodiscard]]
static iterator iter(
any &container,
const bool as_end) {
60 if(
auto *
const cont = any_cast<Type>(&container); cont) {
61 return iterator{begin(*cont),
static_cast<typename iterator::difference_type
>(as_end * cont->size())};
64 const Type &as_const = any_cast<const Type &>(container);
65 return iterator{begin(as_const),
static_cast<typename iterator::difference_type
>(as_end * as_const.size())};
68 [[nodiscard]]
static iterator insert([[maybe_unused]]
any &container, [[maybe_unused]]
const std::ptrdiff_t offset, [[maybe_unused]] meta_any &value) {
69 if constexpr(is_dynamic_sequence_container<Type>::value) {
70 if(
auto *
const cont = any_cast<Type>(&container); cont) {
72 if(value.allow_cast<
typename Type::const_reference>() || value.allow_cast<
typename Type::value_type>()) {
74 const auto *element = value.try_cast<std::remove_reference_t<typename Type::const_reference>>();
75 const auto curr = cont->insert(begin(*cont) + offset, element ? *element : value.cast<
typename Type::value_type>());
76 return iterator{curr, curr - begin(*cont)};
84 [[nodiscard]]
static iterator erase([[maybe_unused]]
any &container, [[maybe_unused]]
const std::ptrdiff_t offset) {
85 if constexpr(is_dynamic_sequence_container<Type>::value) {
86 if(
auto *
const cont = any_cast<Type>(&container); cont) {
88 const auto curr = cont->erase(begin(*cont) + offset);
89 return iterator{curr, curr - begin(*cont)};
97 template<
typename Type>
98 struct basic_meta_associative_container_traits {
100 using size_type = std::size_t;
102 static constexpr
auto key_only = is_key_only_meta_associative_container<Type>::value;
104 [[nodiscard]]
static size_type size(
const any &container) ENTT_NOEXCEPT {
105 return any_cast<const Type &>(container).size();
108 [[nodiscard]]
static bool clear(
any &container) {
109 if(
auto *
const cont = any_cast<Type>(&container); cont) {
117 [[nodiscard]]
static iterator iter(
any &container,
const bool as_end) {
121 if(
auto *
const cont = any_cast<Type>(&container); cont) {
122 return iterator{std::integral_constant<bool, key_only>{}, as_end ? end(*cont) : begin(*cont)};
125 const auto &as_const = any_cast<const Type &>(container);
126 return iterator{std::integral_constant<bool, key_only>{}, as_end ? end(as_const) : begin(as_const)};
129 [[nodiscard]]
static bool insert(
any &container, meta_any &key, [[maybe_unused]] meta_any &value) {
130 auto *
const cont = any_cast<Type>(&container);
132 if constexpr(is_key_only_meta_associative_container<Type>::value) {
133 return cont && key.allow_cast<
const typename Type::key_type &>()
134 && cont->insert(key.cast<
const typename Type::key_type &>()).second;
136 return cont && key.allow_cast<
const typename Type::key_type &>() && value.allow_cast<
const typename Type::mapped_type &>()
137 && cont->emplace(key.cast<
const typename Type::key_type &>(), value.cast<
const typename Type::mapped_type &>()).second;
141 [[nodiscard]]
static bool erase(
any &container, meta_any &key) {
142 auto *
const cont = any_cast<Type>(&container);
143 return cont && key.allow_cast<
const typename Type::key_type &>()
144 && (cont->erase(key.cast<
const typename Type::key_type &>()) != cont->size());
147 [[nodiscard]]
static iterator find(
any &container, meta_any &key) {
148 if(key.allow_cast<
const typename Type::key_type &>()) {
149 if(
auto *
const cont = any_cast<Type>(&container); cont) {
150 return iterator{std::integral_constant<bool, key_only>{}, cont->find(key.cast<
const typename Type::key_type &>())};
153 return iterator{std::integral_constant<bool, key_only>{}, any_cast<const Type &>(container).find(key.cast<
const typename Type::key_type &>())};
172 template<
typename Type,
typename... Args>
174 : internal::basic_meta_sequence_container_traits<std::vector<Type, Args...>> {};
181 template<
typename Type, auto N>
183 : internal::basic_meta_sequence_container_traits<std::array<Type, N>> {};
191 template<
typename Key,
typename Value,
typename... Args>
193 : internal::basic_meta_associative_container_traits<std::map<Key, Value, Args...>> {};
202 template<
typename Key,
typename Value,
typename... Args>
204 : internal::basic_meta_associative_container_traits<std::unordered_map<Key, Value, Args...>> {};
211 template<
typename Key,
typename... Args>
213 : internal::basic_meta_associative_container_traits<std::set<Key, Args...>> {};
221 template<
typename Key,
typename... Args>
223 : internal::basic_meta_associative_container_traits<std::unordered_set<Key, Args...>> {};
231 template<
typename Key,
typename Type,
typename... Args>
233 : internal::basic_meta_associative_container_traits<dense_map<Key, Type, Args...>> {};
240 template<
typename Type,
typename... Args>
242 : internal::basic_meta_associative_container_traits<dense_set<Type, Args...>> {};
Associative container for key-value pairs with unique keys.
Associative container for unique objects of a given type.
basic_any<> any
Alias declaration for the most common use case.