EnTT  3.10.0
meta.hpp
1 #ifndef ENTT_META_META_HPP
2 #define ENTT_META_META_HPP
3 
4 #include <cstddef>
5 #include <iterator>
6 #include <memory>
7 #include <type_traits>
8 #include <utility>
9 #include "../config/config.h"
10 #include "../core/any.hpp"
11 #include "../core/fwd.hpp"
12 #include "../core/iterator.hpp"
13 #include "../core/type_info.hpp"
14 #include "../core/type_traits.hpp"
15 #include "../core/utility.hpp"
16 #include "adl_pointer.hpp"
17 #include "ctx.hpp"
18 #include "fwd.hpp"
19 #include "node.hpp"
20 #include "range.hpp"
21 #include "type_traits.hpp"
22 
23 namespace entt {
24 
25 class meta_any;
26 class meta_type;
27 
30  class meta_iterator;
31 
32 public:
34  using size_type = std::size_t;
36  using iterator = meta_iterator;
37 
39  meta_sequence_container() ENTT_NOEXCEPT = default;
40 
46  template<typename Type>
47  meta_sequence_container(std::in_place_type_t<Type>, any instance) ENTT_NOEXCEPT
48  : value_type_node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::value_type>>>::resolve()},
50  resize_fn{&meta_sequence_container_traits<Type>::resize},
51  iter_fn{&meta_sequence_container_traits<Type>::iter},
52  insert_fn{&meta_sequence_container_traits<Type>::insert},
53  erase_fn{&meta_sequence_container_traits<Type>::erase},
54  storage{std::move(instance)} {}
55 
56  [[nodiscard]] inline meta_type value_type() const ENTT_NOEXCEPT;
57  [[nodiscard]] inline size_type size() const ENTT_NOEXCEPT;
58  inline bool resize(const size_type);
59  inline bool clear();
60  [[nodiscard]] inline iterator begin();
61  [[nodiscard]] inline iterator end();
62  inline iterator insert(iterator, meta_any);
63  inline iterator erase(iterator);
64  [[nodiscard]] inline meta_any operator[](const size_type);
65  [[nodiscard]] inline explicit operator bool() const ENTT_NOEXCEPT;
66 
67 private:
68  internal::meta_type_node *value_type_node = nullptr;
69  size_type (*size_fn)(const any &) ENTT_NOEXCEPT = nullptr;
70  bool (*resize_fn)(any &, size_type) = nullptr;
71  iterator (*iter_fn)(any &, const bool) = nullptr;
72  iterator (*insert_fn)(any &, const std::ptrdiff_t, meta_any &) = nullptr;
73  iterator (*erase_fn)(any &, const std::ptrdiff_t) = nullptr;
74  any storage{};
75 };
76 
79  class meta_iterator;
80 
81 public:
83  using size_type = std::size_t;
85  using iterator = meta_iterator;
86 
88  meta_associative_container() ENTT_NOEXCEPT = default;
89 
95  template<typename Type>
96  meta_associative_container(std::in_place_type_t<Type>, any instance) ENTT_NOEXCEPT
98  key_type_node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::key_type>>>::resolve()},
99  mapped_type_node{nullptr},
100  value_type_node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::value_type>>>::resolve()},
101  size_fn{&meta_associative_container_traits<Type>::size},
102  clear_fn{&meta_associative_container_traits<Type>::clear},
103  iter_fn{&meta_associative_container_traits<Type>::iter},
104  insert_fn{&meta_associative_container_traits<Type>::insert},
105  erase_fn{&meta_associative_container_traits<Type>::erase},
106  find_fn{&meta_associative_container_traits<Type>::find},
107  storage{std::move(instance)} {
108  if constexpr(!meta_associative_container_traits<Type>::key_only) {
109  mapped_type_node = internal::meta_node<std::remove_cv_t<std::remove_reference_t<typename Type::mapped_type>>>::resolve();
110  }
111  }
112 
113  [[nodiscard]] inline bool key_only() const ENTT_NOEXCEPT;
114  [[nodiscard]] inline meta_type key_type() const ENTT_NOEXCEPT;
115  [[nodiscard]] inline meta_type mapped_type() const ENTT_NOEXCEPT;
116  [[nodiscard]] inline meta_type value_type() const ENTT_NOEXCEPT;
117  [[nodiscard]] inline size_type size() const ENTT_NOEXCEPT;
118  inline bool clear();
119  [[nodiscard]] inline iterator begin();
120  [[nodiscard]] inline iterator end();
121  inline bool insert(meta_any, meta_any);
122  inline bool erase(meta_any);
123  [[nodiscard]] inline iterator find(meta_any);
124  [[nodiscard]] inline explicit operator bool() const ENTT_NOEXCEPT;
125 
126 private:
127  bool key_only_container{};
128  internal::meta_type_node *key_type_node = nullptr;
129  internal::meta_type_node *mapped_type_node = nullptr;
130  internal::meta_type_node *value_type_node = nullptr;
131  size_type (*size_fn)(const any &) ENTT_NOEXCEPT = nullptr;
132  bool (*clear_fn)(any &) = nullptr;
133  iterator (*iter_fn)(any &, const bool) = nullptr;
134  bool (*insert_fn)(any &, meta_any &, meta_any &) = nullptr;
135  bool (*erase_fn)(any &, meta_any &) = nullptr;
136  iterator (*find_fn)(any &, meta_any &) = nullptr;
137  any storage{};
138 };
139 
141 class meta_any {
142  enum class operation : std::uint8_t {
143  deref,
144  seq,
145  assoc
146  };
147 
148  using vtable_type = void(const operation, const any &, void *);
149 
150  template<typename Type>
151  static void basic_vtable([[maybe_unused]] const operation op, [[maybe_unused]] const any &value, [[maybe_unused]] void *other) {
152  static_assert(std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
153 
154  if constexpr(!std::is_void_v<Type>) {
155  switch(op) {
156  case operation::deref:
157  if constexpr(is_meta_pointer_like_v<Type>) {
158  if constexpr(std::is_function_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>>) {
159  *static_cast<meta_any *>(other) = any_cast<Type>(value);
160  } else if constexpr(!std::is_same_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>, void>) {
161  using in_place_type = decltype(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(value)));
162 
163  if constexpr(std::is_constructible_v<bool, Type>) {
164  if(const auto &pointer_like = any_cast<const Type &>(value); pointer_like) {
165  static_cast<meta_any *>(other)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(pointer_like));
166  }
167  } else {
168  static_cast<meta_any *>(other)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(value)));
169  }
170  }
171  }
172  break;
173  case operation::seq:
175  *static_cast<meta_sequence_container *>(other) = {std::in_place_type<Type>, std::move(const_cast<any &>(value))};
176  }
177  break;
178  case operation::assoc:
180  *static_cast<meta_associative_container *>(other) = {std::in_place_type<Type>, std::move(const_cast<any &>(value))};
181  }
182  break;
183  }
184  }
185  }
186 
187  void release() {
188  if(node && node->dtor && storage.owner()) {
189  node->dtor(storage.data());
190  }
191  }
192 
193  meta_any(const meta_any &other, any ref) ENTT_NOEXCEPT
194  : storage{std::move(ref)},
195  node{storage ? other.node : nullptr},
196  vtable{storage ? other.vtable : &basic_vtable<void>} {}
197 
198 public:
200  meta_any() ENTT_NOEXCEPT
201  : storage{},
202  node{},
203  vtable{&basic_vtable<void>} {}
204 
211  template<typename Type, typename... Args>
212  explicit meta_any(std::in_place_type_t<Type>, Args &&...args)
213  : storage{std::in_place_type<Type>, std::forward<Args>(args)...},
214  node{internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve()},
215  vtable{&basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>} {}
216 
222  template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
223  meta_any(Type &&value)
224  : meta_any{std::in_place_type<std::remove_cv_t<std::remove_reference_t<Type>>>, std::forward<Type>(value)} {}
225 
230  meta_any(const meta_any &other) = default;
231 
236  meta_any(meta_any &&other) ENTT_NOEXCEPT
237  : storage{std::move(other.storage)},
238  node{std::exchange(other.node, nullptr)},
239  vtable{std::exchange(other.vtable, &basic_vtable<void>)} {}
240 
243  release();
244  }
245 
251  meta_any &operator=(const meta_any &other) {
252  release();
253  vtable = other.vtable;
254  storage = other.storage;
255  node = other.node;
256  return *this;
257  }
258 
264  meta_any &operator=(meta_any &&other) ENTT_NOEXCEPT {
265  release();
266  vtable = std::exchange(other.vtable, &basic_vtable<void>);
267  storage = std::move(other.storage);
268  node = std::exchange(other.node, nullptr);
269  return *this;
270  }
271 
278  template<typename Type>
279  std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>, meta_any &>
280  operator=(Type &&value) {
281  emplace<std::decay_t<Type>>(std::forward<Type>(value));
282  return *this;
283  }
284 
286  [[nodiscard]] inline meta_type type() const ENTT_NOEXCEPT;
287 
289  [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
290  return storage.data();
291  }
292 
294  [[nodiscard]] void *data() ENTT_NOEXCEPT {
295  return storage.data();
296  }
297 
308  template<typename... Args>
309  meta_any invoke(const id_type id, Args &&...args) const;
310 
312  template<typename... Args>
313  meta_any invoke(const id_type id, Args &&...args);
314 
326  template<typename Type>
327  bool set(const id_type id, Type &&value);
328 
334  [[nodiscard]] meta_any get(const id_type id) const;
335 
337  [[nodiscard]] meta_any get(const id_type id);
338 
344  template<typename Type>
345  [[nodiscard]] const Type *try_cast() const {
346  if(const auto &info = type_id<Type>(); node && *node->info == info) {
347  return any_cast<Type>(&storage);
348  } else if(node) {
349  for(auto *it = node->base; it; it = it->next) {
350  const auto as_const = it->cast(as_ref());
351 
352  if(const Type *base = as_const.template try_cast<Type>(); base) {
353  return base;
354  }
355  }
356  }
357 
358  return nullptr;
359  }
360 
362  template<typename Type>
363  [[nodiscard]] Type *try_cast() {
364  if(const auto &info = type_id<Type>(); node && *node->info == info) {
365  return any_cast<Type>(&storage);
366  } else if(node) {
367  for(auto *it = node->base; it; it = it->next) {
368  if(Type *base = it->cast(as_ref()).template try_cast<Type>(); base) {
369  return base;
370  }
371  }
372  }
373 
374  return nullptr;
375  }
376 
388  template<typename Type>
389  [[nodiscard]] Type cast() const {
390  auto *const instance = try_cast<std::remove_reference_t<Type>>();
391  ENTT_ASSERT(instance, "Invalid instance");
392  return static_cast<Type>(*instance);
393  }
394 
396  template<typename Type>
397  [[nodiscard]] Type cast() {
398  // forces const on non-reference types to make them work also with wrappers for const references
399  auto *const instance = try_cast<std::remove_reference_t<const Type>>();
400  ENTT_ASSERT(instance, "Invalid instance");
401  return static_cast<Type>(*instance);
402  }
403 
410  [[nodiscard]] meta_any allow_cast(const meta_type &type) const;
411 
417  [[nodiscard]] bool allow_cast(const meta_type &type) {
418  if(auto other = std::as_const(*this).allow_cast(type); other) {
419  if(other.storage.owner()) {
420  std::swap(*this, other);
421  }
422 
423  return true;
424  }
425 
426  return false;
427  }
428 
435  template<typename Type>
436  [[nodiscard]] meta_any allow_cast() const {
437  const auto other = allow_cast(internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve());
438 
439  if constexpr(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) {
440  return other.storage.owner() ? other : meta_any{};
441  } else {
442  return other;
443  }
444  }
445 
451  template<typename Type>
452  bool allow_cast() {
453  if(auto other = std::as_const(*this).allow_cast(internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve()); other) {
454  if(other.storage.owner()) {
455  std::swap(*this, other);
456  return true;
457  }
458 
459  return (static_cast<constness_as_t<any, std::remove_reference_t<const Type>> &>(storage).data() != nullptr);
460  }
461 
462  return false;
463  }
464 
466  template<typename Type, typename... Args>
467  void emplace(Args &&...args) {
468  release();
469  vtable = &basic_vtable<std::remove_cv_t<std::remove_reference_t<Type>>>;
470  storage.emplace<Type>(std::forward<Args>(args)...);
471  node = internal::meta_node<std::remove_cv_t<std::remove_reference_t<Type>>>::resolve();
472  }
473 
475  bool assign(const meta_any &other);
476 
478  bool assign(meta_any &&other);
479 
481  void reset() {
482  release();
483  vtable = &basic_vtable<void>;
484  storage.reset();
485  node = nullptr;
486  }
487 
492  [[nodiscard]] meta_sequence_container as_sequence_container() ENTT_NOEXCEPT {
493  any detached = storage.as_ref();
495  vtable(operation::seq, detached, &proxy);
496  return proxy;
497  }
498 
500  [[nodiscard]] meta_sequence_container as_sequence_container() const ENTT_NOEXCEPT {
501  any detached = storage.as_ref();
503  vtable(operation::seq, detached, &proxy);
504  return proxy;
505  }
506 
511  [[nodiscard]] meta_associative_container as_associative_container() ENTT_NOEXCEPT {
512  any detached = storage.as_ref();
514  vtable(operation::assoc, detached, &proxy);
515  return proxy;
516  }
517 
519  [[nodiscard]] meta_associative_container as_associative_container() const ENTT_NOEXCEPT {
520  any detached = storage.as_ref();
522  vtable(operation::assoc, detached, &proxy);
523  return proxy;
524  }
525 
531  [[nodiscard]] meta_any operator*() const ENTT_NOEXCEPT {
532  meta_any ret{};
533  vtable(operation::deref, storage, &ret);
534  return ret;
535  }
536 
541  [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
542  return !(node == nullptr);
543  }
544 
546  [[nodiscard]] bool operator==(const meta_any &other) const {
547  return (!node && !other.node) || (node && other.node && *node->info == *other.node->info && storage == other.storage);
548  }
549 
551  [[nodiscard]] meta_any as_ref() ENTT_NOEXCEPT {
552  return meta_any{*this, storage.as_ref()};
553  }
554 
556  [[nodiscard]] meta_any as_ref() const ENTT_NOEXCEPT {
557  return meta_any{*this, storage.as_ref()};
558  }
559 
561  [[nodiscard]] bool owner() const ENTT_NOEXCEPT {
562  return storage.owner();
563  }
564 
565 private:
566  any storage;
567  internal::meta_type_node *node;
568  vtable_type *vtable;
569 };
570 
577 [[nodiscard]] inline bool operator!=(const meta_any &lhs, const meta_any &rhs) ENTT_NOEXCEPT {
578  return !(lhs == rhs);
579 }
580 
588 template<typename Type, typename... Args>
589 meta_any make_meta(Args &&...args) {
590  return meta_any{std::in_place_type<Type>, std::forward<Args>(args)...};
591 }
592 
599 template<typename Type>
600 meta_any forward_as_meta(Type &&value) {
601  return meta_any{std::in_place_type<std::conditional_t<std::is_rvalue_reference_v<Type>, std::decay_t<Type>, Type>>, std::forward<Type>(value)};
602 }
603 
611 struct meta_handle {
613  meta_handle() = default;
614 
616  meta_handle(const meta_handle &) = delete;
617 
619  meta_handle(meta_handle &&) = default;
620 
625  meta_handle &operator=(const meta_handle &) = delete;
626 
632 
638  template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_handle>>>
639  meta_handle(Type &value) ENTT_NOEXCEPT
640  : meta_handle{} {
641  if constexpr(std::is_same_v<std::decay_t<Type>, meta_any>) {
642  any = value.as_ref();
643  } else {
644  any.emplace<Type &>(value);
645  }
646  }
647 
652  [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
653  return static_cast<bool>(any);
654  }
655 
660  [[nodiscard]] meta_any *operator->() {
661  return &any;
662  }
663 
665  [[nodiscard]] const meta_any *operator->() const {
666  return &any;
667  }
668 
669 private:
670  meta_any any;
671 };
672 
674 struct meta_prop {
676  using node_type = internal::meta_prop_node;
677 
682  meta_prop(const node_type *curr = nullptr) ENTT_NOEXCEPT
683  : node{curr} {}
684 
689  [[nodiscard]] meta_any key() const {
690  return node->id.as_ref();
691  }
692 
697  [[nodiscard]] meta_any value() const {
698  return node->value;
699  }
700 
705  [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
706  return !(node == nullptr);
707  }
708 
709 private:
710  const node_type *node;
711 };
712 
714 struct meta_data {
716  using node_type = internal::meta_data_node;
718  using size_type = typename node_type::size_type;
719 
721  meta_data(const node_type *curr = nullptr) ENTT_NOEXCEPT
722  : node{curr} {}
723 
725  [[nodiscard]] id_type id() const ENTT_NOEXCEPT {
726  return node->id;
727  }
728 
733  [[nodiscard]] size_type arity() const ENTT_NOEXCEPT {
734  return node->arity;
735  }
736 
741  [[nodiscard]] bool is_const() const ENTT_NOEXCEPT {
742  return !!(node->traits & internal::meta_traits::is_const);
743  }
744 
749  [[nodiscard]] bool is_static() const ENTT_NOEXCEPT {
750  return !!(node->traits & internal::meta_traits::is_static);
751  }
752 
754  [[nodiscard]] inline meta_type type() const ENTT_NOEXCEPT;
755 
769  template<typename Type>
770  bool set(meta_handle instance, Type &&value) const {
771  return node->set && node->set(std::move(instance), std::forward<Type>(value));
772  }
773 
783  [[nodiscard]] meta_any get(meta_handle instance) const {
784  return node->get(std::move(instance));
785  }
786 
792  [[nodiscard]] inline meta_type arg(const size_type index) const ENTT_NOEXCEPT;
793 
798  [[nodiscard]] meta_range<meta_prop> prop() const ENTT_NOEXCEPT {
799  return node->prop;
800  }
801 
807  [[nodiscard]] meta_prop prop(meta_any key) const {
808  for(auto curr: prop()) {
809  if(curr.key() == key) {
810  return curr;
811  }
812  }
813 
814  return nullptr;
815  }
816 
821  [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
822  return !(node == nullptr);
823  }
824 
825 private:
826  const node_type *node;
827 };
828 
830 struct meta_func {
832  using node_type = internal::meta_func_node;
834  using size_type = typename node_type::size_type;
835 
837  meta_func(const node_type *curr = nullptr) ENTT_NOEXCEPT
838  : node{curr} {}
839 
841  [[nodiscard]] id_type id() const ENTT_NOEXCEPT {
842  return node->id;
843  }
844 
849  [[nodiscard]] size_type arity() const ENTT_NOEXCEPT {
850  return node->arity;
851  }
852 
857  [[nodiscard]] bool is_const() const ENTT_NOEXCEPT {
858  return !!(node->traits & internal::meta_traits::is_const);
859  }
860 
865  [[nodiscard]] bool is_static() const ENTT_NOEXCEPT {
866  return !!(node->traits & internal::meta_traits::is_static);
867  }
868 
873  [[nodiscard]] inline meta_type ret() const ENTT_NOEXCEPT;
874 
880  [[nodiscard]] inline meta_type arg(const size_type index) const ENTT_NOEXCEPT;
881 
896  meta_any invoke(meta_handle instance, meta_any *const args, const size_type sz) const {
897  return sz == arity() ? node->invoke(std::move(instance), args) : meta_any{};
898  }
899 
910  template<typename... Args>
911  meta_any invoke(meta_handle instance, Args &&...args) const {
912  meta_any arguments[sizeof...(Args) + 1u]{std::forward<Args>(args)...};
913  return invoke(std::move(instance), arguments, sizeof...(Args));
914  }
915 
917  [[nodiscard]] meta_range<meta_prop> prop() const ENTT_NOEXCEPT {
918  return node->prop;
919  }
920 
926  [[nodiscard]] meta_prop prop(meta_any key) const {
927  for(auto curr: prop()) {
928  if(curr.key() == key) {
929  return curr;
930  }
931  }
932 
933  return nullptr;
934  }
935 
940  [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
941  return !(node == nullptr);
942  }
943 
944 private:
945  const node_type *node;
946 };
947 
949 class meta_type {
950  template<auto Member, typename Pred>
951  [[nodiscard]] std::decay_t<decltype(std::declval<internal::meta_type_node>().*Member)> lookup(meta_any *const args, const typename internal::meta_type_node::size_type sz, Pred pred) const {
952  std::decay_t<decltype(node->*Member)> candidate{};
953  size_type extent{sz + 1u};
954  bool ambiguous{};
955 
956  for(auto *curr = (node->*Member); curr; curr = curr->next) {
957  if(pred(curr) && curr->arity == sz) {
958  size_type direct{};
959  size_type ext{};
960 
961  for(size_type next{}; next < sz && next == (direct + ext) && args[next]; ++next) {
962  const auto type = args[next].type();
963  const auto other = curr->arg(next);
964 
965  if(const auto &info = other.info(); info == type.info()) {
966  ++direct;
967  } else {
968  ext += internal::find_by<&node_type::base>(info, type.node)
969  || internal::find_by<&node_type::conv>(info, type.node)
970  || (type.node->conversion_helper && other.node->conversion_helper);
971  }
972  }
973 
974  if((direct + ext) == sz) {
975  if(ext < extent) {
976  candidate = curr;
977  extent = ext;
978  ambiguous = false;
979  } else if(ext == extent) {
980  ambiguous = true;
981  }
982  }
983  }
984  }
985 
986  return (candidate && !ambiguous) ? candidate : decltype(candidate){};
987  }
988 
989 public:
991  using node_type = internal::meta_type_node;
993  using base_node_type = internal::meta_base_node;
995  using size_type = typename node_type::size_type;
996 
998  meta_type(const node_type *curr = nullptr) ENTT_NOEXCEPT
999  : node{curr} {}
1000 
1005  meta_type(const base_node_type *curr) ENTT_NOEXCEPT
1006  : node{curr ? curr->type : nullptr} {}
1007 
1012  [[nodiscard]] const type_info &info() const ENTT_NOEXCEPT {
1013  return *node->info;
1014  }
1015 
1020  [[nodiscard]] id_type id() const ENTT_NOEXCEPT {
1021  return node->id;
1022  }
1023 
1028  [[nodiscard]] size_type size_of() const ENTT_NOEXCEPT {
1029  return node->size_of;
1030  }
1031 
1037  [[nodiscard]] bool is_arithmetic() const ENTT_NOEXCEPT {
1038  return !!(node->traits & internal::meta_traits::is_arithmetic);
1039  }
1040 
1045  [[nodiscard]] bool is_array() const ENTT_NOEXCEPT {
1046  return !!(node->traits & internal::meta_traits::is_array);
1047  }
1048 
1053  [[nodiscard]] bool is_enum() const ENTT_NOEXCEPT {
1054  return !!(node->traits & internal::meta_traits::is_enum);
1055  }
1056 
1061  [[nodiscard]] bool is_class() const ENTT_NOEXCEPT {
1062  return !!(node->traits & internal::meta_traits::is_class);
1063  }
1064 
1069  [[nodiscard]] bool is_pointer() const ENTT_NOEXCEPT {
1070  return !!(node->traits & internal::meta_traits::is_pointer);
1071  }
1072 
1078  [[nodiscard]] bool is_pointer_like() const ENTT_NOEXCEPT {
1079  return !!(node->traits & internal::meta_traits::is_meta_pointer_like);
1080  }
1081 
1086  [[nodiscard]] bool is_sequence_container() const ENTT_NOEXCEPT {
1087  return !!(node->traits & internal::meta_traits::is_meta_sequence_container);
1088  }
1089 
1094  [[nodiscard]] bool is_associative_container() const ENTT_NOEXCEPT {
1095  return !!(node->traits & internal::meta_traits::is_meta_associative_container);
1096  }
1097 
1104  [[nodiscard]] bool is_template_specialization() const ENTT_NOEXCEPT {
1105  return (node->templ != nullptr);
1106  }
1107 
1112  [[nodiscard]] size_type template_arity() const ENTT_NOEXCEPT {
1113  return node->templ ? node->templ->arity : size_type{};
1114  }
1115 
1123  [[nodiscard]] inline meta_type template_type() const ENTT_NOEXCEPT {
1124  return node->templ ? node->templ->type : meta_type{};
1125  }
1126 
1132  [[nodiscard]] inline meta_type template_arg(const size_type index) const ENTT_NOEXCEPT {
1133  return index < template_arity() ? node->templ->arg(index) : meta_type{};
1134  }
1135 
1140  [[nodiscard]] meta_range<meta_type, internal::meta_base_node> base() const ENTT_NOEXCEPT {
1141  return node->base;
1142  }
1143 
1149  [[nodiscard]] meta_type base(const id_type id) const {
1150  return internal::find_by<&node_type::base>(id, node);
1151  }
1152 
1157  [[nodiscard]] meta_range<meta_data> data() const ENTT_NOEXCEPT {
1158  return node->data;
1159  }
1160 
1169  [[nodiscard]] meta_data data(const id_type id) const {
1170  return internal::find_by<&node_type::data>(id, node);
1171  }
1172 
1177  [[nodiscard]] meta_range<meta_func> func() const ENTT_NOEXCEPT {
1178  return node->func;
1179  }
1180 
1191  [[nodiscard]] meta_func func(const id_type id) const {
1192  return internal::find_by<&node_type::func>(id, node);
1193  }
1194 
1206  [[nodiscard]] meta_any construct(meta_any *const args, const size_type sz) const {
1207  const auto *candidate = lookup<&node_type::ctor>(args, sz, [](const auto *) { return true; });
1208  return candidate ? candidate->invoke(args) : ((!sz && node->default_constructor) ? node->default_constructor() : meta_any{});
1209  }
1210 
1220  template<typename... Args>
1221  [[nodiscard]] meta_any construct(Args &&...args) const {
1222  meta_any arguments[sizeof...(Args) + 1u]{std::forward<Args>(args)...};
1223  return construct(arguments, sizeof...(Args));
1224  }
1225 
1240  meta_any invoke(const id_type id, meta_handle instance, meta_any *const args, const size_type sz) const {
1241  const auto *candidate = lookup<&node_type::func>(args, sz, [id](const auto *curr) { return curr->id == id; });
1242 
1243  for(auto it = base().begin(), last = base().end(); it != last && !candidate; ++it) {
1244  candidate = it->lookup<&node_type::func>(args, sz, [id](const auto *curr) { return curr->id == id; });
1245  }
1246 
1247  return candidate ? candidate->invoke(std::move(instance), args) : meta_any{};
1248  }
1249 
1261  template<typename... Args>
1262  meta_any invoke(const id_type id, meta_handle instance, Args &&...args) const {
1263  meta_any arguments[sizeof...(Args) + 1u]{std::forward<Args>(args)...};
1264  return invoke(id, std::move(instance), arguments, sizeof...(Args));
1265  }
1266 
1281  template<typename Type>
1282  bool set(const id_type id, meta_handle instance, Type &&value) const {
1283  const auto candidate = data(id);
1284  return candidate && candidate.set(std::move(instance), std::forward<Type>(value));
1285  }
1286 
1297  [[nodiscard]] meta_any get(const id_type id, meta_handle instance) const {
1298  const auto candidate = data(id);
1299  return candidate ? candidate.get(std::move(instance)) : meta_any{};
1300  }
1301 
1306  [[nodiscard]] meta_range<meta_prop> prop() const ENTT_NOEXCEPT {
1307  return node->prop;
1308  }
1309 
1318  [[nodiscard]] meta_prop prop(meta_any key) const {
1319  return internal::find_by<&internal::meta_type_node::prop>(key, node);
1320  }
1321 
1326  [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
1327  return !(node == nullptr);
1328  }
1329 
1335  [[nodiscard]] bool operator==(const meta_type &other) const ENTT_NOEXCEPT {
1336  return (!node && !other.node) || (node && other.node && *node->info == *other.node->info);
1337  }
1338 
1339 private:
1340  const node_type *node;
1341 };
1342 
1349 [[nodiscard]] inline bool operator!=(const meta_type &lhs, const meta_type &rhs) ENTT_NOEXCEPT {
1350  return !(lhs == rhs);
1351 }
1352 
1353 [[nodiscard]] inline meta_type meta_any::type() const ENTT_NOEXCEPT {
1354  return node;
1355 }
1356 
1357 template<typename... Args>
1358 meta_any meta_any::invoke(const id_type id, Args &&...args) const {
1359  return type().invoke(id, *this, std::forward<Args>(args)...);
1360 }
1361 
1362 template<typename... Args>
1363 meta_any meta_any::invoke(const id_type id, Args &&...args) {
1364  return type().invoke(id, *this, std::forward<Args>(args)...);
1365 }
1366 
1367 template<typename Type>
1368 bool meta_any::set(const id_type id, Type &&value) {
1369  return type().set(id, *this, std::forward<Type>(value));
1370 }
1371 
1372 [[nodiscard]] inline meta_any meta_any::get(const id_type id) const {
1373  return type().get(id, *this);
1374 }
1375 
1376 [[nodiscard]] inline meta_any meta_any::get(const id_type id) {
1377  return type().get(id, *this);
1378 }
1379 
1380 [[nodiscard]] inline meta_any meta_any::allow_cast(const meta_type &type) const {
1381  if(const auto &info = type.info(); node && *node->info == info) {
1382  return as_ref();
1383  } else if(node) {
1384  for(auto *it = node->conv; it; it = it->next) {
1385  if(*it->type->info == info) {
1386  return it->conv(*this);
1387  }
1388  }
1389 
1390  if(node->conversion_helper && (type.is_arithmetic() || type.is_enum())) {
1391  // exploits the fact that arithmetic types and enums are also default constructible
1392  auto other = type.construct();
1393  ENTT_ASSERT(other.node->conversion_helper, "Conversion helper not found");
1394  const auto value = node->conversion_helper(nullptr, storage.data());
1395  other.node->conversion_helper(other.storage.data(), &value);
1396  return other;
1397  }
1398 
1399  for(auto *it = node->base; it; it = it->next) {
1400  const auto as_const = it->cast(as_ref());
1401 
1402  if(auto other = as_const.allow_cast(type); other) {
1403  return other;
1404  }
1405  }
1406  }
1407 
1408  return {};
1409 }
1410 
1411 inline bool meta_any::assign(const meta_any &other) {
1412  auto value = other.allow_cast(node);
1413  return value && storage.assign(std::move(value.storage));
1414 }
1415 
1416 inline bool meta_any::assign(meta_any &&other) {
1417  if(*node->info == *other.node->info) {
1418  return storage.assign(std::move(other.storage));
1419  }
1420 
1421  return assign(std::as_const(other));
1422 }
1423 
1424 [[nodiscard]] inline meta_type meta_data::type() const ENTT_NOEXCEPT {
1425  return node->type;
1426 }
1427 
1428 [[nodiscard]] inline meta_type meta_func::ret() const ENTT_NOEXCEPT {
1429  return node->ret;
1430 }
1431 
1432 [[nodiscard]] inline meta_type meta_data::arg(const size_type index) const ENTT_NOEXCEPT {
1433  return index < arity() ? node->arg(index) : meta_type{};
1434 }
1435 
1436 [[nodiscard]] inline meta_type meta_func::arg(const size_type index) const ENTT_NOEXCEPT {
1437  return index < arity() ? node->arg(index) : meta_type{};
1438 }
1439 
1445 class meta_sequence_container::meta_iterator final {
1446  friend class meta_sequence_container;
1447 
1448  using deref_fn_type = meta_any(const any &, const std::ptrdiff_t);
1449 
1450  template<typename It>
1451  static meta_any deref_fn(const any &value, const std::ptrdiff_t pos) {
1452  return meta_any{std::in_place_type<typename std::iterator_traits<It>::reference>, any_cast<const It &>(value)[pos]};
1453  }
1454 
1455 public:
1456  using difference_type = std::ptrdiff_t;
1457  using value_type = meta_any;
1458  using pointer = input_iterator_pointer<value_type>;
1459  using reference = value_type;
1460  using iterator_category = std::input_iterator_tag;
1461 
1462  meta_iterator() ENTT_NOEXCEPT
1463  : deref{},
1464  offset{},
1465  handle{} {}
1466 
1467  template<typename It>
1468  explicit meta_iterator(It iter, const difference_type init) ENTT_NOEXCEPT
1469  : deref{&deref_fn<It>},
1470  offset{init},
1471  handle{std::move(iter)} {}
1472 
1473  meta_iterator &operator++() ENTT_NOEXCEPT {
1474  return ++offset, *this;
1475  }
1476 
1477  meta_iterator operator++(int value) ENTT_NOEXCEPT {
1478  meta_iterator orig = *this;
1479  offset += ++value;
1480  return orig;
1481  }
1482 
1483  meta_iterator &operator--() ENTT_NOEXCEPT {
1484  return --offset, *this;
1485  }
1486 
1487  meta_iterator operator--(int value) ENTT_NOEXCEPT {
1488  meta_iterator orig = *this;
1489  offset -= ++value;
1490  return orig;
1491  }
1492 
1493  [[nodiscard]] reference operator*() const {
1494  return deref(handle, offset);
1495  }
1496 
1497  [[nodiscard]] pointer operator->() const {
1498  return operator*();
1499  }
1500 
1501  [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
1502  return static_cast<bool>(handle);
1503  }
1504 
1505  [[nodiscard]] bool operator==(const meta_iterator &other) const ENTT_NOEXCEPT {
1506  return offset == other.offset;
1507  }
1508 
1509  [[nodiscard]] bool operator!=(const meta_iterator &other) const ENTT_NOEXCEPT {
1510  return !(*this == other);
1511  }
1512 
1513 private:
1514  deref_fn_type *deref;
1515  difference_type offset;
1516  any handle;
1517 };
1518 
1519 class meta_associative_container::meta_iterator final {
1520  enum class operation : std::uint8_t {
1521  incr,
1522  deref
1523  };
1524 
1525  using vtable_type = void(const operation, const any &, std::pair<meta_any, meta_any> *);
1526 
1527  template<bool KeyOnly, typename It>
1528  static void basic_vtable(const operation op, const any &value, std::pair<meta_any, meta_any> *other) {
1529  switch(op) {
1530  case operation::incr:
1531  ++any_cast<It &>(const_cast<any &>(value));
1532  break;
1533  case operation::deref:
1534  const auto &it = any_cast<const It &>(value);
1535  if constexpr(KeyOnly) {
1536  other->first.emplace<decltype(*it)>(*it);
1537  } else {
1538  other->first.emplace<decltype((it->first))>(it->first);
1539  other->second.emplace<decltype((it->second))>(it->second);
1540  }
1541  break;
1542  }
1543  }
1544 
1545 public:
1546  using difference_type = std::ptrdiff_t;
1547  using value_type = std::pair<meta_any, meta_any>;
1548  using pointer = input_iterator_pointer<value_type>;
1549  using reference = value_type;
1550  using iterator_category = std::input_iterator_tag;
1551 
1552  meta_iterator() ENTT_NOEXCEPT
1553  : vtable{},
1554  handle{} {}
1555 
1556  template<bool KeyOnly, typename It>
1557  meta_iterator(std::integral_constant<bool, KeyOnly>, It iter) ENTT_NOEXCEPT
1558  : vtable{&basic_vtable<KeyOnly, It>},
1559  handle{std::move(iter)} {}
1560 
1561  meta_iterator &operator++() ENTT_NOEXCEPT {
1562  vtable(operation::incr, handle, nullptr);
1563  return *this;
1564  }
1565 
1566  meta_iterator operator++(int) ENTT_NOEXCEPT {
1567  meta_iterator orig = *this;
1568  return ++(*this), orig;
1569  }
1570 
1571  [[nodiscard]] reference operator*() const {
1572  reference other;
1573  vtable(operation::deref, handle, &other);
1574  return other;
1575  }
1576 
1577  [[nodiscard]] pointer operator->() const {
1578  return operator*();
1579  }
1580 
1581  [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
1582  return static_cast<bool>(handle);
1583  }
1584 
1585  [[nodiscard]] bool operator==(const meta_iterator &other) const ENTT_NOEXCEPT {
1586  return handle == other.handle;
1587  }
1588 
1589  [[nodiscard]] bool operator!=(const meta_iterator &other) const ENTT_NOEXCEPT {
1590  return !(*this == other);
1591  }
1592 
1593 private:
1594  vtable_type *vtable;
1595  any handle;
1596 };
1597 
1607 [[nodiscard]] inline meta_type meta_sequence_container::value_type() const ENTT_NOEXCEPT {
1608  return value_type_node;
1609 }
1610 
1615 [[nodiscard]] inline meta_sequence_container::size_type meta_sequence_container::size() const ENTT_NOEXCEPT {
1616  return size_fn(storage);
1617 }
1618 
1625  return resize_fn(storage, sz);
1626 }
1627 
1633  return resize_fn(storage, 0u);
1634 }
1635 
1641  return iter_fn(storage, false);
1642 }
1643 
1649  return iter_fn(storage, true);
1650 }
1651 
1659  return insert_fn(storage, it.offset, value);
1660 }
1661 
1668  return erase_fn(storage, it.offset);
1669 }
1670 
1677 [[nodiscard]] inline meta_any meta_sequence_container::operator[](const size_type pos) {
1678  auto it = begin();
1679  it.operator++(static_cast<int>(pos) - 1);
1680  return *it;
1681 }
1682 
1687 [[nodiscard]] inline meta_sequence_container::operator bool() const ENTT_NOEXCEPT {
1688  return static_cast<bool>(storage);
1689 }
1690 
1695 [[nodiscard]] inline bool meta_associative_container::key_only() const ENTT_NOEXCEPT {
1696  return key_only_container;
1697 }
1698 
1703 [[nodiscard]] inline meta_type meta_associative_container::key_type() const ENTT_NOEXCEPT {
1704  return key_type_node;
1705 }
1706 
1711 [[nodiscard]] inline meta_type meta_associative_container::mapped_type() const ENTT_NOEXCEPT {
1712  return mapped_type_node;
1713 }
1714 
1716 [[nodiscard]] inline meta_type meta_associative_container::value_type() const ENTT_NOEXCEPT {
1717  return value_type_node;
1718 }
1719 
1722  return size_fn(storage);
1723 }
1724 
1727  return clear_fn(storage);
1728 }
1729 
1732  return iter_fn(storage, false);
1733 }
1734 
1737  return iter_fn(storage, true);
1738 }
1739 
1747  return insert_fn(storage, key, value);
1748 }
1749 
1756  return erase_fn(storage, key);
1757 }
1758 
1765  return find_fn(storage, key);
1766 }
1767 
1772 [[nodiscard]] inline meta_associative_container::operator bool() const ENTT_NOEXCEPT {
1773  return static_cast<bool>(storage);
1774 }
1775 
1776 } // namespace entt
1777 
1778 #endif
basic_any as_ref()
Aliasing constructor.
Definition: any.hpp:366
pointer data() const
Direct access to the internal packed array.
Definition: sparse_set.hpp:481
Basic storage implementation.
Definition: storage.hpp:234
value_type & emplace(const entity_type entt, Args &&...args)
Assigns an entity to a storage and constructs its object.
Definition: storage.hpp:661
Opaque wrapper for values of any type.
Definition: meta.hpp:141
meta_any()
Default constructor.
Definition: meta.hpp:200
bool assign(const meta_any &other)
Assigns a value to the contained object without replacing it.
Definition: meta.hpp:1411
meta_any operator*() const
Indirection operator for dereferencing opaque objects.
Definition: meta.hpp:531
bool operator==(const meta_any &other) const
Checks if two wrappers differ in their content.
Definition: meta.hpp:546
meta_any(std::in_place_type_t< Type >, Args &&...args)
Constructs a wrapper by directly initializing the new object.
Definition: meta.hpp:212
void emplace(Args &&...args)
Replaces the contained object by creating a new instance directly.
Definition: meta.hpp:467
const void * data() const
Returns an opaque pointer to the contained instance.
Definition: meta.hpp:289
Type cast()
Tries to cast an instance to a given type.
Definition: meta.hpp:397
meta_any(const meta_any &other)=default
Copy constructor.
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:1380
void * data()
Returns an opaque pointer to the contained instance.
Definition: meta.hpp:294
meta_any get(const id_type id) const
Gets the value of a given variable.
Definition: meta.hpp:1372
meta_any allow_cast() const
Converts an object in such a way that a given cast becomes viable.
Definition: meta.hpp:436
meta_sequence_container as_sequence_container()
Returns a sequence container proxy.
Definition: meta.hpp:492
meta_any(Type &&value)
Constructs a wrapper from a given value.
Definition: meta.hpp:223
~meta_any()
Frees the internal storage, whatever it means.
Definition: meta.hpp:242
meta_any & operator=(meta_any &&other)
Move assignment operator.
Definition: meta.hpp:264
Type cast() const
Tries to cast an instance to a given type.
Definition: meta.hpp:389
meta_sequence_container as_sequence_container() const
Returns a sequence container proxy.
Definition: meta.hpp:500
meta_type type() const
Returns the object type if any, type_id<void>() otherwise.
Definition: meta.hpp:1353
void reset()
Destroys contained object.
Definition: meta.hpp:481
Type * try_cast()
Tries to cast an instance to a given type.
Definition: meta.hpp:363
meta_any & operator=(const meta_any &other)
Copy assignment operator.
Definition: meta.hpp:251
const Type * try_cast() const
Tries to cast an instance to a given type.
Definition: meta.hpp:345
bool set(const id_type id, Type &&value)
Sets the value of a given variable.
Definition: meta.hpp:1368
meta_any as_ref() const
Aliasing constructor.
Definition: meta.hpp:556
bool owner() const
Returns true if a wrapper owns its object, false otherwise.
Definition: meta.hpp:561
meta_any invoke(const id_type id, Args &&...args) const
Invokes the underlying function, if possible.
Definition: meta.hpp:1358
meta_associative_container as_associative_container() const
Returns an associative container proxy.
Definition: meta.hpp:519
meta_any as_ref()
Aliasing constructor.
Definition: meta.hpp:551
std::enable_if_t<!std::is_same_v< std::decay_t< Type >, meta_any >, meta_any & > operator=(Type &&value)
Value assignment operator.
Definition: meta.hpp:280
bool allow_cast()
Converts an object in such a way that a given cast becomes viable.
Definition: meta.hpp:452
bool allow_cast(const meta_type &type)
Converts an object in such a way that a given cast becomes viable.
Definition: meta.hpp:417
meta_any(meta_any &&other)
Move constructor.
Definition: meta.hpp:236
meta_associative_container as_associative_container()
Returns an associative container proxy.
Definition: meta.hpp:511
Proxy object for associative containers.
Definition: meta.hpp:78
bool key_only() const
Returns true if a container is also key-only, false otherwise.
Definition: meta.hpp:1695
meta_associative_container()=default
Default constructor.
meta_type value_type() const
Returns the meta value type of a container.
Definition: meta.hpp:1716
iterator find(meta_any)
Returns an iterator to the element with a given key, if any.
Definition: meta.hpp:1764
bool insert(meta_any, meta_any)
Inserts an element (a key/value pair) into a container.
Definition: meta.hpp:1746
iterator end()
Returns an iterator that is past the last element of a container.
Definition: meta.hpp:1736
iterator begin()
Returns an iterator to the first element of a container.
Definition: meta.hpp:1731
std::size_t size_type
Unsigned integer type.
Definition: meta.hpp:83
meta_iterator iterator
Meta iterator type.
Definition: meta.hpp:85
bool erase(meta_any)
Removes the specified element from a container.
Definition: meta.hpp:1755
meta_type key_type() const
Returns the meta key type of a container.
Definition: meta.hpp:1703
meta_type mapped_type() const
Returns the meta mapped type of a container.
Definition: meta.hpp:1711
size_type size() const
Returns the size of a container.
Definition: meta.hpp:1721
bool clear()
Clears the content of a container.
Definition: meta.hpp:1726
Proxy object for sequence containers.
Definition: meta.hpp:29
meta_sequence_container()=default
Default constructor.
iterator end()
Returns an iterator that is past the last element of a container.
Definition: meta.hpp:1648
meta_type value_type() const
Returns the meta value type of a container.
Definition: meta.hpp:1607
meta_any operator[](const size_type)
Returns a reference to the element at a given location of a container (no bounds checking is performe...
Definition: meta.hpp:1677
bool resize(const size_type)
Resizes a container to contain a given number of elements.
Definition: meta.hpp:1624
meta_iterator iterator
Meta iterator type.
Definition: meta.hpp:36
std::size_t size_type
Unsigned integer type.
Definition: meta.hpp:34
iterator erase(iterator)
Removes a given element from a container.
Definition: meta.hpp:1667
iterator insert(iterator, meta_any)
Inserts an element at a specified location of a container.
Definition: meta.hpp:1658
size_type size() const
Returns the size of a container.
Definition: meta.hpp:1615
iterator begin()
Returns an iterator to the first element of a container.
Definition: meta.hpp:1640
bool clear()
Clears the content of a container.
Definition: meta.hpp:1632
Opaque wrapper for types.
Definition: meta.hpp:949
const type_info & info() const
Returns the type info object of the underlying type.
Definition: meta.hpp:1012
meta_type template_arg(const size_type index) const
Returns the type of the i-th template argument of a type.
Definition: meta.hpp:1132
bool is_associative_container() const
Checks whether a type refers to an associative container or not.
Definition: meta.hpp:1094
meta_range< meta_func > func() const
Returns a range to visit registered top-level functions.
Definition: meta.hpp:1177
internal::meta_type_node node_type
Node type.
Definition: meta.hpp:991
meta_range< meta_type, internal::meta_base_node > base() const
Returns a range to visit registered top-level base meta types.
Definition: meta.hpp:1140
bool operator==(const meta_type &other) const
Checks if two objects refer to the same type.
Definition: meta.hpp:1335
bool is_arithmetic() const
Checks whether a type refers to an arithmetic type or not.
Definition: meta.hpp:1037
meta_type base(const id_type id) const
Lookup function for registered base meta types.
Definition: meta.hpp:1149
meta_func func(const id_type id) const
Lookup function for registered meta functions.
Definition: meta.hpp:1191
meta_any construct(Args &&...args) const
Creates an instance of the underlying type, if possible.
Definition: meta.hpp:1221
meta_prop prop(meta_any key) const
Lookup function for meta properties.
Definition: meta.hpp:1318
size_type size_of() const
Returns the size of the underlying type if known.
Definition: meta.hpp:1028
meta_data data(const id_type id) const
Lookup function for registered meta data.
Definition: meta.hpp:1169
bool set(const id_type id, meta_handle instance, Type &&value) const
Sets the value of a given variable.
Definition: meta.hpp:1282
bool is_pointer() const
Checks whether a type refers to a pointer or not.
Definition: meta.hpp:1069
bool is_class() const
Checks whether a type refers to a class or not.
Definition: meta.hpp:1061
meta_any invoke(const id_type id, meta_handle instance, Args &&...args) const
Invokes a function given an identifier, if possible.
Definition: meta.hpp:1262
typename node_type::size_type size_type
Unsigned integer type.
Definition: meta.hpp:995
bool is_pointer_like() const
Checks whether a type is a pointer-like type or not.
Definition: meta.hpp:1078
id_type id() const
Returns the identifier assigned to a type.
Definition: meta.hpp:1020
bool is_array() const
Checks whether a type refers to an array type or not.
Definition: meta.hpp:1045
bool is_sequence_container() const
Checks whether a type refers to a sequence container or not.
Definition: meta.hpp:1086
meta_any get(const id_type id, meta_handle instance) const
Gets the value of a given variable.
Definition: meta.hpp:1297
meta_type(const base_node_type *curr)
Constructs an instance from a given base node.
Definition: meta.hpp:1005
meta_any construct(meta_any *const args, const size_type sz) const
Creates an instance of the underlying type, if possible.
Definition: meta.hpp:1206
size_type template_arity() const
Returns the number of template arguments.
Definition: meta.hpp:1112
bool is_enum() const
Checks whether a type refers to an enum or not.
Definition: meta.hpp:1053
meta_type(const node_type *curr=nullptr)
Constructs an instance from a given node.
Definition: meta.hpp:998
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:1240
bool is_template_specialization() const
Checks whether a type refers to a recognized class template specialization or not.
Definition: meta.hpp:1104
internal::meta_base_node base_node_type
Node type.
Definition: meta.hpp:993
meta_type template_type() const
Returns a tag for the class template of the underlying type.
Definition: meta.hpp:1123
meta_range< meta_data > data() const
Returns a range to visit registered top-level meta data.
Definition: meta.hpp:1157
meta_range< meta_prop > prop() const
Returns a range to visit registered top-level meta properties.
Definition: meta.hpp:1306
EnTT default namespace.
Definition: dense_map.hpp:22
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.
meta_type resolve()
Returns the meta type associated with a given type.
Definition: resolve.hpp:19
std::uint32_t id_type
Alias declaration for type identifiers.
Definition: fwd.hpp:14
basic_any<> any
Alias declaration for the most common use case.
Definition: fwd.hpp:17
basic_handle< entity > handle
Alias declaration for the most common use case.
Definition: fwd.hpp:69
meta_any forward_as_meta(Type &&value)
Forwards its argument and avoids copies for lvalue references.
Definition: meta.hpp:600
typename constness_as< To, From >::type constness_as_t
Alias template to facilitate the transcription of the constness.
constexpr bool is_complete_v
Helper variable template.
basic_storage< entity, Args... > storage
Alias declaration for the most common use case.
Definition: fwd.hpp:57
meta_any make_meta(Args &&...args)
Constructs a wrapper from a given type, passing it all arguments.
Definition: meta.hpp:589
bool operator!=(const basic_any< Len, Align > &lhs, const basic_any< Len, Align > &rhs)
Checks if two wrappers differ in their content.
Definition: any.hpp:402
Fake ADL based lookup function for meta pointer-like types.
Definition: adl_pointer.hpp:22
Traits class template to be specialized to enable support for meta associative containers.
Definition: type_traits.hpp:28
Opaque wrapper for data members.
Definition: meta.hpp:714
bool is_static() const
Indicates whether a data member is static or not.
Definition: meta.hpp:749
internal::meta_data_node node_type
Node type.
Definition: meta.hpp:716
meta_prop prop(meta_any key) const
Lookup function for registered meta properties.
Definition: meta.hpp:807
meta_data(const node_type *curr=nullptr)
Constructs an instance from a given node.
Definition: meta.hpp:721
id_type id() const
Returns the identifier assigned to a type.
Definition: meta.hpp:725
meta_any get(meta_handle instance) const
Gets the value of a given variable.
Definition: meta.hpp:783
meta_type arg(const size_type index) const
Returns the type accepted by the i-th setter.
Definition: meta.hpp:1432
bool is_const() const
Indicates whether a data member is constant or not.
Definition: meta.hpp:741
bool set(meta_handle instance, Type &&value) const
Sets the value of a given variable.
Definition: meta.hpp:770
typename node_type::size_type size_type
Unsigned integer type.
Definition: meta.hpp:718
meta_range< meta_prop > prop() const
Returns a range to visit registered meta properties.
Definition: meta.hpp:798
meta_type type() const
Returns the object type if any, type_id<void>() otherwise.
Definition: meta.hpp:1424
size_type arity() const
Returns the number of setters available.
Definition: meta.hpp:733
Opaque wrapper for member functions.
Definition: meta.hpp:830
meta_type arg(const size_type index) const
Returns the type of the i-th argument of a member function.
Definition: meta.hpp:1436
meta_range< meta_prop > prop() const
Returns a range to visit registered meta properties.
Definition: meta.hpp:917
id_type id() const
Returns the identifier assigned to a type.
Definition: meta.hpp:841
meta_type ret() const
Returns the return type of a member function.
Definition: meta.hpp:1428
meta_prop prop(meta_any key) const
Lookup function for registered meta properties.
Definition: meta.hpp:926
bool is_const() const
Indicates whether a member function is constant or not.
Definition: meta.hpp:857
meta_any invoke(meta_handle instance, meta_any *const args, const size_type sz) const
Invokes the underlying function, if possible.
Definition: meta.hpp:896
meta_any invoke(meta_handle instance, Args &&...args) const
Invokes the underlying function, if possible.
Definition: meta.hpp:911
typename node_type::size_type size_type
Unsigned integer type.
Definition: meta.hpp:834
bool is_static() const
Indicates whether a member function is static or not.
Definition: meta.hpp:865
internal::meta_func_node node_type
Node type.
Definition: meta.hpp:832
size_type arity() const
Returns the number of arguments accepted by a member function.
Definition: meta.hpp:849
meta_func(const node_type *curr=nullptr)
Constructs an instance from a given node.
Definition: meta.hpp:837
Opaque pointers to instances of any type.
Definition: meta.hpp:611
meta_handle & operator=(const meta_handle &)=delete
Default copy assignment operator, deleted on purpose.
meta_handle()=default
Default constructor.
meta_handle(meta_handle &&)=default
Default move constructor.
meta_handle & operator=(meta_handle &&)=default
Default move assignment operator.
meta_handle(const meta_handle &)=delete
Default copy constructor, deleted on purpose.
meta_any * operator->()
Access operator for accessing the contained opaque object.
Definition: meta.hpp:660
const meta_any * operator->() const
Access operator for accessing the contained opaque object.
Definition: meta.hpp:665
meta_handle(Type &value)
Creates a handle that points to an unmanaged object.
Definition: meta.hpp:639
Opaque wrapper for properties of any type.
Definition: meta.hpp:674
meta_prop(const node_type *curr=nullptr)
Constructs an instance from a given node.
Definition: meta.hpp:682
meta_any value() const
Returns the stored value by copy.
Definition: meta.hpp:697
internal::meta_prop_node node_type
Node type.
Definition: meta.hpp:676
meta_any key() const
Returns the stored key as a const reference.
Definition: meta.hpp:689
Iterable range to use to iterate all types of meta objects.
Definition: range.hpp:74
Traits class template to be specialized to enable support for meta sequence containers.
Definition: type_traits.hpp:21
Implementation specific information about a type.
Definition: type_info.hpp:141