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_factoryConstructs an extended factory from a given node.
propAssigns a property to the last meta object created.
propsAssigns 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;
};





Add Discussion

Log in to comment