EnTT 3.14.0
Loading...
Searching...
No Matches
meta.hpp
1#ifndef ENTT_META_META_HPP
2#define ENTT_META_META_HPP
3
4#include <array>
5#include <cstddef>
6#include <iterator>
7#include <memory>
8#include <type_traits>
9#include <utility>
10#include "../config/config.h"
11#include "../core/any.hpp"
12#include "../core/fwd.hpp"
13#include "../core/iterator.hpp"
14#include "../core/type_info.hpp"
15#include "../core/type_traits.hpp"
16#include "../core/utility.hpp"
17#include "../locator/locator.hpp"
18#include "adl_pointer.hpp"
19#include "context.hpp"
20#include "fwd.hpp"
21#include "node.hpp"
22#include "range.hpp"
23#include "type_traits.hpp"
24
25namespace entt {
26
27class meta_any;
28class meta_type;
29
32 class meta_iterator;
33
34public:
36 using size_type = std::size_t;
39
42
49
55 template<typename Type>
56 void rebind(Type &instance) noexcept {
57 value_type_node = &internal::resolve<typename Type::value_type>;
58 const_reference_node = &internal::resolve<std::remove_const_t<std::remove_reference_t<typename Type::const_reference>>>;
67 const_only = std::is_const_v<Type>;
68 data = &instance;
69 }
70
74 inline bool clear();
82
85 internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
86 internal::meta_type_node (*const_reference_node)(const internal::meta_context &){};
87 size_type (*size_fn)(const void *){};
88 bool (*clear_fn)(void *){};
89 bool (*reserve_fn)(void *, const size_type){};
90 bool (*resize_fn)(void *, const size_type){};
91 iterator (*begin_fn)(const meta_ctx &, void *, const void *){};
92 iterator (*end_fn)(const meta_ctx &, void *, const void *){};
93 iterator (*insert_fn)(const meta_ctx &, void *, const void *, const void *, const iterator &){};
94 iterator (*erase_fn)(const meta_ctx &, void *, const iterator &){};
95 const void *data{};
96 bool const_only{};
97};
98
101 class meta_iterator;
102
103public:
105 using size_type = std::size_t;
108
111
118
124 template<typename Type>
125 void rebind(Type &instance) noexcept {
126 key_type_node = &internal::resolve<typename Type::key_type>;
127 value_type_node = &internal::resolve<typename Type::value_type>;
128
130 mapped_type_node = &internal::resolve<typename Type::mapped_type>;
131 }
132
141 const_only = std::is_const_v<Type>;
142 data = &instance;
143 }
144
149 inline bool clear();
157
158private:
160 internal::meta_type_node (*key_type_node)(const internal::meta_context &){};
161 internal::meta_type_node (*mapped_type_node)(const internal::meta_context &){};
162 internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
163 size_type (*size_fn)(const void *){};
164 bool (*clear_fn)(void *){};
165 bool (*reserve_fn)(void *, const size_type){};
166 iterator (*begin_fn)(const meta_ctx &, void *, const void *){};
167 iterator (*end_fn)(const meta_ctx &, void *, const void *){};
168 bool (*insert_fn)(void *, const void *, const void *){};
169 size_type (*erase_fn)(void *, const void *){};
170 iterator (*find_fn)(const meta_ctx &, void *, const void *, const void *){};
171 const void *data{};
172 bool const_only{};
173};
174
177
179class meta_any {
180 using vtable_type = void(const internal::meta_traits op, const bool, const void *, void *);
181
182 template<typename Type>
183 static std::enable_if_t<std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, Type>> basic_vtable([[maybe_unused]] const internal::meta_traits req, [[maybe_unused]] const bool const_only, [[maybe_unused]] const void *value, [[maybe_unused]] void *other) {
184 if constexpr(is_meta_pointer_like_v<Type>) {
185 if(req == internal::meta_traits::is_meta_pointer_like) {
186 if constexpr(std::is_function_v<typename std::pointer_traits<Type>::element_type>) {
187 static_cast<meta_any *>(other)->emplace<Type>(*static_cast<const Type *>(value));
188 } else if constexpr(!std::is_void_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>>) {
189 using in_place_type = decltype(adl_meta_pointer_like<Type>::dereference(*static_cast<const Type *>(value)));
190
191 if constexpr(std::is_constructible_v<bool, Type>) {
192 if(const auto &pointer_like = *static_cast<const Type *>(value); pointer_like) {
194 }
195 } else {
196 static_cast<meta_any *>(other)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(*static_cast<const Type *>(value)));
197 }
198 }
199 }
200 }
201
203 if(req == internal::meta_traits::is_meta_sequence_container) {
204 const_only ? static_cast<meta_sequence_container *>(other)->rebind(*static_cast<const Type *>(value)) : static_cast<meta_sequence_container *>(other)->rebind(*static_cast<Type *>(const_cast<void *>(value)));
205 }
206 }
207
209 if(req == internal::meta_traits::is_meta_associative_container) {
210 const_only ? static_cast<meta_associative_container *>(other)->rebind(*static_cast<const Type *>(value)) : static_cast<meta_associative_container *>(other)->rebind(*static_cast<Type *>(const_cast<void *>(value)));
211 }
212 }
213 }
214
215 void release() {
216 if((node.dtor.dtor != nullptr) && (storage.policy() == any_policy::owner)) {
217 node.dtor.dtor(storage.data());
218 }
219 }
220
222 : storage{std::move(ref)},
223 ctx{other.ctx},
224 node{storage ? other.node : internal::meta_type_node{}},
225 vtable{storage ? other.vtable : &basic_vtable<void>} {}
226
227public:
229 meta_any() = default;
230
236 : ctx{&area} {}
237
244 template<typename Type, typename... Args>
245 explicit meta_any(std::in_place_type_t<Type>, Args &&...args)
246 : meta_any{locator<meta_ctx>::value_or(), std::in_place_type<Type>, std::forward<Args>(args)...} {}
247
255 template<typename Type, typename... Args>
256 explicit meta_any(const meta_ctx &area, std::in_place_type_t<Type>, Args &&...args)
257 : storage{std::in_place_type<Type>, std::forward<Args>(args)...},
258 ctx{&area},
259 node{internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx))},
260 vtable{&basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>} {}
261
267 template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
268 meta_any(Type &&value)
269 : meta_any{locator<meta_ctx>::value_or(), std::forward<Type>(value)} {}
270
277 template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
278 meta_any(const meta_ctx &area, Type &&value)
279 : meta_any{area, std::in_place_type<std::decay_t<Type>>, std::forward<Type>(value)} {}
280
288 ctx{&area},
289 node{(other.node.resolve != nullptr) ? other.node.resolve(internal::meta_context::from(*ctx)) : other.node},
290 vtable{other.vtable} {}
291
298 : storage{std::move(other.storage)},
299 ctx{&area},
300 node{(other.node.resolve != nullptr) ? std::exchange(other.node, internal::meta_type_node{}).resolve(internal::meta_context::from(*ctx)) : std::exchange(other.node, internal::meta_type_node{})},
301 vtable{std::exchange(other.vtable, &basic_vtable<void>)} {}
302
307 meta_any(const meta_any &other) = default;
308
314 : storage{std::move(other.storage)},
315 ctx{other.ctx},
316 node{std::exchange(other.node, internal::meta_type_node{})},
317 vtable{std::exchange(other.vtable, &basic_vtable<void>)} {}
318
321 release();
322 }
323
330 if(this != &other) {
331 release();
332 storage = other.storage;
333 ctx = other.ctx;
334 node = other.node;
335 vtable = other.vtable;
336 }
337
338 return *this;
339 }
340
347 ENTT_ASSERT(this != &other, "Self move assignment");
348
349 release();
350 storage = std::move(other.storage);
351 ctx = other.ctx;
352 node = std::exchange(other.node, internal::meta_type_node{});
353 vtable = std::exchange(other.vtable, &basic_vtable<void>);
354 return *this;
355 }
356
363 template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
364 meta_any &operator=(Type &&value) {
365 emplace<std::decay_t<Type>>(std::forward<Type>(value));
366 return *this;
367 }
368
371
374 return storage.data();
375 }
376
378 [[nodiscard]] void *data() noexcept {
379 return storage.data();
380 }
381
389 template<typename... Args>
390 meta_any invoke(id_type id, Args &&...args) const;
391
393 template<typename... Args>
394 meta_any invoke(id_type id, Args &&...args);
395
403 template<typename Type>
404 bool set(id_type id, Type &&value);
405
411 [[nodiscard]] meta_any get(id_type id) const;
412
415
421 template<typename Type>
422 [[nodiscard]] const Type *try_cast() const {
423 const auto other = internal::resolve<std::remove_cv_t<Type>>(internal::meta_context::from(*ctx));
424 return static_cast<const Type *>(internal::try_cast(internal::meta_context::from(*ctx), node, other, data()));
425 }
426
428 template<typename Type>
429 [[nodiscard]] Type *try_cast() {
430 if constexpr(std::is_const_v<Type>) {
431 return std::as_const(*this).try_cast<std::remove_const_t<Type>>();
432 } else {
433 const auto other = internal::resolve<std::remove_cv_t<Type>>(internal::meta_context::from(*ctx));
434 return static_cast<Type *>(const_cast<void *>(internal::try_cast(internal::meta_context::from(*ctx), node, other, data())));
435 }
436 }
437
443 template<typename Type>
444 [[nodiscard]] std::remove_const_t<Type> cast() const {
445 auto *const instance = try_cast<std::remove_reference_t<Type>>();
446 ENTT_ASSERT(instance, "Invalid instance");
447 return static_cast<Type>(*instance);
448 }
449
451 template<typename Type>
452 [[nodiscard]] std::remove_const_t<Type> cast() {
453 // forces const on non-reference types to make them work also with wrappers for const references
454 auto *const instance = try_cast<std::remove_reference_t<const Type>>();
455 ENTT_ASSERT(instance, "Invalid instance");
456 return static_cast<Type>(*instance);
457 }
458
465 [[nodiscard]] meta_any allow_cast(const meta_type &type) const;
466
473 if(auto other = std::as_const(*this).allow_cast(type); other) {
474 if((other.storage.policy() == any_policy::owner)) {
475 std::swap(*this, other);
476 }
477
478 return true;
479 }
480
481 return false;
482 }
483
490 template<typename Type>
492 if constexpr(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) {
493 return meta_any{meta_ctx_arg, *ctx};
494 } else {
495 auto other = internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx));
496 return allow_cast(meta_type{*ctx, other});
497 }
498 }
499
505 template<typename Type>
507 auto other = internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx));
508 return allow_cast(meta_type{*ctx, other}) && (!(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) || storage.data() != nullptr);
509 }
510
512 template<typename Type, typename... Args>
513 void emplace(Args &&...args) {
514 release();
515 storage.emplace<Type>(std::forward<Args>(args)...);
516 node = internal::resolve<std::remove_cv_t<std::remove_reference_t<Type>>>(internal::meta_context::from(*ctx));
518 }
519
521 bool assign(const meta_any &other);
522
524 bool assign(meta_any &&other);
525
527 void reset() {
528 release();
529 storage.reset();
530 node = {};
531 vtable = &basic_vtable<void>;
532 }
533
540 vtable(internal::meta_traits::is_meta_sequence_container, policy() == meta_any_policy::cref, std::as_const(*this).data(), &proxy);
541 return proxy;
542 }
543
547 vtable(internal::meta_traits::is_meta_sequence_container, true, data(), &proxy);
548 return proxy;
549 }
550
557 vtable(internal::meta_traits::is_meta_associative_container, policy() == meta_any_policy::cref, std::as_const(*this).data(), &proxy);
558 return proxy;
559 }
560
564 vtable(internal::meta_traits::is_meta_associative_container, true, data(), &proxy);
565 return proxy;
566 }
567
574 meta_any ret{meta_ctx_arg, *ctx};
575 vtable(internal::meta_traits::is_meta_pointer_like, true, storage.data(), &ret);
576 return ret;
577 }
578
583 [[nodiscard]] explicit operator bool() const noexcept {
584 return !(node.info == nullptr);
585 }
586
588 [[nodiscard]] bool operator==(const meta_any &other) const noexcept {
589 return (ctx == other.ctx) && (((node.info == nullptr) && (other.node.info == nullptr)) || ((node.info != nullptr) && (other.node.info != nullptr) && *node.info == *other.node.info && storage == other.storage));
590 }
591
593 [[nodiscard]] bool operator!=(const meta_any &other) const noexcept {
594 return !(*this == other);
595 }
596
599 return meta_any{*this, storage.as_ref()};
600 }
601
604 return meta_any{*this, storage.as_ref()};
605 }
606
614
615private:
616 any storage{};
617 const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
618 internal::meta_type_node node{};
619 vtable_type *vtable{&basic_vtable<void>};
620};
621
629template<typename Type>
630[[nodiscard]] meta_any forward_as_meta(const meta_ctx &ctx, Type &&value) {
631 return meta_any{ctx, std::in_place_type<Type &&>, std::forward<Type>(value)};
632}
633
640template<typename Type>
642 return forward_as_meta(locator<meta_ctx>::value_or(), std::forward<Type>(value));
643}
644
653 meta_handle() = default;
654
661
667 : any{value.as_ref()} {}
668
673 meta_handle(const meta_any &value)
674 : any{value.as_ref()} {}
675
682 template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_handle>>>
683 meta_handle(const meta_ctx &ctx, Type &value)
684 : any{ctx, std::in_place_type<Type &>, value} {}
685
691 template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_handle>>>
692 meta_handle(Type &value)
693 : meta_handle{locator<meta_ctx>::value_or(), value} {}
694
702
710
712 meta_handle(const meta_handle &) = delete;
713
716
718 ~meta_handle() = default;
719
725
731
736 [[nodiscard]] explicit operator bool() const noexcept {
737 return static_cast<bool>(any);
738 }
739
741 [[nodiscard]] bool operator==(const meta_handle &other) const noexcept {
742 return (any == other.any);
743 }
744
746 [[nodiscard]] bool operator!=(const meta_handle &other) const noexcept {
747 return !(*this == other);
748 }
749
755 return &any;
756 }
757
759 [[nodiscard]] const meta_any *operator->() const {
760 return &any;
761 }
762
763private:
765};
766
768struct meta_prop {
771
778 : node{std::move(curr)},
779 ctx{&area} {}
780
786 return node.value ? node.type(internal::meta_context::from(*ctx)).from_void(*ctx, nullptr, node.value.get()) : meta_any{meta_ctx_arg, *ctx};
787 }
788
794 return node.value ? node.type(internal::meta_context::from(*ctx)).from_void(*ctx, node.value.get(), nullptr) : meta_any{meta_ctx_arg, *ctx};
795 }
796
801 [[nodiscard]] explicit operator bool() const noexcept {
802 return static_cast<bool>(node.type);
803 }
804
810 [[nodiscard]] bool operator==(const meta_prop &other) const noexcept {
811 return (ctx == other.ctx && node.value == other.node.value);
812 }
813
814private:
815 internal::meta_prop_node node{};
816 const meta_ctx *ctx{};
817};
818
825[[nodiscard]] inline bool operator!=(const meta_prop &lhs, const meta_prop &rhs) noexcept {
826 return !(lhs == rhs);
827}
828
833
839 : node{std::move(curr)} {}
840
845 template<typename Type>
846 [[nodiscard]] operator Type *() const noexcept {
847 return (type_id<Type>().hash() == node.type) ? std::static_pointer_cast<Type>(node.value).get() : nullptr;
848 }
849
854 template<typename Type>
855 [[nodiscard]] operator Type &() const noexcept {
856 ENTT_ASSERT(type_id<Type>().hash() == node.type, "Invalid type");
857 return *std::static_pointer_cast<Type>(node.value);
858 }
859
860private:
861 internal::meta_custom_node node{};
862};
863
865struct meta_data {
867 using size_type = typename internal::meta_data_node::size_type;
868
871
878 : node{&curr},
879 ctx{&area} {}
880
886 return node->arity;
887 }
888
894 return static_cast<bool>(node->traits & internal::meta_traits::is_const);
895 }
896
902 return static_cast<bool>(node->traits & internal::meta_traits::is_static);
903 }
904
907
915 template<typename Type>
916 // NOLINTNEXTLINE(modernize-use-nodiscard)
917 bool set(meta_handle instance, Type &&value) const {
918 return node->set && node->set(meta_handle{*ctx, std::move(instance)}, meta_any{*ctx, std::forward<Type>(value)});
919 }
920
926 [[nodiscard]] meta_any get(meta_handle instance) const {
927 return node->get(*ctx, meta_handle{*ctx, std::move(instance)});
928 }
929
935 [[nodiscard]] inline meta_type arg(size_type index) const noexcept;
936
941 [[nodiscard]] [[deprecated("use ::custom() instead")]] meta_range<meta_prop, typename decltype(internal::meta_data_node::prop)::const_iterator> prop() const noexcept {
942 return {{*ctx, node->prop.cbegin()}, {*ctx, node->prop.cend()}};
943 }
944
950 [[nodiscard]] [[deprecated("use ::custom() instead")]] meta_prop prop(const id_type key) const {
951 for(auto &&elem: node->prop) {
952 if(elem.id == key) {
953 return meta_prop{*ctx, elem};
954 }
955 }
956
957 return meta_prop{};
958 }
959
965 template<typename Type>
967 return internal::meta_to_user_traits<Type>(node->traits);
968 }
969
975 return {node->custom};
976 }
977
982 [[nodiscard]] explicit operator bool() const noexcept {
983 return (node != nullptr);
984 }
985
987 [[nodiscard]] bool operator==(const meta_data &other) const noexcept {
988 return (ctx == other.ctx && node == other.node);
989 }
990
991private:
992 const internal::meta_data_node *node{};
993 const meta_ctx *ctx{};
994};
995
1002[[nodiscard]] inline bool operator!=(const meta_data &lhs, const meta_data &rhs) noexcept {
1003 return !(lhs == rhs);
1004}
1005
1009 using size_type = typename internal::meta_func_node::size_type;
1010
1013
1020 : node{&curr},
1021 ctx{&area} {}
1022
1028 return node->arity;
1029 }
1030
1036 return static_cast<bool>(node->traits & internal::meta_traits::is_const);
1037 }
1038
1044 return static_cast<bool>(node->traits & internal::meta_traits::is_static);
1045 }
1046
1051 [[nodiscard]] inline meta_type ret() const noexcept;
1052
1059
1068 return sz == arity() ? node->invoke(*ctx, meta_handle{*ctx, std::move(instance)}, args) : meta_any{meta_ctx_arg, *ctx};
1069 }
1070
1078 template<typename... Args>
1079 // NOLINTNEXTLINE(modernize-use-nodiscard)
1080 meta_any invoke(meta_handle instance, Args &&...args) const {
1081 std::array<meta_any, sizeof...(Args)> arguments{meta_any{*ctx, std::forward<Args>(args)}...};
1082 return invoke(std::move(instance), arguments.data(), sizeof...(Args));
1083 }
1084
1086 [[nodiscard]] [[deprecated("use ::custom() instead")]] meta_range<meta_prop, typename decltype(internal::meta_func_node::prop)::const_iterator> prop() const noexcept {
1087 return {{*ctx, node->prop.cbegin()}, {*ctx, node->prop.cend()}};
1088 }
1089
1095 [[nodiscard]] [[deprecated("use ::custom() instead")]] meta_prop prop(const id_type key) const {
1096 for(auto &&elem: node->prop) {
1097 if(elem.id == key) {
1098 return meta_prop{*ctx, elem};
1099 }
1100 }
1101
1102 return meta_prop{};
1103 }
1104
1106 template<typename Type>
1108 return internal::meta_to_user_traits<Type>(node->traits);
1109 }
1110
1113 return {node->custom};
1114 }
1115
1121 return node->next ? meta_func{*ctx, *node->next} : meta_func{};
1122 }
1123
1128 [[nodiscard]] explicit operator bool() const noexcept {
1129 return (node != nullptr);
1130 }
1131
1133 [[nodiscard]] bool operator==(const meta_func &other) const noexcept {
1134 return (ctx == other.ctx && node == other.node);
1135 }
1136
1137private:
1138 const internal::meta_func_node *node{};
1139 const meta_ctx *ctx{};
1140};
1141
1148[[nodiscard]] inline bool operator!=(const meta_func &lhs, const meta_func &rhs) noexcept {
1149 return !(lhs == rhs);
1150}
1151
1154 template<typename Func>
1155 [[nodiscard]] auto lookup(meta_any *const args, const typename internal::meta_type_node::size_type sz, [[maybe_unused]] bool constness, Func next) const {
1156 decltype(next()) candidate = nullptr;
1157 size_type same{};
1158 bool ambiguous{};
1159
1160 for(auto curr = next(); curr; curr = next()) {
1161 if constexpr(std::is_same_v<std::decay_t<decltype(*curr)>, internal::meta_func_node>) {
1162 if(constness && !static_cast<bool>(curr->traits & internal::meta_traits::is_const)) {
1163 continue;
1164 }
1165 }
1166
1167 if(curr->arity == sz) {
1168 size_type match{};
1169 size_type pos{};
1170
1171 // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span)
1172 for(; pos < sz && args[pos]; ++pos) {
1173 const auto other = curr->arg(*ctx, pos);
1174 const auto type = args[pos].type();
1175
1176 if(const auto &info = other.info(); info == type.info()) {
1177 ++match;
1178 } else if(!(type.node.conversion_helper && other.node.conversion_helper) && !(type.node.details && (internal::find_member<&internal::meta_base_node::type>(type.node.details->base, info.hash()) || internal::find_member<&internal::meta_conv_node::type>(type.node.details->conv, info.hash())))) {
1179 break;
1180 }
1181 }
1182 // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1183
1184 if(pos == sz) {
1185 if(!candidate || match > same) {
1186 candidate = curr;
1187 same = match;
1188 ambiguous = false;
1189 } else if(match == same) {
1190 if constexpr(std::is_same_v<std::decay_t<decltype(*curr)>, internal::meta_func_node>) {
1191 if(static_cast<bool>(curr->traits & internal::meta_traits::is_const) != static_cast<bool>(candidate->traits & internal::meta_traits::is_const)) {
1192 candidate = static_cast<bool>(candidate->traits & internal::meta_traits::is_const) ? curr : candidate;
1193 ambiguous = false;
1194 continue;
1195 }
1196 }
1197
1198 ambiguous = true;
1199 }
1200 }
1201 }
1202 }
1203
1204 return ambiguous ? nullptr : candidate;
1205 }
1206
1207public:
1209 using size_type = typename internal::meta_type_node::size_type;
1210
1213
1220 : node{std::move(curr)},
1221 ctx{&area} {}
1222
1228 meta_type(const meta_ctx &area, const internal::meta_base_node &curr) noexcept
1229 : meta_type{area, curr.resolve(internal::meta_context::from(area))} {}
1230
1236 return *node.info;
1237 }
1238
1244 return node.id;
1245 }
1246
1252 return node.size_of;
1253 }
1254
1261 return static_cast<bool>(node.traits & internal::meta_traits::is_arithmetic);
1262 }
1263
1269 return static_cast<bool>(node.traits & internal::meta_traits::is_integral);
1270 }
1271
1277 return static_cast<bool>(node.traits & internal::meta_traits::is_signed);
1278 }
1279
1285 return static_cast<bool>(node.traits & internal::meta_traits::is_array);
1286 }
1287
1293 return static_cast<bool>(node.traits & internal::meta_traits::is_enum);
1294 }
1295
1301 return static_cast<bool>(node.traits & internal::meta_traits::is_class);
1302 }
1303
1309 return static_cast<bool>(node.traits & internal::meta_traits::is_pointer);
1310 }
1311
1318 return {*ctx, node.remove_pointer(internal::meta_context::from(*ctx))};
1319 }
1320
1326 return static_cast<bool>(node.traits & internal::meta_traits::is_meta_pointer_like);
1327 }
1328
1334 return static_cast<bool>(node.traits & internal::meta_traits::is_meta_sequence_container);
1335 }
1336
1342 return static_cast<bool>(node.traits & internal::meta_traits::is_meta_associative_container);
1343 }
1344
1352 return (node.templ.arity != 0u);
1353 }
1354
1360 return node.templ.arity;
1361 }
1362
1368 return (node.templ.resolve != nullptr) ? meta_type{*ctx, node.templ.resolve(internal::meta_context::from(*ctx))} : meta_type{};
1369 }
1370
1376 [[nodiscard]] inline meta_type template_arg(const size_type index) const noexcept {
1377 return index < template_arity() ? meta_type{*ctx, node.templ.arg(internal::meta_context::from(*ctx), index)} : meta_type{};
1378 }
1379
1385 [[nodiscard]] bool can_cast(const meta_type &other) const noexcept {
1386 // casting this is UB in all cases but we aren't going to use the resulting pointer, so...
1387 return (internal::try_cast(internal::meta_context::from(*ctx), node, other.node, this) != nullptr);
1388 }
1389
1395 [[nodiscard]] bool can_convert(const meta_type &other) const noexcept {
1396 return (internal::try_convert(internal::meta_context::from(*ctx), node, other.info(), other.is_arithmetic() || other.is_enum(), nullptr, [](const void *, auto &&...args) { return ((static_cast<void>(args), 1) + ... + 0u); }) != 0u);
1397 }
1398
1403 [[nodiscard]] meta_range<meta_type, typename decltype(internal::meta_type_descriptor::base)::const_iterator> base() const noexcept {
1404 using range_type = meta_range<meta_type, typename decltype(internal::meta_type_descriptor::base)::const_iterator>;
1405 return node.details ? range_type{{*ctx, node.details->base.cbegin()}, {*ctx, node.details->base.cend()}} : range_type{};
1406 }
1407
1412 [[nodiscard]] meta_range<meta_data, typename decltype(internal::meta_type_descriptor::data)::const_iterator> data() const noexcept {
1413 using range_type = meta_range<meta_data, typename decltype(internal::meta_type_descriptor::data)::const_iterator>;
1414 return node.details ? range_type{{*ctx, node.details->data.cbegin()}, {*ctx, node.details->data.cend()}} : range_type{};
1415 }
1416
1422 [[nodiscard]] meta_data data(const id_type id) const {
1423 const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), node, id);
1424 return (elem != nullptr) ? meta_data{*ctx, *elem} : meta_data{};
1425 }
1426
1431 [[nodiscard]] meta_range<meta_func, typename decltype(internal::meta_type_descriptor::func)::const_iterator> func() const noexcept {
1432 using return_type = meta_range<meta_func, typename decltype(internal::meta_type_descriptor::func)::const_iterator>;
1433 return node.details ? return_type{{*ctx, node.details->func.cbegin()}, {*ctx, node.details->func.cend()}} : return_type{};
1434 }
1435
1444 [[nodiscard]] meta_func func(const id_type id) const {
1445 const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), node, id);
1446 return (elem != nullptr) ? meta_func{*ctx, *elem} : meta_func{};
1447 }
1448
1456 if(node.details) {
1457 if(const auto *candidate = lookup(args, sz, false, [first = node.details->ctor.cbegin(), last = node.details->ctor.cend()]() mutable { return first == last ? nullptr : &*(first++); }); candidate) {
1458 return candidate->invoke(*ctx, args);
1459 }
1460 }
1461
1462 if(sz == 0u && (node.default_constructor != nullptr)) {
1463 return node.default_constructor(*ctx);
1464 }
1465
1466 return meta_any{meta_ctx_arg, *ctx};
1467 }
1468
1475 template<typename... Args>
1477 std::array<meta_any, sizeof...(Args)> arguments{meta_any{*ctx, std::forward<Args>(args)}...};
1478 return construct(arguments.data(), sizeof...(Args));
1479 }
1480
1487 return ((elem != nullptr) && (node.from_void != nullptr)) ? node.from_void(*ctx, elem, nullptr) : meta_any{meta_ctx_arg, *ctx};
1488 }
1489
1491 [[nodiscard]] meta_any from_void(const void *elem) const {
1492 return ((elem != nullptr) && (node.from_void != nullptr)) ? node.from_void(*ctx, nullptr, elem) : meta_any{meta_ctx_arg, *ctx};
1493 }
1494
1503 meta_any invoke(const id_type id, meta_handle instance, meta_any *const args, const size_type sz) const {
1504 if(node.details) {
1505 if(auto *elem = internal::find_member<&internal::meta_func_node::id>(node.details->func, id); elem != nullptr) {
1506 if(const auto *candidate = lookup(args, sz, instance && (instance->data() == nullptr), [curr = elem]() mutable { return (curr != nullptr) ? std::exchange(curr, curr->next.get()) : nullptr; }); candidate) {
1507 return candidate->invoke(*ctx, meta_handle{*ctx, std::move(instance)}, args);
1508 }
1509 }
1510 }
1511
1512 for(auto &&curr: base()) {
1513 if(auto elem = curr.second.invoke(id, *instance.operator->(), args, sz); elem) {
1514 return elem;
1515 }
1516 }
1517
1518 return meta_any{meta_ctx_arg, *ctx};
1519 }
1520
1529 template<typename... Args>
1530 // NOLINTNEXTLINE(modernize-use-nodiscard)
1531 meta_any invoke(const id_type id, meta_handle instance, Args &&...args) const {
1532 std::array<meta_any, sizeof...(Args)> arguments{meta_any{*ctx, std::forward<Args>(args)}...};
1533 return invoke(id, std::move(instance), arguments.data(), sizeof...(Args));
1534 }
1535
1544 template<typename Type>
1545 bool set(const id_type id, meta_handle instance, Type &&value) const {
1546 const auto candidate = data(id);
1547 return candidate && candidate.set(std::move(instance), std::forward<Type>(value));
1548 }
1549
1556 [[nodiscard]] meta_any get(const id_type id, meta_handle instance) const {
1557 const auto candidate = data(id);
1558 return candidate ? candidate.get(std::move(instance)) : meta_any{meta_ctx_arg, *ctx};
1559 }
1560
1565 [[nodiscard]] [[deprecated("use ::custom() instead")]] meta_range<meta_prop, typename decltype(internal::meta_type_descriptor::prop)::const_iterator> prop() const noexcept {
1566 using range_type = meta_range<meta_prop, typename decltype(internal::meta_type_descriptor::prop)::const_iterator>;
1567 return node.details ? range_type{{*ctx, node.details->prop.cbegin()}, {*ctx, node.details->prop.cend()}} : range_type{};
1568 }
1569
1575 [[nodiscard]] [[deprecated("use ::custom() instead")]] meta_prop prop(const id_type key) const {
1576 const auto *elem = internal::look_for<&internal::meta_type_descriptor::prop>(internal::meta_context::from(*ctx), node, key);
1577 return (elem != nullptr) ? meta_prop{*ctx, *elem} : meta_prop{};
1578 }
1579
1581 template<typename Type>
1583 return internal::meta_to_user_traits<Type>(node.traits);
1584 }
1585
1588 return {node.custom};
1589 }
1590
1595 [[nodiscard]] explicit operator bool() const noexcept {
1596 return !(ctx == nullptr);
1597 }
1598
1600 [[nodiscard]] bool operator==(const meta_type &other) const noexcept {
1601 return (ctx == other.ctx) && (((node.info == nullptr) && (other.node.info == nullptr)) || ((node.info != nullptr) && (other.node.info != nullptr) && *node.info == *other.node.info));
1602 }
1603
1604private:
1605 internal::meta_type_node node{};
1606 const meta_ctx *ctx{};
1607};
1608
1615[[nodiscard]] inline bool operator!=(const meta_type &lhs, const meta_type &rhs) noexcept {
1616 return !(lhs == rhs);
1617}
1618
1620 return (node.info != nullptr) ? meta_type{*ctx, node} : meta_type{};
1621}
1622
1623template<typename... Args>
1624// NOLINTNEXTLINE(modernize-use-nodiscard)
1626 return type().invoke(id, *this, std::forward<Args>(args)...);
1627}
1628
1629template<typename... Args>
1631 return type().invoke(id, *this, std::forward<Args>(args)...);
1632}
1633
1634template<typename Type>
1635bool meta_any::set(const id_type id, Type &&value) {
1636 return type().set(id, *this, std::forward<Type>(value));
1637}
1638
1639[[nodiscard]] inline meta_any meta_any::get(const id_type id) const {
1640 return type().get(id, *this);
1641}
1642
1644 return type().get(id, *this);
1645}
1646
1647[[nodiscard]] inline meta_any meta_any::allow_cast(const meta_type &type) const {
1648 return internal::try_convert(internal::meta_context::from(*ctx), node, type.info(), type.is_arithmetic() || type.is_enum(), data(), [this, &type]([[maybe_unused]] const void *instance, auto &&...args) {
1649 if constexpr((std::is_same_v<std::remove_const_t<std::remove_reference_t<decltype(args)>>, internal::meta_type_node> || ...)) {
1650 return (args.from_void(*ctx, nullptr, instance), ...);
1651 } else if constexpr((std::is_same_v<std::remove_const_t<std::remove_reference_t<decltype(args)>>, internal::meta_conv_node> || ...)) {
1652 return (args.conv(*ctx, instance), ...);
1653 } else if constexpr((std::is_same_v<std::remove_const_t<std::remove_reference_t<decltype(args)>>, decltype(internal::meta_type_node::conversion_helper)> || ...)) {
1654 // exploits the fact that arithmetic types and enums are also default constructible
1655 auto other = type.construct();
1656 const auto value = (args(nullptr, instance), ...);
1657 other.node.conversion_helper(other.data(), &value);
1658 return other;
1659 } else {
1660 // forwards to force a compile-time error in case of available arguments
1661 return meta_any{meta_ctx_arg, *ctx, std::forward<decltype(args)>(args)...};
1662 }
1663 });
1664}
1665
1666inline bool meta_any::assign(const meta_any &other) {
1667 auto value = other.allow_cast({*ctx, node});
1668 return value && storage.assign(value.storage);
1669}
1670
1672 if(*node.info == *other.node.info) {
1673 return storage.assign(std::move(other.storage));
1674 }
1675
1676 return assign(std::as_const(other));
1677}
1678
1680 return meta_type{*ctx, node->type(internal::meta_context::from(*ctx))};
1681}
1682
1683[[nodiscard]] inline meta_type meta_data::arg(const size_type index) const noexcept {
1684 return index < arity() ? node->arg(*ctx, index) : meta_type{};
1685}
1686
1688 return meta_type{*ctx, node->ret(internal::meta_context::from(*ctx))};
1689}
1690
1691[[nodiscard]] inline meta_type meta_func::arg(const size_type index) const noexcept {
1692 return index < arity() ? node->arg(*ctx, index) : meta_type{};
1693}
1694
1696class meta_sequence_container::meta_iterator final {
1697 using vtable_type = void(const void *, const std::ptrdiff_t, meta_any *);
1698
1699 template<typename It>
1700 static void basic_vtable(const void *value, const std::ptrdiff_t offset, meta_any *other) {
1701 const auto &it = *static_cast<const It *>(value);
1702 other ? other->emplace<decltype(*it)>(*it) : std::advance(const_cast<It &>(it), offset);
1703 }
1704
1705public:
1706 using value_type = meta_any;
1707 using pointer = input_iterator_pointer<value_type>;
1708 using reference = value_type;
1709 using difference_type = std::ptrdiff_t;
1710 using iterator_category = std::input_iterator_tag;
1711 using iterator_concept = std::bidirectional_iterator_tag;
1712
1713 meta_iterator() = default;
1714
1715 template<typename It>
1716 meta_iterator(const meta_ctx &area, It iter) noexcept
1717 : ctx{&area},
1718 vtable{&basic_vtable<It>},
1719 handle{iter} {}
1720
1721 meta_iterator &operator++() noexcept {
1722 vtable(handle.data(), 1, nullptr);
1723 return *this;
1724 }
1725
1726 meta_iterator operator++(int value) noexcept {
1727 meta_iterator orig = *this;
1728 vtable(handle.data(), ++value, nullptr);
1729 return orig;
1730 }
1731
1732 meta_iterator &operator--() noexcept {
1733 vtable(handle.data(), -1, nullptr);
1734 return *this;
1735 }
1736
1737 meta_iterator operator--(int value) noexcept {
1738 meta_iterator orig = *this;
1739 vtable(handle.data(), --value, nullptr);
1740 return orig;
1741 }
1742
1743 [[nodiscard]] reference operator*() const {
1744 reference other{meta_ctx_arg, *ctx};
1745 vtable(handle.data(), 0, &other);
1746 return other;
1747 }
1748
1749 [[nodiscard]] pointer operator->() const {
1750 return operator*();
1751 }
1752
1753 [[nodiscard]] explicit operator bool() const noexcept {
1754 return static_cast<bool>(handle);
1755 }
1756
1757 [[nodiscard]] bool operator==(const meta_iterator &other) const noexcept {
1758 return handle == other.handle;
1759 }
1760
1761 [[nodiscard]] bool operator!=(const meta_iterator &other) const noexcept {
1762 return !(*this == other);
1763 }
1764
1765 [[nodiscard]] const any &base() const noexcept {
1766 return handle;
1767 }
1768
1769private:
1770 const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
1771 vtable_type *vtable{};
1772 any handle{};
1773};
1774
1775class meta_associative_container::meta_iterator final {
1776 using vtable_type = void(const void *, std::pair<meta_any, meta_any> *);
1777
1778 template<bool KeyOnly, typename It>
1779 static void basic_vtable(const void *value, std::pair<meta_any, meta_any> *other) {
1780 if(const auto &it = *static_cast<const It *>(value); other) {
1781 if constexpr(KeyOnly) {
1782 other->first.emplace<decltype(*it)>(*it);
1783 } else {
1784 other->first.emplace<decltype((it->first))>(it->first);
1785 other->second.emplace<decltype((it->second))>(it->second);
1786 }
1787 } else {
1788 ++const_cast<It &>(it);
1789 }
1790 }
1791
1792public:
1793 using value_type = std::pair<meta_any, meta_any>;
1794 using pointer = input_iterator_pointer<value_type>;
1795 using reference = value_type;
1796 using difference_type = std::ptrdiff_t;
1797 using iterator_category = std::input_iterator_tag;
1798 using iterator_concept = std::forward_iterator_tag;
1799
1800 meta_iterator() = default;
1801
1802 template<bool KeyOnly, typename It>
1803 meta_iterator(const meta_ctx &area, std::bool_constant<KeyOnly>, It iter) noexcept
1804 : ctx{&area},
1805 vtable{&basic_vtable<KeyOnly, It>},
1806 handle{iter} {}
1807
1808 meta_iterator &operator++() noexcept {
1809 vtable(handle.data(), nullptr);
1810 return *this;
1811 }
1812
1813 meta_iterator operator++(int) noexcept {
1814 meta_iterator orig = *this;
1815 vtable(handle.data(), nullptr);
1816 return orig;
1817 }
1818
1819 [[nodiscard]] reference operator*() const {
1820 reference other{{meta_ctx_arg, *ctx}, {meta_ctx_arg, *ctx}};
1821 vtable(handle.data(), &other);
1822 return other;
1823 }
1824
1825 [[nodiscard]] pointer operator->() const {
1826 return operator*();
1827 }
1828
1829 [[nodiscard]] explicit operator bool() const noexcept {
1830 return static_cast<bool>(handle);
1831 }
1832
1833 [[nodiscard]] bool operator==(const meta_iterator &other) const noexcept {
1834 return handle == other.handle;
1835 }
1836
1837 [[nodiscard]] bool operator!=(const meta_iterator &other) const noexcept {
1838 return !(*this == other);
1839 }
1840
1841private:
1842 const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
1843 vtable_type *vtable{};
1844 any handle{};
1845};
1853 return (value_type_node != nullptr) ? meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} : meta_type{};
1854}
1855
1863
1870 return !const_only && resize_fn(const_cast<void *>(data), sz);
1871}
1872
1878 return !const_only && clear_fn(const_cast<void *>(data));
1879}
1880
1887 return !const_only && reserve_fn(const_cast<void *>(data), sz);
1888}
1889
1895 return begin_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data);
1896}
1897
1903 return end_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data);
1904}
1905
1913 // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
1914 if(const auto vtype = value_type_node(internal::meta_context::from(*ctx)); !const_only && (value.allow_cast({*ctx, vtype}) || value.allow_cast({*ctx, const_reference_node(internal::meta_context::from(*ctx))}))) {
1915 const bool is_value_type = (value.type().info() == *vtype.info);
1916 return insert_fn(*ctx, const_cast<void *>(data), is_value_type ? std::as_const(value).data() : nullptr, is_value_type ? nullptr : std::as_const(value).data(), it);
1917 }
1918
1919 return iterator{};
1920}
1921
1928 return const_only ? iterator{} : erase_fn(*ctx, const_cast<void *>(data), it);
1929}
1930
1937 auto it = begin();
1938 it.operator++(static_cast<int>(pos) - 1);
1939 return *it;
1940}
1941
1946[[nodiscard]] inline meta_sequence_container::operator bool() const noexcept {
1947 return (data != nullptr);
1948}
1949
1955 return (key_type_node != nullptr) ? meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))} : meta_type{};
1956}
1957
1963 return (mapped_type_node != nullptr) ? meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))} : meta_type{};
1964}
1965
1968 return (value_type_node != nullptr) ? meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} : meta_type{};
1969}
1970
1975
1978 return !const_only && clear_fn(const_cast<void *>(data));
1979}
1980
1983 return !const_only && reserve_fn(const_cast<void *>(data), sz);
1984}
1985
1988 return begin_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data);
1989}
1990
1993 return end_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data);
1994}
1995
2003 return !const_only && key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})
2004 && ((mapped_type_node == nullptr) || value.allow_cast(meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))}))
2005 && insert_fn(const_cast<void *>(data), std::as_const(key).data(), std::as_const(value).data());
2006}
2007
2014 return (!const_only && key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})) ? erase_fn(const_cast<void *>(data), std::as_const(key).data()) : 0u;
2015}
2016
2023 return key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))}) ? find_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data, std::as_const(key).data()) : iterator{};
2024}
2025
2030[[nodiscard]] inline meta_associative_container::operator bool() const noexcept {
2031 return (data != nullptr);
2032}
2033
2034} // namespace entt
2035
2036#endif
pointer data() const noexcept
Direct access to the internal packed array.
deletion_policy policy() const noexcept
Returns the deletion policy of a sparse set.
Storage implementation.
Definition storage.hpp:230
value_type & emplace(const entity_type entt, Args &&...args)
Assigns an entity to a storage and constructs its object.
Definition storage.hpp:675
Service locator, nothing more.
Definition locator.hpp:27
static Service & value_or(Args &&...args)
Returns a service if available or sets it from a fallback type.
Definition locator.hpp:88
Opaque wrapper for values of any type.
Definition meta.hpp:179
bool assign(const meta_any &other)
Assigns a value to the contained object without replacing it.
Definition meta.hpp:1666
meta_any & operator=(const meta_any &other)
Copy assignment operator.
Definition meta.hpp:329
meta_associative_container as_associative_container() noexcept
Returns an associative container proxy.
Definition meta.hpp:555
meta_type type() const noexcept
Returns the object type if any, type_id<void>() otherwise.
Definition meta.hpp:1619
meta_any(const meta_ctx &area, const meta_any &other)
Context aware copy constructor.
Definition meta.hpp:286
meta_any()=default
meta_any invoke(id_type id, Args &&...args) const
Invokes the underlying function, if possible.
Definition meta.hpp:1625
std::remove_const_t< Type > cast()
Tries to cast an instance to a given type.
Definition meta.hpp:452
meta_any(meta_any &&other) noexcept
Move constructor.
Definition meta.hpp:313
void * data() noexcept
Returns an opaque pointer to the contained instance.
Definition meta.hpp:378
meta_any(std::in_place_type_t< Type >, Args &&...args)
Constructs a wrapper by directly initializing the new object.
Definition meta.hpp:245
std::remove_const_t< Type > cast() const
Tries to cast an instance to a given type.
Definition meta.hpp:444
meta_any as_ref() noexcept
Aliasing constructor.
Definition meta.hpp:598
const Type * try_cast() const
Tries to cast an instance to a given type.
Definition meta.hpp:422
void emplace(Args &&...args)
Replaces the contained object by creating a new instance directly.
Definition meta.hpp:513
meta_any(const meta_ctx &area, meta_any &&other)
Context aware move constructor.
Definition meta.hpp:297
meta_sequence_container as_sequence_container() noexcept
Returns a sequence container proxy.
Definition meta.hpp:538
Type * try_cast()
Tries to cast an instance to a given type.
Definition meta.hpp:429
meta_associative_container as_associative_container() const noexcept
Returns an associative container proxy.
Definition meta.hpp:562
meta_any_policy policy() const noexcept
Returns the current mode of a meta any object.
Definition meta.hpp:611
meta_any(const meta_any &other)=default
Copy constructor.
meta_any operator*() const noexcept
Indirection operator for dereferencing opaque objects.
Definition meta.hpp:573
meta_any allow_cast(const meta_type &type) const
Converts an object in such a way that a given cast becomes viable.
Definition meta.hpp:1647
meta_any(const meta_ctx &area, Type &&value)
Constructs a wrapper from a given value.
Definition meta.hpp:278
meta_any(const meta_ctx &area, std::in_place_type_t< Type >, Args &&...args)
Constructs a wrapper by directly initializing the new object.
Definition meta.hpp:256
meta_any as_ref() const noexcept
Aliasing constructor.
Definition meta.hpp:603
meta_any allow_cast() const
Converts an object in such a way that a given cast becomes viable.
Definition meta.hpp:491
meta_any(meta_ctx_arg_t, const meta_ctx &area)
Context aware constructor.
Definition meta.hpp:235
meta_any(Type &&value)
Constructs a wrapper from a given value.
Definition meta.hpp:268
~meta_any()
Frees the internal storage, whatever it means.
Definition meta.hpp:320
void reset()
Destroys contained object.
Definition meta.hpp:527
meta_any & operator=(Type &&value)
Value assignment operator.
Definition meta.hpp:364
meta_sequence_container as_sequence_container() const noexcept
Returns a sequence container proxy.
Definition meta.hpp:545
bool operator==(const meta_any &other) const noexcept
Checks if two wrappers differ in their content.
Definition meta.hpp:588
const void * data() const noexcept
Returns an opaque pointer to the contained instance.
Definition meta.hpp:373
bool operator!=(const meta_any &other) const noexcept
Checks if two wrappers differ in their content.
Definition meta.hpp:593
bool set(id_type id, Type &&value)
Sets the value of a given variable.
Definition meta.hpp:1635
bool allow_cast()
Converts an object in such a way that a given cast becomes viable.
Definition meta.hpp:506
meta_any get(id_type id) const
Gets the value of a given variable.
Definition meta.hpp:1639
bool allow_cast(const meta_type &type)
Converts an object in such a way that a given cast becomes viable.
Definition meta.hpp:472
meta_any & operator=(meta_any &&other) noexcept
Move assignment operator.
Definition meta.hpp:346
Proxy object for associative containers.
Definition meta.hpp:100
meta_associative_container()=default
Default constructor.
meta_associative_container(const meta_ctx &area) noexcept
Context aware constructor.
Definition meta.hpp:116
size_type erase(meta_any)
Removes the specified element from a container.
Definition meta.hpp:2013
iterator find(meta_any)
Returns an iterator to the element with a given key, if any.
Definition meta.hpp:2022
bool insert(meta_any, meta_any)
Inserts a key-only or key/value element into a container.
Definition meta.hpp:2002
iterator end()
Returns an iterator that is past the last element of a container.
Definition meta.hpp:1992
bool reserve(size_type)
Reserves storage for at least the given number of elements.
Definition meta.hpp:1982
iterator begin()
Returns an iterator to the first element of a container.
Definition meta.hpp:1987
size_type size() const noexcept
Returns the size of a container.
Definition meta.hpp:1972
meta_type mapped_type() const noexcept
Returns the meta mapped type of a container.
Definition meta.hpp:1962
std::size_t size_type
Unsigned integer type.
Definition meta.hpp:105
meta_iterator iterator
Meta iterator type.
Definition meta.hpp:107
meta_type value_type() const noexcept
Returns the meta value type of a container.
Definition meta.hpp:1967
void rebind(Type &instance) noexcept
Rebinds a proxy object to an associative container type.
Definition meta.hpp:125
meta_type key_type() const noexcept
Returns the meta key type of a container.
Definition meta.hpp:1954
bool clear()
Clears the content of a container.
Definition meta.hpp:1977
Disambiguation tag for constructors and the like.
Definition context.hpp:28
Opaque meta context type.
Definition context.hpp:34
Proxy object for sequence containers.
Definition meta.hpp:31
bool reserve(size_type)
Reserves storage for at least the given number of elements.
Definition meta.hpp:1886
iterator insert(const iterator &, meta_any)
Inserts an element at a specified location of a container.
Definition meta.hpp:1912
meta_type value_type() const noexcept
Returns the meta value type of a container.
Definition meta.hpp:1852
meta_any operator[](size_type)
Returns a reference to the element at a given location of a container.
Definition meta.hpp:1936
meta_sequence_container()=default
Default constructor.
iterator end()
Returns an iterator that is past the last element of a container.
Definition meta.hpp:1902
void rebind(Type &instance) noexcept
Rebinds a proxy object to a sequence container type.
Definition meta.hpp:56
iterator erase(const iterator &)
Removes a given element from a container.
Definition meta.hpp:1927
meta_iterator iterator
Meta iterator type.
Definition meta.hpp:38
std::size_t size_type
Unsigned integer type.
Definition meta.hpp:36
meta_sequence_container(const meta_ctx &area) noexcept
Context aware constructor.
Definition meta.hpp:47
bool resize(size_type)
Resizes a container to contain a given number of elements.
Definition meta.hpp:1869
size_type size() const noexcept
Returns the size of a container.
Definition meta.hpp:1860
iterator begin()
Returns an iterator to the first element of a container.
Definition meta.hpp:1894
bool clear()
Clears the content of a container.
Definition meta.hpp:1877
Opaque wrapper for types.
Definition meta.hpp:1153
bool is_pointer() const noexcept
Checks whether a type refers to a pointer or not.
Definition meta.hpp:1308
bool is_arithmetic() const noexcept
Checks whether a type refers to an arithmetic type or not.
Definition meta.hpp:1260
meta_range< meta_func, typename decltype(internal::meta_type_descriptor::func)::const_iterator > func() const noexcept
Returns a range to visit registered top-level functions.
Definition meta.hpp:1431
meta_custom custom() const noexcept
Returns user defined data for a given meta object.
Definition meta.hpp:1587
id_type id() const noexcept
Returns the identifier assigned to a type.
Definition meta.hpp:1243
meta_func func(const id_type id) const
Lookup utility for meta functions (bases are also visited).
Definition meta.hpp:1444
meta_type remove_pointer() const noexcept
Provides the type for which the pointer is defined.
Definition meta.hpp:1317
meta_any construct(Args &&...args) const
Creates an instance of the underlying type, if possible.
Definition meta.hpp:1476
meta_type template_arg(const size_type index) const noexcept
Returns the type of the i-th template argument of a type.
Definition meta.hpp:1376
bool is_array() const noexcept
Checks whether a type refers to an array type or not.
Definition meta.hpp:1284
meta_range< meta_prop, typename decltype(internal::meta_type_descriptor::prop)::const_iterator > prop() const noexcept
Returns a range to visit registered top-level meta properties.
Definition meta.hpp:1565
meta_data data(const id_type id) const
Lookup utility for meta data (bases are also visited).
Definition meta.hpp:1422
bool is_class() const noexcept
Checks whether a type refers to a class or not.
Definition meta.hpp:1300
bool set(const id_type id, meta_handle instance, Type &&value) const
Sets the value of a given variable.
Definition meta.hpp:1545
typename internal::meta_type_node::size_type size_type
Unsigned integer type.
Definition meta.hpp:1209
meta_any from_void(void *elem) const
Wraps an opaque element of the underlying type.
Definition meta.hpp:1486
meta_any from_void(const void *elem) const
Wraps an opaque element of the underlying type.
Definition meta.hpp:1491
meta_range< meta_data, typename decltype(internal::meta_type_descriptor::data)::const_iterator > data() const noexcept
Returns a range to visit registered top-level meta data.
Definition meta.hpp:1412
meta_prop prop(const id_type key) const
Lookup utility for meta properties (bases are also visited).
Definition meta.hpp:1575
meta_any invoke(const id_type id, meta_handle instance, Args &&...args) const
Invokes a function given an identifier, if possible.
Definition meta.hpp:1531
bool can_convert(const meta_type &other) const noexcept
Checks if a type supports conversion it to another type.
Definition meta.hpp:1395
bool is_signed() const noexcept
Checks whether a type refers to a signed type or not.
Definition meta.hpp:1276
bool is_enum() const noexcept
Checks whether a type refers to an enum or not.
Definition meta.hpp:1292
bool can_cast(const meta_type &other) const noexcept
Checks if a type supports direct casting to another type.
Definition meta.hpp:1385
meta_type() noexcept=default
Default constructor.
bool operator==(const meta_type &other) const noexcept
Checks if two objects refer to the same type.
Definition meta.hpp:1600
meta_range< meta_type, typename decltype(internal::meta_type_descriptor::base)::const_iterator > base() const noexcept
Returns a range to visit registered top-level base meta types.
Definition meta.hpp:1403
bool is_pointer_like() const noexcept
Checks whether a type is a pointer-like type or not.
Definition meta.hpp:1325
meta_any get(const id_type id, meta_handle instance) const
Gets the value of a given variable.
Definition meta.hpp:1556
Type traits() const noexcept
Returns all meta traits for a given meta object.
Definition meta.hpp:1582
meta_any construct(meta_any *const args, const size_type sz) const
Creates an instance of the underlying type, if possible.
Definition meta.hpp:1455
bool is_integral() const noexcept
Checks whether a type refers to an integral type or not.
Definition meta.hpp:1268
meta_type template_type() const noexcept
Returns a tag for the class template of the underlying type.
Definition meta.hpp:1367
meta_type(const meta_ctx &area, const internal::meta_base_node &curr) noexcept
Context aware constructor for meta objects.
Definition meta.hpp:1228
const type_info & info() const noexcept
Returns the type info object of the underlying type.
Definition meta.hpp:1235
bool is_template_specialization() const noexcept
Checks whether a type refers to a recognized class template specialization or not.
Definition meta.hpp:1351
meta_any invoke(const id_type id, meta_handle instance, meta_any *const args, const size_type sz) const
Invokes a function given an identifier, if possible.
Definition meta.hpp:1503
bool is_associative_container() const noexcept
Checks whether a type refers to an associative container or not.
Definition meta.hpp:1341
size_type template_arity() const noexcept
Returns the number of template arguments.
Definition meta.hpp:1359
size_type size_of() const noexcept
Returns the size of the underlying type if known.
Definition meta.hpp:1251
bool is_sequence_container() const noexcept
Checks whether a type refers to a sequence container or not.
Definition meta.hpp:1333
EnTT default namespace.
Definition dense_map.hpp:22
constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args)
Uses-allocator construction utility (waiting for C++20).
Definition memory.hpp:219
basic_handle< registry > handle
Alias declaration for the most common use case.
Definition fwd.hpp:102
basic_any<> any
Alias declaration for the most common use case.
Definition fwd.hpp:17
std::uint32_t id_type
Alias declaration for type identifiers.
Definition fwd.hpp:14
constexpr get_t< Type... > get
Variable template for lists of observed elements.
Definition fwd.hpp:168
meta_type resolve() noexcept
Returns the meta type associated with a given type.
Definition resolve.hpp:32
constexpr meta_ctx_arg_t meta_ctx_arg
Constant of type meta_context_arg_t used to disambiguate calls.
Definition context.hpp:31
meta_any forward_as_meta(const meta_ctx &ctx, Type &&value)
Forwards its argument and avoids copies for lvalue references.
Definition meta.hpp:630
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
any_policy
Possible modes of an any object.
Definition any.hpp:33
@ ref
Aliasing mode, the object points to a non-const element.
@ cref
Const aliasing mode, the object points to a const element.
@ owner
Default mode, the object owns the contained element.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Fake ADL based lookup function for meta pointer-like types.
static decltype(auto) dereference(const Type &value)
Uses the default ADL based lookup method to resolve the call.
Utility class to create an iterable object from a pair of iterators.
Definition iterator.hpp:141
Traits class template to be specialized to enable support for meta associative containers.
Opaque wrapper for user defined data of any type.
Definition meta.hpp:830
meta_custom() noexcept=default
Default constructor.
Opaque wrapper for data members.
Definition meta.hpp:865
bool is_const() const noexcept
Indicates whether a data member is constant or not.
Definition meta.hpp:893
meta_type arg(size_type index) const noexcept
Returns the type accepted by the i-th setter.
Definition meta.hpp:1683
typename internal::meta_data_node::size_type size_type
Unsigned integer type.
Definition meta.hpp:867
meta_prop prop(const id_type key) const
Lookup utility for meta properties.
Definition meta.hpp:950
meta_any get(meta_handle instance) const
Gets the value of a given variable.
Definition meta.hpp:926
size_type arity() const noexcept
Returns the number of setters available.
Definition meta.hpp:885
meta_range< meta_prop, typename decltype(internal::meta_data_node::prop)::const_iterator > prop() const noexcept
Returns a range to visit registered meta properties.
Definition meta.hpp:941
bool operator==(const meta_data &other) const noexcept
Checks if two objects refer to the same type.
Definition meta.hpp:987
bool set(meta_handle instance, Type &&value) const
Sets the value of a given variable.
Definition meta.hpp:917
meta_custom custom() const noexcept
Returns user defined data for a given meta object.
Definition meta.hpp:974
meta_type type() const noexcept
Returns the object type if any, type_id<void>() otherwise.
Definition meta.hpp:1679
meta_data() noexcept=default
Default constructor.
bool is_static() const noexcept
Indicates whether a data member is static or not.
Definition meta.hpp:901
Type traits() const noexcept
Returns all meta traits for a given meta object.
Definition meta.hpp:966
Opaque wrapper for member functions.
Definition meta.hpp:1007
bool is_static() const noexcept
Indicates whether a member function is static or not.
Definition meta.hpp:1043
typename internal::meta_func_node::size_type size_type
Unsigned integer type.
Definition meta.hpp:1009
meta_func() noexcept=default
Default constructor.
meta_type ret() const noexcept
Returns the return type of a member function.
Definition meta.hpp:1687
bool operator==(const meta_func &other) const noexcept
Checks if two objects refer to the same type.
Definition meta.hpp:1133
meta_prop prop(const id_type key) const
Lookup utility for meta properties.
Definition meta.hpp:1095
meta_range< meta_prop, typename decltype(internal::meta_func_node::prop)::const_iterator > prop() const noexcept
Returns a range to visit registered meta properties.
Definition meta.hpp:1086
Type traits() const noexcept
Returns all meta traits for a given meta object.
Definition meta.hpp:1107
meta_any invoke(meta_handle instance, meta_any *const args, const size_type sz) const
Invokes the underlying function, if possible.
Definition meta.hpp:1067
bool is_const() const noexcept
Indicates whether a member function is constant or not.
Definition meta.hpp:1035
meta_any invoke(meta_handle instance, Args &&...args) const
Invokes the underlying function, if possible.
Definition meta.hpp:1080
meta_custom custom() const noexcept
Returns user defined data for a given meta object.
Definition meta.hpp:1112
meta_func next() const
Returns the next overload of a given function, if any.
Definition meta.hpp:1120
meta_type arg(size_type index) const noexcept
Returns the type of the i-th argument of a member function.
Definition meta.hpp:1691
size_type arity() const noexcept
Returns the number of arguments accepted by a member function.
Definition meta.hpp:1027
Opaque pointers to instances of any type.
Definition meta.hpp:651
bool operator!=(const meta_handle &other) const noexcept
Checks if two wrappers differ in their content.
Definition meta.hpp:746
meta_handle(const meta_any &value)
Creates a handle that points to an unmanaged object.
Definition meta.hpp:673
meta_handle & operator=(const meta_handle &)=delete
Default copy assignment operator, deleted on purpose.
meta_handle(const meta_ctx &ctx, Type &value)
Creates a handle that points to an unmanaged object.
Definition meta.hpp:683
~meta_handle()=default
Default destructor.
meta_handle()=default
meta_handle(const meta_ctx &area, const meta_handle &other)
Context aware copy constructor.
Definition meta.hpp:700
bool operator==(const meta_handle &other) const noexcept
Checks if two wrappers differ in their content.
Definition meta.hpp:741
meta_handle(meta_handle &&)=default
Default move constructor.
meta_handle(const meta_ctx &area, meta_handle &&other)
Context aware move constructor.
Definition meta.hpp:708
const meta_any * operator->() const
Access operator for accessing the contained opaque object.
Definition meta.hpp:759
meta_handle(const meta_handle &)=delete
Default copy constructor, deleted on purpose.
meta_handle(meta_ctx_arg_t, const meta_ctx &area)
Context aware constructor.
Definition meta.hpp:659
meta_handle(meta_any &value)
Creates a handle that points to an unmanaged object.
Definition meta.hpp:666
meta_handle(Type &value)
Creates a handle that points to an unmanaged object.
Definition meta.hpp:692
meta_handle & operator=(meta_handle &&)=default
Default move assignment operator.
meta_any * operator->()
Access operator for accessing the contained opaque object.
Definition meta.hpp:754
Opaque wrapper for properties of any type.
Definition meta.hpp:768
meta_any value()
Returns the stored value by reference.
Definition meta.hpp:793
meta_any value() const
Returns the stored value by const reference.
Definition meta.hpp:785
meta_prop() noexcept=default
Default constructor.
bool operator==(const meta_prop &other) const noexcept
Checks if two objects refer to the same type.
Definition meta.hpp:810
Traits class template to be specialized to enable support for meta sequence containers.
Implementation specific information about a type.
constexpr id_type hash() const noexcept
Type hash.