1 #ifndef ENTT_META_NODE_HPP
2 #define ENTT_META_NODE_HPP
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"
34 struct meta_type_node;
37 struct meta_prop_node {
38 meta_prop_node * next;
39 const meta_any *
const id;
40 meta_any *
const value;
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;
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 *);
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);
71 struct meta_data_node {
73 meta_type_node *
const parent;
74 meta_data_node * next;
75 meta_prop_node * prop;
78 meta_type_node *(*
const type)() ENTT_NOEXCEPT;
79 bool(* const set)(meta_handle, meta_any);
80 meta_any(* const
get)(meta_handle);
84 struct meta_func_node {
85 using size_type = std::size_t;
87 meta_type_node *
const parent;
88 meta_func_node * next;
89 meta_prop_node * prop;
90 const size_type arity;
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 *);
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;
108 struct meta_type_node {
109 using size_type = std::size_t;
110 const type_info info;
112 meta_type_node * next;
113 meta_prop_node * prop;
114 const size_type size_of;
116 const bool is_integral;
117 const bool is_floating_point;
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};
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) {
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) {
165 template<
typename... Args>
166 meta_type_node * meta_arg_node(type_list<Args...>,
const std::size_t index) ENTT_NOEXCEPT;
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");
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)), ...);
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{
188 [](meta_any *
const) {
return meta_any{std::in_place_type<Type>}; }
197 [[nodiscard]]
static meta_template_info meta_template_descriptor() ENTT_NOEXCEPT {
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);
208 return {
false, 0u,
nullptr,
nullptr };
213 [[nodiscard]]
static meta_type_node *
resolve() ENTT_NOEXCEPT {
214 static meta_type_node node{
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(),
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)
248 template<
typename Type>
249 struct meta_info: meta_node<std::remove_cv_t<std::remove_reference_t<Type>>> {};
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];