|
|
@@ -1023,10 +1023,6 @@ struct meta_base: meta_object<internal::meta_base_node> {
|
|
|
class meta_type {
|
|
|
friend class meta_any;
|
|
|
|
|
|
- [[nodiscard]] const auto &fetch_node() const {
|
|
|
- return (node == nullptr) ? internal::resolve<void>(internal::meta_context::from(*ctx)) : *node;
|
|
|
- }
|
|
|
-
|
|
|
[[nodiscard]] auto lookup(meta_handle *const args, const auto sz, [[maybe_unused]] bool constness, auto next) const {
|
|
|
decltype(next()) candidate = nullptr;
|
|
|
size_type same{};
|
|
|
@@ -1050,7 +1046,7 @@ class meta_type {
|
|
|
|
|
|
if(const auto &info = other.info(); info == type.info()) {
|
|
|
++match;
|
|
|
- } else if(!(type.fetch_node().conversion_helper && other.fetch_node().conversion_helper) && !(type.fetch_node().details && (internal::find_member(type.fetch_node().details->base, info.hash()) || internal::find_member(type.fetch_node().details->conv, info.hash())))) {
|
|
|
+ } else if(!(type.node->conversion_helper && other.node->conversion_helper) && !(type.node->details && (internal::find_member(type.node->details->base, info.hash()) || internal::find_member(type.node->details->conv, info.hash())))) {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
@@ -1084,7 +1080,8 @@ public:
|
|
|
using size_type = internal::meta_type_node::size_type;
|
|
|
|
|
|
/*! @brief Default constructor. */
|
|
|
- meta_type() noexcept = default;
|
|
|
+ meta_type() noexcept
|
|
|
+ : node{&internal::resolve<void>(internal::meta_context::from(*ctx))} {}
|
|
|
|
|
|
/**
|
|
|
* @brief Context aware constructor for meta objects.
|
|
|
@@ -1093,14 +1090,15 @@ public:
|
|
|
*/
|
|
|
meta_type(const meta_ctx &area, const internal::meta_type_node &curr) noexcept
|
|
|
: ctx{&area},
|
|
|
- node{&curr} {}
|
|
|
+ node{&curr},
|
|
|
+ initialized{true} {}
|
|
|
|
|
|
/**
|
|
|
* @brief Returns the type info object of the underlying type.
|
|
|
* @return The type info object of the underlying type.
|
|
|
*/
|
|
|
[[nodiscard]] const type_info &info() const noexcept {
|
|
|
- return *fetch_node().info;
|
|
|
+ return *node->info;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1108,7 +1106,7 @@ public:
|
|
|
* @return The alias assigned to the type.
|
|
|
*/
|
|
|
[[nodiscard]] id_type alias() const noexcept {
|
|
|
- return fetch_node().alias;
|
|
|
+ return node->alias;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1116,7 +1114,7 @@ public:
|
|
|
* @return The name assigned to the type, if any.
|
|
|
*/
|
|
|
[[nodiscard]] stl::string_view name() const noexcept {
|
|
|
- return (fetch_node().name == nullptr) ? stl::string_view{} : stl::string_view{fetch_node().name};
|
|
|
+ return (node->name == nullptr) ? stl::string_view{} : stl::string_view{node->name};
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1124,7 +1122,7 @@ public:
|
|
|
* @return The size of the underlying type if known, 0 otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] size_type size_of() const noexcept {
|
|
|
- return fetch_node().size_of;
|
|
|
+ return node->size_of;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1133,7 +1131,7 @@ public:
|
|
|
* otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool is_arithmetic() const noexcept {
|
|
|
- return !!(fetch_node().traits & internal::meta_traits::is_arithmetic);
|
|
|
+ return !!(node->traits & internal::meta_traits::is_arithmetic);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1141,7 +1139,7 @@ public:
|
|
|
* @return True if the underlying type is an integral type, false otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool is_integral() const noexcept {
|
|
|
- return !!(fetch_node().traits & internal::meta_traits::is_integral);
|
|
|
+ return !!(node->traits & internal::meta_traits::is_integral);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1149,7 +1147,7 @@ public:
|
|
|
* @return True if the underlying type is a signed type, false otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool is_signed() const noexcept {
|
|
|
- return !!(fetch_node().traits & internal::meta_traits::is_signed);
|
|
|
+ return !!(node->traits & internal::meta_traits::is_signed);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1157,7 +1155,7 @@ public:
|
|
|
* @return True if the underlying type is an array type, false otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool is_array() const noexcept {
|
|
|
- return !!(fetch_node().traits & internal::meta_traits::is_array);
|
|
|
+ return !!(node->traits & internal::meta_traits::is_array);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1165,7 +1163,7 @@ public:
|
|
|
* @return True if the underlying type is an enum, false otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool is_enum() const noexcept {
|
|
|
- return !!(fetch_node().traits & internal::meta_traits::is_enum);
|
|
|
+ return !!(node->traits & internal::meta_traits::is_enum);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1173,7 +1171,7 @@ public:
|
|
|
* @return True if the underlying type is a class, false otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool is_class() const noexcept {
|
|
|
- return !!(fetch_node().traits & internal::meta_traits::is_class);
|
|
|
+ return !!(node->traits & internal::meta_traits::is_class);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1181,7 +1179,7 @@ public:
|
|
|
* @return True if the underlying type is a pointer, false otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool is_pointer() const noexcept {
|
|
|
- return !!(fetch_node().traits & internal::meta_traits::is_pointer);
|
|
|
+ return !!(node->traits & internal::meta_traits::is_pointer);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1190,7 +1188,7 @@ public:
|
|
|
* doesn't refer to a pointer type.
|
|
|
*/
|
|
|
[[nodiscard]] meta_type remove_pointer() const noexcept {
|
|
|
- return meta_type{*ctx, fetch_node().remove_pointer(internal::meta_context::from(*ctx))};
|
|
|
+ return meta_type{*ctx, node->remove_pointer(internal::meta_context::from(*ctx))};
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1198,7 +1196,7 @@ public:
|
|
|
* @return True if the underlying type is pointer-like, false otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool is_pointer_like() const noexcept {
|
|
|
- return !!(fetch_node().traits & internal::meta_traits::is_pointer_like);
|
|
|
+ return !!(node->traits & internal::meta_traits::is_pointer_like);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1206,7 +1204,7 @@ public:
|
|
|
* @return True if the type is a sequence container, false otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool is_sequence_container() const noexcept {
|
|
|
- return !!(fetch_node().traits & internal::meta_traits::is_sequence_container);
|
|
|
+ return !!(node->traits & internal::meta_traits::is_sequence_container);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1214,7 +1212,7 @@ public:
|
|
|
* @return True if the type is an associative container, false otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool is_associative_container() const noexcept {
|
|
|
- return !!(fetch_node().traits & internal::meta_traits::is_associative_container);
|
|
|
+ return !!(node->traits & internal::meta_traits::is_associative_container);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1222,7 +1220,7 @@ public:
|
|
|
* @return True if the type is a template specialization, false otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool is_template_specialization() const noexcept {
|
|
|
- return (fetch_node().templ.arity != 0u);
|
|
|
+ return (node->templ.arity != 0u);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1230,7 +1228,7 @@ public:
|
|
|
* @return The number of template arguments.
|
|
|
*/
|
|
|
[[nodiscard]] size_type template_arity() const noexcept {
|
|
|
- return fetch_node().templ.arity;
|
|
|
+ return node->templ.arity;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1238,7 +1236,7 @@ public:
|
|
|
* @return The tag for the class template of the underlying type.
|
|
|
*/
|
|
|
[[nodiscard]] meta_type template_type() const noexcept {
|
|
|
- return (fetch_node().templ.resolve != nullptr) ? meta_type{*ctx, fetch_node().templ.resolve(internal::meta_context::from(*ctx))} : meta_type{};
|
|
|
+ return (node->templ.resolve != nullptr) ? meta_type{*ctx, node->templ.resolve(internal::meta_context::from(*ctx))} : meta_type{};
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1247,7 +1245,7 @@ public:
|
|
|
* @return The type of the i-th template argument of a type.
|
|
|
*/
|
|
|
[[nodiscard]] meta_type template_arg(const size_type index) const noexcept {
|
|
|
- return index < template_arity() ? meta_type{*ctx, fetch_node().templ.arg(internal::meta_context::from(*ctx), index)} : meta_type{};
|
|
|
+ return index < template_arity() ? meta_type{*ctx, node->templ.arg(internal::meta_context::from(*ctx), index)} : meta_type{};
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1257,7 +1255,7 @@ public:
|
|
|
*/
|
|
|
[[nodiscard]] bool can_cast(const meta_type &other) const noexcept {
|
|
|
// casting this is UB in all cases but we aren't going to use the resulting pointer, so...
|
|
|
- return other && ((*this == other) || (internal::try_cast(internal::meta_context::from(*ctx), fetch_node(), other.fetch_node().info->hash(), this) != nullptr));
|
|
|
+ return other && ((*this == other) || (internal::try_cast(internal::meta_context::from(*ctx), *node, other.node->info->hash(), this) != nullptr));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1266,14 +1264,14 @@ public:
|
|
|
* @return True if the conversion is allowed, false otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] bool can_convert(const meta_type &other) const noexcept {
|
|
|
- if(const auto &to = other.info().hash(); (info().hash() == to) || ((fetch_node().conversion_helper != nullptr) && (other.is_arithmetic() || other.is_enum()))) {
|
|
|
+ if(const auto &to = other.info().hash(); (info().hash() == to) || ((node->conversion_helper != nullptr) && (other.is_arithmetic() || other.is_enum()))) {
|
|
|
return true;
|
|
|
- } else if(const auto &from = fetch_node(); from.details) {
|
|
|
- if(const auto *elem = internal::find_member(from.details->conv, to); elem != nullptr) {
|
|
|
+ } else if(node->details) {
|
|
|
+ if(const auto *elem = internal::find_member(node->details->conv, to); elem != nullptr) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- for(auto &&curr: from.details->base) {
|
|
|
+ for(auto &&curr: node->details->base) {
|
|
|
if(curr.id == to || meta_type{*ctx, curr.type(internal::meta_context::from(*ctx))}.can_convert(other)) {
|
|
|
return true;
|
|
|
}
|
|
|
@@ -1289,7 +1287,7 @@ public:
|
|
|
*/
|
|
|
[[nodiscard]] meta_range<meta_base, decltype(internal::meta_type_descriptor::base)::const_iterator> base() const noexcept {
|
|
|
using range_type = meta_range<meta_base, decltype(internal::meta_type_descriptor::base)::const_iterator>;
|
|
|
- return fetch_node().details ? range_type{{*ctx, fetch_node().details->base.cbegin()}, {*ctx, fetch_node().details->base.cend()}} : range_type{};
|
|
|
+ return node->details ? range_type{{*ctx, node->details->base.cbegin()}, {*ctx, node->details->base.cend()}} : range_type{};
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1298,7 +1296,7 @@ public:
|
|
|
*/
|
|
|
[[nodiscard]] meta_range<meta_data, decltype(internal::meta_type_descriptor::data)::const_iterator> data() const noexcept {
|
|
|
using range_type = meta_range<meta_data, decltype(internal::meta_type_descriptor::data)::const_iterator>;
|
|
|
- return fetch_node().details ? range_type{{*ctx, fetch_node().details->data.cbegin()}, {*ctx, fetch_node().details->data.cend()}} : range_type{};
|
|
|
+ return node->details ? range_type{{*ctx, node->details->data.cbegin()}, {*ctx, node->details->data.cend()}} : range_type{};
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1308,7 +1306,7 @@ public:
|
|
|
* @return The registered meta data for the given identifier, if any.
|
|
|
*/
|
|
|
[[nodiscard]] meta_data data(const id_type id, const bool recursive = true) const {
|
|
|
- const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), fetch_node(), id, recursive);
|
|
|
+ const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), *node, id, recursive);
|
|
|
return (elem != nullptr) ? meta_data{*ctx, *elem} : meta_data{};
|
|
|
}
|
|
|
|
|
|
@@ -1318,7 +1316,7 @@ public:
|
|
|
*/
|
|
|
[[nodiscard]] meta_range<meta_func, decltype(internal::meta_type_descriptor::func)::const_iterator> func() const noexcept {
|
|
|
using return_type = meta_range<meta_func, decltype(internal::meta_type_descriptor::func)::const_iterator>;
|
|
|
- return fetch_node().details ? return_type{{*ctx, fetch_node().details->func.cbegin()}, {*ctx, fetch_node().details->func.cend()}} : return_type{};
|
|
|
+ return node->details ? return_type{{*ctx, node->details->func.cbegin()}, {*ctx, node->details->func.cend()}} : return_type{};
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1328,7 +1326,7 @@ public:
|
|
|
* @return The registered meta function for the given identifier, if any.
|
|
|
*/
|
|
|
[[nodiscard]] meta_func func(const id_type id, const bool recursive = true) const {
|
|
|
- const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), fetch_node(), id, recursive);
|
|
|
+ const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), *node, id, recursive);
|
|
|
return (elem != nullptr) ? meta_func{*ctx, *elem} : meta_func{};
|
|
|
}
|
|
|
|
|
|
@@ -1338,14 +1336,14 @@ public:
|
|
|
* @return A wrapper containing the new instance, if any.
|
|
|
*/
|
|
|
[[nodiscard]] meta_any construct(auto &&...args) const {
|
|
|
- if(const auto &ref = fetch_node(); ref.details) {
|
|
|
- if(const auto *candidate = lookup(stl::array<meta_handle, sizeof...(args)>{meta_handle{*ctx, args}...}.data(), sizeof...(args), false, [first = ref.details->ctor.cbegin(), last = ref.details->ctor.cend()]() mutable { return first == last ? nullptr : &*(first++); }); candidate) {
|
|
|
+ if(node->details) {
|
|
|
+ if(const auto *candidate = lookup(stl::array<meta_handle, sizeof...(args)>{meta_handle{*ctx, args}...}.data(), sizeof...(args), false, [first = node->details->ctor.cbegin(), last = node->details->ctor.cend()]() mutable { return first == last ? nullptr : &*(first++); }); candidate) {
|
|
|
return candidate->invoke(*ctx, stl::array<meta_any, sizeof...(args)>{meta_any{*ctx, stl::forward<decltype(args)>(args)}...}.data());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if(const auto &ref = fetch_node(); (sizeof...(args) == 0u) && (ref.default_constructor != nullptr)) {
|
|
|
- return ref.default_constructor(*ctx);
|
|
|
+ if((sizeof...(args) == 0u) && (node->default_constructor != nullptr)) {
|
|
|
+ return node->default_constructor(*ctx);
|
|
|
}
|
|
|
|
|
|
return meta_any{meta_ctx_arg, *ctx};
|
|
|
@@ -1358,7 +1356,7 @@ public:
|
|
|
* @return A wrapper that references the given instance.
|
|
|
*/
|
|
|
[[nodiscard]] meta_any from_void(void *elem, bool transfer_ownership = false) const {
|
|
|
- return ((elem != nullptr) && (fetch_node().from_void != nullptr)) ? fetch_node().from_void(*ctx, elem, transfer_ownership ? elem : nullptr) : meta_any{meta_ctx_arg, *ctx};
|
|
|
+ return ((elem != nullptr) && (node->from_void != nullptr)) ? node->from_void(*ctx, elem, transfer_ownership ? elem : nullptr) : meta_any{meta_ctx_arg, *ctx};
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1367,7 +1365,7 @@ public:
|
|
|
* @return A wrapper that references the given instance.
|
|
|
*/
|
|
|
[[nodiscard]] meta_any from_void(const void *elem) const {
|
|
|
- return ((elem != nullptr) && (fetch_node().from_void != nullptr)) ? fetch_node().from_void(*ctx, nullptr, elem) : meta_any{meta_ctx_arg, *ctx};
|
|
|
+ return ((elem != nullptr) && (node->from_void != nullptr)) ? node->from_void(*ctx, nullptr, elem) : meta_any{meta_ctx_arg, *ctx};
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1383,8 +1381,8 @@ public:
|
|
|
meta_any invoke(const id_type id, Instance &&instance, auto &&...args) const {
|
|
|
meta_handle wrapped{*ctx, stl::forward<Instance>(instance)};
|
|
|
|
|
|
- if(const auto &ref = fetch_node(); ref.details) {
|
|
|
- if(auto *elem = internal::find_member(ref.details->func, id); elem != nullptr) {
|
|
|
+ if(node->details) {
|
|
|
+ if(auto *elem = internal::find_member(node->details->func, id); elem != nullptr) {
|
|
|
if(const auto *candidate = lookup(stl::array<meta_handle, sizeof...(args)>{meta_handle{*ctx, args}...}.data(), sizeof...(args), (wrapped->base().policy() == any_policy::cref), [curr = elem]() mutable { return (curr != nullptr) ? stl::exchange(curr, curr->next.get()) : nullptr; }); candidate) {
|
|
|
return candidate->invoke(stl::move(wrapped), stl::array<meta_any, sizeof...(args)>{meta_any{*ctx, stl::forward<decltype(args)>(args)}...}.data());
|
|
|
}
|
|
|
@@ -1432,27 +1430,28 @@ public:
|
|
|
/*! @copydoc meta_data::traits */
|
|
|
template<typename Type>
|
|
|
[[nodiscard]] Type traits() const noexcept {
|
|
|
- return internal::meta_to_user_traits<Type>(fetch_node().traits);
|
|
|
+ return internal::meta_to_user_traits<Type>(node->traits);
|
|
|
}
|
|
|
|
|
|
/*! @copydoc meta_data::custom */
|
|
|
[[nodiscard]] meta_custom custom() const noexcept {
|
|
|
- return fetch_node().custom;
|
|
|
+ return node->custom;
|
|
|
}
|
|
|
|
|
|
/*! @copydoc meta_data::operator bool */
|
|
|
[[nodiscard]] explicit operator bool() const noexcept {
|
|
|
- return (node != nullptr);
|
|
|
+ return initialized;
|
|
|
}
|
|
|
|
|
|
/*! @copydoc meta_data::operator== */
|
|
|
[[nodiscard]] bool operator==(const meta_type &other) const noexcept {
|
|
|
- return (ctx == other.ctx) && (fetch_node().alias == other.fetch_node().alias);
|
|
|
+ return (ctx == other.ctx) && (node->alias == other.node->alias);
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
|
|
|
const internal::meta_type_node *node{};
|
|
|
+ bool initialized{};
|
|
|
};
|
|
|
|
|
|
[[nodiscard]] inline meta_type meta_any::type() const noexcept {
|