Class basic_poly

Synopsis

#include <src/entt/poly/poly.hpp>

template<typename Concept, std::size_t Len, std::size_t Align>
class basic_poly: private Concept::template type<poly_base<basic_poly<Concept, Len, Align>>>

Description

Static polymorphism made simple and within everyone's reach.

Static polymorphism is a very powerful tool in C++, albeit sometimes cumbersome to obtain.
This class aims to make it simple and easy to use.

Note
Both deduced and defined static virtual tables are supported.
Moreover, the poly class template also works with unmanaged objects.
Template Parameters

Concept - Concept descriptor.

Len - Size of the storage reserved for the small buffer optimization.

Align - Optional alignment requirement.

Mentioned in

Methods

basic_poly overloadDefault constructor.
basic_poly overloadConstructs a poly by directly initializing the new object.
basic_poly overloadConstructs a poly from a given value.
as_ref overloadAliasing constructor.
data overloadReturns an opaque pointer to the contained instance.
emplaceReplaces the contained object by creating a new instance directly.
operator boolReturns false if a poly is empty, true otherwise.
operator-> overloadReturns a pointer to the underlying concept.
resetDestroys contained object.
typeReturns the object type if any, type_id<void>() otherwise.

Source

Lines 192-310 in src/entt/poly/poly.hpp.

template<typename Concept, std::size_t Len, std::size_t Align>
class basic_poly: private Concept::template type<poly_base<basic_poly<Concept, Len, Align>>> {
    /*! @brief A poly base is allowed to snoop into a poly object. */
    friend struct poly_base<basic_poly>;

public:
    /*! @brief Concept type. */
    using concept_type = typename Concept::template type<poly_base<basic_poly>>;
    /*! @brief Virtual table type. */
    using vtable_type = typename poly_vtable<Concept, Len, Align>::type;

    /*! @brief Default constructor. */
    basic_poly() ENTT_NOEXCEPT
        : storage{},
          vtable{} {}

    /**
     * @brief Constructs a poly by directly initializing the new object.
     * @tparam Type Type of object to use to initialize the poly.
     * @tparam Args Types of arguments to use to construct the new instance.
     * @param args Parameters to use to construct the instance.
     */
    template<typename Type, typename... Args>
    explicit basic_poly(std::in_place_type_t<Type>, Args &&...args)
        : storage{std::in_place_type<Type>, std::forward<Args>(args)...},
          vtable{poly_vtable<Concept, Len, Align>::template instance<std::remove_cv_t<std::remove_reference_t<Type>>>()} {}

    /**
     * @brief Constructs a poly from a given value.
     * @tparam Type Type of object to use to initialize the poly.
     * @param value An instance of an object to use to initialize the poly.
     */
    template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, basic_poly>>>
    basic_poly(Type &&value) ENTT_NOEXCEPT
        : basic_poly{std::in_place_type<std::remove_cv_t<std::remove_reference_t<Type>>>, std::forward<Type>(value)} {}

    /**
     * @brief Returns the object type if any, `type_id<void>()` otherwise.
     * @return The object type if any, `type_id<void>()` otherwise.
     */
    [[nodiscard]] const type_info &type() const ENTT_NOEXCEPT {
        return storage.type();
    }

    /**
     * @brief Returns an opaque pointer to the contained instance.
     * @return An opaque pointer the contained instance, if any.
     */
    [[nodiscard]] const void *data() const ENTT_NOEXCEPT {
        return storage.data();
    }

    /*! @copydoc data */
    [[nodiscard]] void *data() ENTT_NOEXCEPT {
        return storage.data();
    }

    /**
     * @brief Replaces the contained object by creating a new instance directly.
     * @tparam Type Type of object to use to initialize the poly.
     * @tparam Args Types of arguments to use to construct the new instance.
     * @param args Parameters to use to construct the instance.
     */
    template<typename Type, typename... Args>
    void emplace(Args &&...args) {
        storage.template emplace<Type>(std::forward<Args>(args)...);
        vtable = poly_vtable<Concept, Len, Align>::template instance<std::remove_cv_t<std::remove_reference_t<Type>>>();
    }

    /*! @brief Destroys contained object */
    void reset() {
        storage.reset();
        vtable = {};
    }

    /**
     * @brief Returns false if a poly is empty, true otherwise.
     * @return False if the poly is empty, true otherwise.
     */
    [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
        return static_cast<bool>(storage);
    }

    /**
     * @brief Returns a pointer to the underlying concept.
     * @return A pointer to the underlying concept.
     */
    [[nodiscard]] concept_type *operator->() ENTT_NOEXCEPT {
        return this;
    }

    /*! @copydoc operator-> */
    [[nodiscard]] const concept_type *operator->() const ENTT_NOEXCEPT {
        return this;
    }

    /**
     * @brief Aliasing constructor.
     * @return A poly that shares a reference to an unmanaged object.
     */
    [[nodiscard]] basic_poly as_ref() ENTT_NOEXCEPT {
        basic_poly ref{};
        ref.storage = storage.as_ref();
        ref.vtable = vtable;
        return ref;
    }

    /*! @copydoc as_ref */
    [[nodiscard]] basic_poly as_ref() const ENTT_NOEXCEPT {
        basic_poly ref{};
        ref.storage = storage.as_ref();
        ref.vtable = vtable;
        return ref;
    }

private:
    basic_any<Len, Align> storage;
    vtable_type vtable;
};





Add Discussion

Log in to comment