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