1 #ifndef ENTT_META_NODE_HPP
2 #define ENTT_META_NODE_HPP
7 #include "../config/config.h"
8 #include "../core/attribute.h"
9 #include "../core/enum.hpp"
10 #include "../core/fwd.hpp"
11 #include "../core/type_info.hpp"
12 #include "../core/type_traits.hpp"
13 #include "type_traits.hpp"
28 enum class meta_traits : std::uint32_t {
32 is_arithmetic = 0x0004,
37 is_meta_pointer_like = 0x0080,
38 is_meta_sequence_container = 0x0100,
39 is_meta_associative_container = 0x0200,
43 struct meta_type_node;
45 struct meta_prop_node {
51 struct meta_base_node {
53 meta_type_node *
const type;
54 meta_any (*
const cast)(meta_any) ENTT_NOEXCEPT;
57 struct meta_conv_node {
59 meta_type_node *
const type;
60 meta_any (*
const conv)(
const meta_any &);
63 struct meta_ctor_node {
64 using size_type = std::size_t;
66 const size_type arity;
67 meta_type (*
const arg)(
const size_type) ENTT_NOEXCEPT;
68 meta_any (*
const invoke)(meta_any *
const);
71 struct meta_data_node {
72 using size_type = std::size_t;
74 const meta_traits traits;
77 const size_type arity;
78 meta_type_node *
const type;
79 meta_type (*
const arg)(
const size_type) ENTT_NOEXCEPT;
80 bool (*
const set)(meta_handle, meta_any);
81 meta_any (*
const get)(meta_handle);
84 struct meta_func_node {
85 using size_type = std::size_t;
87 const meta_traits traits;
90 const size_type arity;
91 meta_type_node *
const ret;
92 meta_type (*
const arg)(
const size_type) ENTT_NOEXCEPT;
93 meta_any (*
const invoke)(meta_handle, meta_any *
const);
96 struct meta_template_node {
97 using size_type = std::size_t;
98 const size_type arity;
99 meta_type_node *
const type;
100 meta_type_node *(*
const arg)(
const size_type)ENTT_NOEXCEPT;
103 struct meta_type_node {
104 using size_type = std::size_t;
105 const type_info *info;
107 const meta_traits traits;
108 meta_type_node *next;
109 meta_prop_node *prop;
110 const size_type size_of;
111 meta_any (*
const default_constructor)();
112 double (*
const conversion_helper)(
void *,
const void *);
113 const meta_template_node *
const templ;
114 meta_ctor_node *ctor{
nullptr};
115 meta_base_node *base{
nullptr};
116 meta_conv_node *conv{
nullptr};
117 meta_data_node *data{
nullptr};
118 meta_func_node *func{
nullptr};
119 void (*dtor)(
void *){
nullptr};
122 template<
typename... Args>
123 meta_type_node *meta_arg_node(type_list<Args...>,
const std::size_t index) ENTT_NOEXCEPT;
125 template<
typename Type>
126 class ENTT_API meta_node {
127 static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>,
"Invalid type");
129 [[nodiscard]]
static auto *meta_default_constructor() ENTT_NOEXCEPT {
130 if constexpr(std::is_default_constructible_v<Type>) {
131 return +[]() {
return meta_any{std::in_place_type<Type>}; };
133 return static_cast<std::decay_t<decltype(meta_type_node::default_constructor)
>>(
nullptr);
137 [[nodiscard]]
static auto *meta_conversion_helper() ENTT_NOEXCEPT {
138 if constexpr(std::is_arithmetic_v<Type>) {
139 return +[](
void *bin,
const void *value) {
140 return bin ?
static_cast<double>(*
static_cast<Type *
>(bin) =
static_cast<Type
>(*
static_cast<const double *
>(value))) : static_cast<double>(*static_cast<const Type *>(value));
142 }
else if constexpr(std::is_enum_v<Type>) {
143 return +[](
void *bin,
const void *value) {
144 return bin ?
static_cast<double>(*
static_cast<Type *
>(bin) =
static_cast<Type
>(
static_cast<std::underlying_type_t<Type>
>(*
static_cast<const double *
>(value)))) :
static_cast<double>(*
static_cast<const Type *
>(value));
147 return static_cast<std::decay_t<decltype(meta_type_node::conversion_helper)
>>(
nullptr);
151 [[nodiscard]]
static meta_template_node *meta_template_info() ENTT_NOEXCEPT {
153 static meta_template_node node{
154 meta_template_traits<Type>::args_type::size,
155 meta_node<typename meta_template_traits<Type>::class_type>
::resolve(),
156 [](
const std::size_t index) ENTT_NOEXCEPT {
return meta_arg_node(
typename meta_template_traits<Type>::args_type{}, index); }
167 [[nodiscard]]
static meta_type_node *
resolve() ENTT_NOEXCEPT {
168 static meta_type_node node{
171 internal::meta_traits::is_none
172 | (std::is_arithmetic_v<Type> ? internal::meta_traits::is_arithmetic : internal::meta_traits::is_none)
173 | (std::is_array_v<Type> ? internal::meta_traits::is_array : internal::meta_traits::is_none)
174 | (std::is_enum_v<Type> ? internal::meta_traits::is_enum : internal::meta_traits::is_none)
175 | (std::is_class_v<Type> ? internal::meta_traits::is_class : internal::meta_traits::is_none)
176 | (std::is_pointer_v<Type> ? internal::meta_traits::is_pointer : internal::meta_traits::is_none)
177 | (is_meta_pointer_like_v<Type> ? internal::meta_traits::is_meta_pointer_like : internal::meta_traits::is_none)
178 | (is_complete_v<meta_sequence_container_traits<Type>> ? internal::meta_traits::is_meta_sequence_container : internal::meta_traits::is_none)
179 | (
is_complete_v<meta_associative_container_traits<Type>> ? internal::meta_traits::is_meta_associative_container : internal::meta_traits::is_none),
183 meta_default_constructor(),
184 meta_conversion_helper(),
193 template<
typename... Args>
194 [[nodiscard]] meta_type_node *meta_arg_node(type_list<Args...>,
const std::size_t index) ENTT_NOEXCEPT {
195 meta_type_node *args[
sizeof...(Args) + 1u]{
nullptr, internal::meta_node<std::remove_cv_t<std::remove_reference_t<Args>>>
::resolve()...};
196 return args[index + 1u];
199 template<auto Member,
typename Type>
200 [[nodiscard]]
static std::decay_t<decltype(std::declval<internal::meta_type_node>().*Member)> find_by(
const Type &info_or_id,
const internal::meta_type_node *node) ENTT_NOEXCEPT {
201 for(
auto *curr = node->*Member; curr; curr = curr->next) {
202 if constexpr(std::is_same_v<Type, type_info>) {
203 if(*curr->type->info == info_or_id) {
206 }
else if constexpr(std::is_same_v<decltype(curr), meta_base_node *>) {
207 if(curr->type->id == info_or_id) {
211 if(curr->id == info_or_id) {
217 for(
auto *curr = node->base; curr; curr = curr->next) {
218 if(
auto *ret = find_by<Member>(info_or_id, curr->type); ret) {
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.