1 #ifndef ENTT_META_NODE_HPP
2 #define ENTT_META_NODE_HPP
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"
33 struct meta_type_node;
36 struct meta_prop_node {
37 meta_prop_node * next;
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;
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 *);
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);
70 struct meta_data_node {
72 meta_type_node *
const parent;
73 meta_data_node * next;
74 meta_prop_node * prop;
77 meta_type_node *(*
const type)() ENTT_NOEXCEPT;
78 bool(* const set)(meta_handle, meta_any);
79 meta_any(* const
get)(meta_handle);
83 struct meta_func_node {
84 using size_type = std::size_t;
86 meta_type_node *
const parent;
87 meta_func_node * next;
88 meta_prop_node * prop;
89 const size_type arity;
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 *);
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;
107 struct meta_type_node {
108 using size_type = std::size_t;
109 const type_info info;
111 meta_type_node * next;
112 meta_prop_node * prop;
113 const size_type size_of;
115 const bool is_integral;
116 const bool is_floating_point;
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};
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) {
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) {
164 template<
typename... Args>
165 meta_type_node * meta_arg_node(type_list<Args...>,
const std::size_t index) ENTT_NOEXCEPT;
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");
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)), ...);
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{
187 [](meta_any *
const) {
return meta_any{std::in_place_type<Type>}; }
196 [[nodiscard]]
static meta_template_info meta_template_descriptor() ENTT_NOEXCEPT {
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);
207 return {
false, 0u,
nullptr,
nullptr };
212 [[nodiscard]]
static meta_type_node *
resolve() ENTT_NOEXCEPT {
213 static meta_type_node node{
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(),
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)
247 template<
typename Type>
248 struct meta_info: meta_node<std::remove_cv_t<std::remove_reference_t<Type>>> {};
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];
meta_type resolve()
Returns the meta type associated with a given type.
std::uint32_t id_type
Alias declaration for type identifiers.
constexpr bool is_complete_v
Helper variable template.
constexpr get_t< Type... > get
Variable template for lists of observed components.
void invoke(basic_registry< Entity > ®, const Entity entt)
Helper to create a listener that directly invokes a member function.