Class meta_type
Synopsis
#include <src/entt/meta/meta.hpp>
class meta_type
Description
Opaque wrapper for types.
Mentioned in
- Runtime Reflection System / Enjoy the runtime
- Runtime Reflection System / Automatic conversions
Methods
meta_type overload | Constructs an instance from a given node. | |
meta_type overload | Constructs an instance from a given base node. | |
base overload | Returns a range to visit registered top-level base meta types. | |
base overload | Lookup function for registered base meta types. | |
construct overload | Creates an instance of the underlying type, if possible. | |
data overload | Returns a range to visit registered top-level meta data. | |
data overload | Lookup function for registered meta data. | |
func overload | Returns a range to visit registered top-level functions. | |
func overload | Lookup function for registered meta functions. | |
get | Gets the value of a given variable. | |
id | Returns the identifier assigned to a type. | |
info | Returns the type info object of the underlying type. | |
invoke overload | Invokes a function given an identifier, if possible. | |
is_arithmetic | Checks whether a type refers to an arithmetic type or not. | |
is_array | Checks whether a type refers to an array type or not. | |
is_associative_container | Checks whether a type refers to an associative container or not. | |
is_class | Checks whether a type refers to a class or not. | |
is_enum | Checks whether a type refers to an enum or not. | |
is_pointer | Checks whether a type refers to a pointer or not. | |
is_pointer_like | Checks whether a type is a pointer-like type or not. | |
is_sequence_container | Checks whether a type refers to a sequence container or not. | |
is_template_specialization | Checks whether a type refers to a recognized class template specialization or not. | |
operator bool | Returns true if an object is valid, false otherwise. | |
operator== | Checks if two objects refer to the same type. | |
prop overload | Returns a range to visit registered top-level meta properties. | |
prop overload | Lookup function for meta properties. | |
set | Sets the value of a given variable. | |
size_of | Returns the size of the underlying type if known. | |
template_arg | Returns the type of the i-th template argument of a type. | |
template_arity | Returns the number of template arguments. | |
template_type | Returns a tag for the class template of the underlying type. |
Source
Lines 949-1341 in src/entt/meta/meta.hpp.
class meta_type {
template<auto Member, typename Pred>
[[nodiscard]] std::decay_t<decltype(std::declval<internal::meta_type_node>().*Member)> lookup(meta_any *const args, const typename internal::meta_type_node::size_type sz, Pred pred) const {
std::decay_t<decltype(node->*Member)> candidate{};
size_type extent{sz + 1u};
bool ambiguous{};
for(auto *curr = (node->*Member); curr; curr = curr->next) {
if(pred(curr) && curr->arity == sz) {
size_type direct{};
size_type ext{};
for(size_type next{}; next < sz && next == (direct + ext) && args[next]; ++next) {
const auto type = args[next].type();
const auto other = curr->arg(next);
if(const auto &info = other.info(); info == type.info()) {
++direct;
} else {
ext += internal::find_by<&node_type::base>(info, type.node)
|| internal::find_by<&node_type::conv>(info, type.node)
|| (type.node->conversion_helper && other.node->conversion_helper);
}
}
if((direct + ext) == sz) {
if(ext < extent) {
candidate = curr;
extent = ext;
ambiguous = false;
} else if(ext == extent) {
ambiguous = true;
}
}
}
}
return (candidate && !ambiguous) ? candidate : decltype(candidate){};
}
public:
/*! @brief Node type. */
using node_type = internal::meta_type_node;
/*! @brief Node type. */
using base_node_type = internal::meta_base_node;
/*! @brief Unsigned integer type. */
using size_type = typename node_type::size_type;
/*! @copydoc meta_prop::meta_prop */
meta_type(const node_type *curr = nullptr) ENTT_NOEXCEPT
: node{curr} {}
/**
* @brief Constructs an instance from a given base node.
* @param curr The base node with which to construct the instance.
*/
meta_type(const base_node_type *curr) ENTT_NOEXCEPT
: node{curr ? curr->type : nullptr} {}
/**
* @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 ENTT_NOEXCEPT {
return *node->info;
}
/**
* @brief Returns the identifier assigned to a type.
* @return The identifier assigned to the type.
*/
[[nodiscard]] id_type id() const ENTT_NOEXCEPT {
return node->id;
}
/**
* @brief Returns the size of the underlying type if known.
* @return The size of the underlying type if known, 0 otherwise.
*/
[[nodiscard]] size_type size_of() const ENTT_NOEXCEPT {
return node->size_of;
}
/**
* @brief Checks whether a type refers to an arithmetic type or not.
* @return True if the underlying type is an arithmetic type, false
* otherwise.
*/
[[nodiscard]] bool is_arithmetic() const ENTT_NOEXCEPT {
return !!(node->traits & internal::meta_traits::is_arithmetic);
}
/**
* @brief Checks whether a type refers to an array type or not.
* @return True if the underlying type is an array type, false otherwise.
*/
[[nodiscard]] bool is_array() const ENTT_NOEXCEPT {
return !!(node->traits & internal::meta_traits::is_array);
}
/**
* @brief Checks whether a type refers to an enum or not.
* @return True if the underlying type is an enum, false otherwise.
*/
[[nodiscard]] bool is_enum() const ENTT_NOEXCEPT {
return !!(node->traits & internal::meta_traits::is_enum);
}
/**
* @brief Checks whether a type refers to a class or not.
* @return True if the underlying type is a class, false otherwise.
*/
[[nodiscard]] bool is_class() const ENTT_NOEXCEPT {
return !!(node->traits & internal::meta_traits::is_class);
}
/**
* @brief Checks whether a type refers to a pointer or not.
* @return True if the underlying type is a pointer, false otherwise.
*/
[[nodiscard]] bool is_pointer() const ENTT_NOEXCEPT {
return !!(node->traits & internal::meta_traits::is_pointer);
}
/**
* @brief Checks whether a type is a pointer-like type or not.
* @return True if the underlying type is a pointer-like one, false
* otherwise.
*/
[[nodiscard]] bool is_pointer_like() const ENTT_NOEXCEPT {
return !!(node->traits & internal::meta_traits::is_meta_pointer_like);
}
/**
* @brief Checks whether a type refers to a sequence container or not.
* @return True if the type is a sequence container, false otherwise.
*/
[[nodiscard]] bool is_sequence_container() const ENTT_NOEXCEPT {
return !!(node->traits & internal::meta_traits::is_meta_sequence_container);
}
/**
* @brief Checks whether a type refers to an associative container or not.
* @return True if the type is an associative container, false otherwise.
*/
[[nodiscard]] bool is_associative_container() const ENTT_NOEXCEPT {
return !!(node->traits & internal::meta_traits::is_meta_associative_container);
}
/**
* @brief Checks whether a type refers to a recognized class template
* specialization or not.
* @return True if the type is a recognized class template specialization,
* false otherwise.
*/
[[nodiscard]] bool is_template_specialization() const ENTT_NOEXCEPT {
return (node->templ != nullptr);
}
/**
* @brief Returns the number of template arguments.
* @return The number of template arguments.
*/
[[nodiscard]] size_type template_arity() const ENTT_NOEXCEPT {
return node->templ ? node->templ->arity : size_type{};
}
/**
* @brief Returns a tag for the class template of the underlying type.
*
* @sa meta_class_template_tag
*
* @return The tag for the class template of the underlying type.
*/
[[nodiscard]] inline meta_type template_type() const ENTT_NOEXCEPT {
return node->templ ? node->templ->type : meta_type{};
}
/**
* @brief Returns the type of the i-th template argument of a type.
* @param index Index of the template argument of which to return the type.
* @return The type of the i-th template argument of a type.
*/
[[nodiscard]] inline meta_type template_arg(const size_type index) const ENTT_NOEXCEPT {
return index < template_arity() ? node->templ->arg(index) : meta_type{};
}
/**
* @brief Returns a range to visit registered top-level base meta types.
* @return An iterable range to visit registered top-level base meta types.
*/
[[nodiscard]] meta_range<meta_type, internal::meta_base_node> base() const ENTT_NOEXCEPT {
return node->base;
}
/**
* @brief Lookup function for registered base meta types.
* @param id Unique identifier.
* @return The registered base meta type for the given identifier, if any.
*/
[[nodiscard]] meta_type base(const id_type id) const {
return internal::find_by<&node_type::base>(id, node);
}
/**
* @brief Returns a range to visit registered top-level meta data.
* @return An iterable range to visit registered top-level meta data.
*/
[[nodiscard]] meta_range<meta_data> data() const ENTT_NOEXCEPT {
return node->data;
}
/**
* @brief Lookup function for registered meta data.
*
* Registered meta data of base classes will also be visited.
*
* @param id Unique identifier.
* @return The registered meta data for the given identifier, if any.
*/
[[nodiscard]] meta_data data(const id_type id) const {
return internal::find_by<&node_type::data>(id, node);
}
/**
* @brief Returns a range to visit registered top-level functions.
* @return An iterable range to visit registered top-level functions.
*/
[[nodiscard]] meta_range<meta_func> func() const ENTT_NOEXCEPT {
return node->func;
}
/**
* @brief Lookup function for registered meta functions.
*
* Registered meta functions of base classes will also be visited.<br/>
* In case of overloaded functions, the first one with the required
* identifier will be returned.
*
* @param id Unique identifier.
* @return The registered meta function for the given identifier, if any.
*/
[[nodiscard]] meta_func func(const id_type id) const {
return internal::find_by<&node_type::func>(id, node);
}
/**
* @brief Creates an instance of the underlying type, if possible.
*
* Parameters are such that a cast or conversion to the required types is
* possible. Otherwise, an empty and thus invalid wrapper is returned.<br/>
* If suitable, the implicitly generated default constructor is used.
*
* @param args Parameters to use to construct the instance.
* @param sz Number of parameters to use to construct the instance.
* @return A wrapper containing the new instance, if any.
*/
[[nodiscard]] meta_any construct(meta_any *const args, const size_type sz) const {
const auto *candidate = lookup<&node_type::ctor>(args, sz, [](const auto *) { return true; });
return candidate ? candidate->invoke(args) : ((!sz && node->default_constructor) ? node->default_constructor() : meta_any{});
}
/**
* @copybrief construct
*
* @sa construct
*
* @tparam Args Types of arguments to use to construct the instance.
* @param args Parameters to use to construct the instance.
* @return A wrapper containing the new instance, if any.
*/
template<typename... Args>
[[nodiscard]] meta_any construct(Args &&...args) const {
meta_any arguments[sizeof...(Args) + 1u]{std::forward<Args>(args)...};
return construct(arguments, sizeof...(Args));
}
/**
* @brief Invokes a function given an identifier, if possible.
*
* It must be possible to cast the instance to the parent type of the member
* function.
*
* @sa meta_func::invoke
*
* @param id Unique identifier.
* @param instance An opaque instance of the underlying type.
* @param args Parameters to use to invoke the function.
* @param sz Number of parameters to use to invoke the function.
* @return A wrapper containing the returned value, if any.
*/
meta_any invoke(const id_type id, meta_handle instance, meta_any *const args, const size_type sz) const {
const auto *candidate = lookup<&node_type::func>(args, sz, [id](const auto *curr) { return curr->id == id; });
for(auto it = base().begin(), last = base().end(); it != last && !candidate; ++it) {
candidate = it->lookup<&node_type::func>(args, sz, [id](const auto *curr) { return curr->id == id; });
}
return candidate ? candidate->invoke(std::move(instance), args) : meta_any{};
}
/**
* @copybrief invoke
*
* @sa invoke
*
* @param id Unique identifier.
* @tparam Args Types of arguments to use to invoke the function.
* @param instance An opaque instance of the underlying type.
* @param args Parameters to use to invoke the function.
* @return A wrapper containing the new instance, if any.
*/
template<typename... Args>
meta_any invoke(const id_type id, meta_handle instance, Args &&...args) const {
meta_any arguments[sizeof...(Args) + 1u]{std::forward<Args>(args)...};
return invoke(id, std::move(instance), arguments, sizeof...(Args));
}
/**
* @brief Sets the value of a given variable.
*
* It must be possible to cast the instance to the parent type of the data
* member.<br/>
* The type of the value is such that a cast or conversion to the type of
* the variable is possible. Otherwise, invoking the setter does nothing.
*
* @tparam Type Type of value to assign.
* @param id Unique identifier.
* @param instance An opaque instance of the underlying type.
* @param value Parameter to use to set the underlying variable.
* @return True in case of success, false otherwise.
*/
template<typename Type>
bool set(const id_type id, meta_handle instance, Type &&value) const {
const auto candidate = data(id);
return candidate && candidate.set(std::move(instance), std::forward<Type>(value));
}
/**
* @brief Gets the value of a given variable.
*
* It must be possible to cast the instance to the parent type of the data
* member.
*
* @param id Unique identifier.
* @param instance An opaque instance of the underlying type.
* @return A wrapper containing the value of the underlying variable.
*/
[[nodiscard]] meta_any get(const id_type id, meta_handle instance) const {
const auto candidate = data(id);
return candidate ? candidate.get(std::move(instance)) : meta_any{};
}
/**
* @brief Returns a range to visit registered top-level meta properties.
* @return An iterable range to visit registered top-level meta properties.
*/
[[nodiscard]] meta_range<meta_prop> prop() const ENTT_NOEXCEPT {
return node->prop;
}
/**
* @brief Lookup function for meta properties.
*
* Properties of base classes are also visited.
*
* @param key The key to use to search for a property.
* @return The registered meta property for the given key, if any.
*/
[[nodiscard]] meta_prop prop(meta_any key) const {
return internal::find_by<&internal::meta_type_node::prop>(key, node);
}
/**
* @brief Returns true if an object is valid, false otherwise.
* @return True if the object is valid, false otherwise.
*/
[[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
return !(node == nullptr);
}
/**
* @brief Checks if two objects refer to the same type.
* @param other The object with which to compare.
* @return True if the objects refer to the same type, false otherwise.
*/
[[nodiscard]] bool operator==(const meta_type &other) const ENTT_NOEXCEPT {
return (!node && !other.node) || (node && other.node && *node->info == *other.node->info);
}
private:
const node_type *node;
};