EnTT  3.7.0
node.hpp
1 #ifndef ENTT_META_NODE_HPP
2 #define ENTT_META_NODE_HPP
3 
4 
5 #include <array>
6 #include <cstddef>
7 #include <type_traits>
8 #include <utility>
9 #include "../config/config.h"
10 #include "../core/attribute.h"
11 #include "../core/fwd.hpp"
12 #include "../core/type_info.hpp"
13 #include "../core/type_traits.hpp"
14 #include "type_traits.hpp"
15 
16 
17 namespace entt {
18 
19 
20 class meta_any;
21 class meta_type;
22 struct meta_handle;
23 
24 
31 namespace internal {
32 
33 
34 struct meta_type_node;
35 
36 
37 struct meta_prop_node {
38  meta_prop_node * next;
39  const meta_any * const id;
40  meta_any * const value;
41 };
42 
43 
44 struct meta_base_node {
45  meta_type_node * const parent;
46  meta_base_node * next;
47  meta_type_node *(* const type)() ENTT_NOEXCEPT;
48  const void *(* const cast)(const void *) ENTT_NOEXCEPT;
49 };
50 
51 
52 struct meta_conv_node {
53  meta_type_node * const parent;
54  meta_conv_node * next;
55  meta_type_node *(* const type)() ENTT_NOEXCEPT;
56  meta_any(* const conv)(const void *);
57 };
58 
59 
60 struct meta_ctor_node {
61  using size_type = std::size_t;
62  meta_type_node * const parent;
63  meta_ctor_node * next;
64  meta_prop_node * prop;
65  const size_type arity;
66  meta_type(* const arg)(const size_type) ENTT_NOEXCEPT;
67  meta_any(* const invoke)(meta_any * const);
68 };
69 
70 
71 struct meta_data_node {
72  id_type id;
73  meta_type_node * const parent;
74  meta_data_node * next;
75  meta_prop_node * prop;
76  const bool is_const;
77  const bool is_static;
78  meta_type_node *(* const type)() ENTT_NOEXCEPT;
79  bool(* const set)(meta_handle, meta_any);
80  meta_any(* const get)(meta_handle);
81 };
82 
83 
84 struct meta_func_node {
85  using size_type = std::size_t;
86  id_type id;
87  meta_type_node * const parent;
88  meta_func_node * next;
89  meta_prop_node * prop;
90  const size_type arity;
91  const bool is_const;
92  const bool is_static;
93  meta_type_node *(* const ret)() ENTT_NOEXCEPT;
94  meta_type(* const arg)(const size_type) ENTT_NOEXCEPT;
95  meta_any(* const invoke)(meta_handle, meta_any *);
96 };
97 
98 
99 struct meta_template_info {
100  using size_type = std::size_t;
101  const bool is_template_specialization;
102  const size_type arity;
103  meta_type_node *(* const type)() ENTT_NOEXCEPT;
104  meta_type_node *(* const arg)(const size_type) ENTT_NOEXCEPT;
105 };
106 
107 
108 struct meta_type_node {
109  using size_type = std::size_t;
110  const type_info info;
111  id_type id;
112  meta_type_node * next;
113  meta_prop_node * prop;
114  const size_type size_of;
115  const bool is_void;
116  const bool is_integral;
117  const bool is_floating_point;
118  const bool is_array;
119  const bool is_enum;
120  const bool is_union;
121  const bool is_class;
122  const bool is_pointer;
123  const bool is_function_pointer;
124  const bool is_member_object_pointer;
125  const bool is_member_function_pointer;
126  const bool is_pointer_like;
127  const bool is_sequence_container;
128  const bool is_associative_container;
129  const meta_template_info template_info;
130  const size_type rank;
131  size_type(* const extent)(const size_type) ENTT_NOEXCEPT ;
132  meta_type_node *(* const remove_pointer)() ENTT_NOEXCEPT;
133  meta_type_node *(* const remove_extent)() ENTT_NOEXCEPT;
134  meta_ctor_node * const def_ctor;
135  meta_ctor_node *ctor{nullptr};
136  meta_base_node *base{nullptr};
137  meta_conv_node *conv{nullptr};
138  meta_data_node *data{nullptr};
139  meta_func_node *func{nullptr};
140  void(* dtor)(void *){nullptr};
141 };
142 
143 
144 template<auto Member, typename Op, typename Node>
145 auto meta_visit(const Op &op, const Node *node)
146 -> std::decay_t<decltype(node->*Member)> {
147  for(auto *curr = node->*Member; curr; curr = curr->next) {
148  if(op(curr)) {
149  return curr;
150  }
151  }
152 
153  if constexpr(std::is_same_v<Node, meta_type_node>) {
154  for(auto *curr = node->base; curr; curr = curr->next) {
155  if(auto *ret = meta_visit<Member>(op, curr->type()); ret) {
156  return ret;
157  }
158  }
159  }
160 
161  return nullptr;
162 }
163 
164 
165 template<typename... Args>
166 meta_type_node * meta_arg_node(type_list<Args...>, const std::size_t index) ENTT_NOEXCEPT;
167 
168 
169 template<typename Type>
170 class ENTT_API meta_node {
171  static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>, "Invalid type");
172 
173  template<std::size_t... Index>
174  [[nodiscard]] static auto extent(const meta_type_node::size_type dim, std::index_sequence<Index...>) ENTT_NOEXCEPT {
175  meta_type_node::size_type ext{};
176  ((ext = (dim == Index ? std::extent_v<Type, Index> : ext)), ...);
177  return ext;
178  }
179 
180  [[nodiscard]] static meta_ctor_node * meta_default_constructor([[maybe_unused]] meta_type_node *type) ENTT_NOEXCEPT {
181  if constexpr(std::is_default_constructible_v<Type>) {
182  static meta_ctor_node node{
183  type,
184  nullptr,
185  nullptr,
186  0u,
187  nullptr,
188  [](meta_any * const) { return meta_any{std::in_place_type<Type>}; }
189  };
190 
191  return &node;
192  } else {
193  return nullptr;
194  }
195  }
196 
197  [[nodiscard]] static meta_template_info meta_template_descriptor() ENTT_NOEXCEPT {
198  if constexpr(is_complete_v<meta_template_traits<Type>>) {
199  return {
200  true,
201  meta_template_traits<Type>::args_type::size,
202  &meta_node<typename meta_template_traits<Type>::class_type>::resolve,
203  [](const std::size_t index) ENTT_NOEXCEPT {
204  return meta_arg_node(typename meta_template_traits<Type>::args_type{}, index);
205  }
206  };
207  } else {
208  return { false, 0u, nullptr, nullptr };
209  }
210  }
211 
212 public:
213  [[nodiscard]] static meta_type_node * resolve() ENTT_NOEXCEPT {
214  static meta_type_node node{
215  type_id<Type>(),
216  {},
217  nullptr,
218  nullptr,
219  size_of_v<Type>,
220  std::is_void_v<Type>,
221  std::is_integral_v<Type>,
222  std::is_floating_point_v<Type>,
223  std::is_array_v<Type>,
224  std::is_enum_v<Type>,
225  std::is_union_v<Type>,
226  std::is_class_v<Type>,
227  std::is_pointer_v<Type>,
228  std::is_pointer_v<Type> && std::is_function_v<std::remove_pointer_t<Type>>,
229  std::is_member_object_pointer_v<Type>,
230  std::is_member_function_pointer_v<Type>,
231  is_meta_pointer_like_v<Type>,
232  is_complete_v<meta_sequence_container_traits<Type>>,
233  is_complete_v<meta_associative_container_traits<Type>>,
234  meta_template_descriptor(),
235  std::rank_v<Type>,
236  [](meta_type_node::size_type dim) ENTT_NOEXCEPT { return extent(dim, std::make_index_sequence<std::rank_v<Type>>{}); },
237  &meta_node<std::remove_cv_t<std::remove_pointer_t<Type>>>::resolve,
238  &meta_node<std::remove_cv_t<std::remove_reference_t<std::remove_extent_t<Type>>>>::resolve,
239  meta_default_constructor(&node),
240  meta_default_constructor(&node)
241  };
242 
243  return &node;
244  }
245 };
246 
247 
248 template<typename Type>
249 struct meta_info: meta_node<std::remove_cv_t<std::remove_reference_t<Type>>> {};
250 
251 
252 template<typename... Args>
253 meta_type_node * meta_arg_node(type_list<Args...>, const std::size_t index) ENTT_NOEXCEPT {
254  return std::array<meta_type_node *, sizeof...(Args)>{{internal::meta_info<Args>::resolve()...}}[index];
255 }
256 
257 
258 }
259 
260 
267 }
268 
269 
270 #endif
entt::get
constexpr get_t< Type... > get
Variable template for lists of observed components.
Definition: utility.hpp:40
entt::id_type
std::uint32_t id_type
Alias declaration for type identifiers.
Definition: fwd.hpp:17
entt
EnTT default namespace.
Definition: algorithm.hpp:13
entt::resolve
meta_type resolve() noexcept
Returns the meta type associated with a given type.
Definition: resolve.hpp:22
entt::invoke
void invoke(basic_registry< Entity > &reg, const Entity entt)
Helper to create a listener that directly invokes a member function.
Definition: helper.hpp:130
entt::is_complete_v
constexpr auto is_complete_v
Helper variable template.
Definition: type_traits.hpp:562