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.
basic_poly overloadCopy constructor.
basic_poly overloadMove constructor.
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.
operator=Assignment operator.
resetDestroys contained object.
typeReturns the type of the contained object.

Source

Lines 180-335 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>;

    using vtable_type = typename poly_vtable<Concept, Len, Align>::type;

public:
    /*! @brief Concept type. */
    using concept_type = typename Concept::template type<poly_base<basic_poly>>;

    /*! @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_const_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 Copy constructor.
     * @param other The instance to copy from.
     */
    basic_poly(const basic_poly &other) = default;

    /**
     * @brief Move constructor.
     * @param other The instance to move from.
     */
    basic_poly(basic_poly &&other) ENTT_NOEXCEPT
        : basic_poly{}
    {
        swap(*this, other);
    }

    /**
     * @brief Assignment operator.
     * @param other The instance to assign from.
     * @return This poly object.
     */
    basic_poly & operator=(basic_poly other) {
        swap(other, *this);
        return *this;
    }

    /**
     * @brief Returns the type of the contained object.
     * @return The type of the contained object, if any.
     */
    [[nodiscard]] 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) {
        *this = basic_poly{std::in_place_type<Type>, std::forward<Args>(args)...};
    }

    /*! @brief Destroys contained object */
    void reset() {
        *this = basic_poly{};
    }

    /**
     * @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 !(vtable == nullptr);
    }

    /**
     * @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 Swaps two poly objects.
     * @param lhs A valid poly object.
     * @param rhs A valid poly object.
     */
    friend void swap(basic_poly &lhs, basic_poly &rhs) {
        using std::swap;
        swap(lhs.storage, rhs.storage);
        swap(lhs.vtable, rhs.vtable);
    }

    /**
     * @brief Aliasing constructor.
     * @return A poly that shares a reference to an unmanaged object.
     */
    [[nodiscard]] basic_poly as_ref() ENTT_NOEXCEPT {
        basic_poly ref = std::as_const(*this).as_ref();
        ref.storage = storage.as_ref();
        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;
    const vtable_type *vtable;
};





Add Discussion

Log in to comment