Class meta_factory< Type, Spec... >
Synopsis
#include <src/entt/meta/factory.hpp>
template<typename Type, typename... Spec>
class meta_factory<Type, Spec...>: public meta_factory<Type>
Description
Extended meta factory to be used for reflection purposes.
- Template Parameters
Type
- Reflected type for which the factory was created.Spec
- Property specialization pack used to disambiguate overloads.
Inheritance
Ancestors: meta_factory< Type >
Methods
meta_factory | Constructs an extended factory from a given node. | |
prop | Assigns a property to the last meta object created. | |
props | Assigns properties to the last meta object created. |
Source
Lines 38-133 in src/entt/meta/factory.hpp.
template<typename Type, typename... Spec>
class meta_factory<Type, Spec...>: public meta_factory<Type> {
void link_prop_if_required(internal::meta_prop_node &node) ENTT_NOEXCEPT {
if(meta_range<internal::meta_prop_node *, internal::meta_prop_node> range{*ref}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [&node](const auto *curr) { return curr->id == node.id; }) == range.cend(), "Duplicate identifier");
node.next = *ref;
*ref = &node;
}
}
template<std::size_t Step = 0, typename... Property, typename... Other>
void unroll(choice_t<2>, std::tuple<Property...> property, Other &&...other) ENTT_NOEXCEPT {
std::apply([this](auto &&...curr) { (this->unroll<Step>(choice<2>, std::forward<Property>(curr)...)); }, property);
unroll<Step + sizeof...(Property)>(choice<2>, std::forward<Other>(other)...);
}
template<std::size_t Step = 0, typename... Property, typename... Other>
void unroll(choice_t<1>, std::pair<Property...> property, Other &&...other) ENTT_NOEXCEPT {
assign<Step>(std::move(property.first), std::move(property.second));
unroll<Step + 1>(choice<2>, std::forward<Other>(other)...);
}
template<std::size_t Step = 0, typename Property, typename... Other>
void unroll(choice_t<0>, Property &&property, Other &&...other) ENTT_NOEXCEPT {
assign<Step>(std::forward<Property>(property));
unroll<Step + 1>(choice<2>, std::forward<Other>(other)...);
}
template<std::size_t>
void unroll(choice_t<0>) ENTT_NOEXCEPT {}
template<std::size_t = 0>
void assign(meta_any key, meta_any value = {}) {
static meta_any property[2u]{};
static internal::meta_prop_node node{
nullptr,
property[0u],
property[1u]
// tricks clang-format
};
property[0u] = std::move(key);
property[1u] = std::move(value);
link_prop_if_required(node);
}
public:
/**
* @brief Constructs an extended factory from a given node.
* @param target The underlying node to which to assign the properties.
*/
meta_factory(internal::meta_prop_node **target) ENTT_NOEXCEPT
: ref{target} {}
/**
* @brief Assigns a property to the last meta object created.
*
* Both the key and the value (if any) must be at least copy constructible.
*
* @tparam PropertyOrKey Type of the property or property key.
* @tparam Value Optional type of the property value.
* @param property_or_key Property or property key.
* @param value Optional property value.
* @return A meta factory for the parent type.
*/
template<typename PropertyOrKey, typename... Value>
meta_factory<Type> prop(PropertyOrKey &&property_or_key, Value &&...value) {
if constexpr(sizeof...(Value) == 0) {
unroll(choice<2>, std::forward<PropertyOrKey>(property_or_key));
} else {
assign(std::forward<PropertyOrKey>(property_or_key), std::forward<Value>(value)...);
}
return {};
}
/**
* @brief Assigns properties to the last meta object created.
*
* Both key and value (if any) must be at least copy constructible.
*
* @tparam Property Types of the properties.
* @param property Properties to assign to the last meta object created.
* @return A meta factory for the parent type.
*/
template<typename... Property>
meta_factory<Type> props(Property... property) {
unroll(choice<2>, std::forward<Property>(property)...);
return {};
}
private:
internal::meta_prop_node **ref;
};