Class object_ref

Synopsis

#include <include/type_safe/reference.hpp>

template <typename T, bool XValue /* = false*/>
class object_ref

Description

A reference to an object of some type T.

Unlike [std::reference_wrapper]() it does not try to model reference semantics, instead it is basically a non-null pointer to a single object. This allows rebinding on assignment. Apart from the different access syntax it can be safely used instead of a reference, and is safe for all kinds of containers.

If the given type is const, it will only return a const reference, but then XValue must be false.

If XValue is true, dereferencing will [std::move()]() the object, modelling a reference to an expiring lvalue. \notes T is the type without the reference, ie. object_ref<int>.

Mentioned in

Methods

object_ref overload\effects Binds the reference to the given object
object_ref overload\group ctor_assign
getReturns: A native reference to the referenced object
map\effects Invokes the function with the referred object followed by the arguments.
operator*\group deref
operator->Member access operator.
operator=\group ctor_assign

Source

Lines 56-133 in include/type_safe/reference.hpp.

template <typename T, bool XValue /* = false*/>
class object_ref
{
    static_assert(!std::is_void<T>::value, "must not be void");
    static_assert(!std::is_reference<T>::value, "pass the type without reference");
    static_assert(!XValue || !std::is_const<T>::value, "must not be const if xvalue reference");

    T* ptr_;

public:
    using value_type     = T;
    using reference_type = typename std::conditional<XValue, T&&, T&>::type;

    /// \effects Binds the reference to the given object.
    /// \notes This constructor will only participate in overload resolution
    /// if `U` is a compatible type (i.e. non-const variant or derived type).
    /// \group ctor_assign
    /// \param 1
    /// \exclude
    template <typename U, typename = decltype(std::declval<T*&>() = std::declval<U*>())>
    explicit constexpr object_ref(U& obj) noexcept : ptr_(&obj)
    {}

    /// \group ctor_assign
    /// \param 1
    /// \exclude
    template <typename U, typename = decltype(std::declval<T*&>() = std::declval<U*>())>
    constexpr object_ref(const object_ref<U>& obj) noexcept : ptr_(&*obj)
    {}

    /// \group ctor_assign
    /// \param 1
    /// \exclude
    template <typename U, typename = decltype(std::declval<T*&>() = std::declval<U*>())>
    object_ref& operator=(const object_ref<U>& obj) noexcept
    {
        ptr_ = &*obj;
        return *this;
    }

    /// \returns A native reference to the referenced object.
    /// if `XValue` is true, this will be an rvalue reference,
    /// else an lvalue reference.
    /// \group deref
    constexpr reference_type get() const noexcept
    {
        return **this;
    }

    /// \group deref
    constexpr reference_type operator*() const noexcept
    {
        return static_cast<reference_type>(*ptr_);
    }

    /// Member access operator.
    constexpr T* operator->() const noexcept
    {
        return ptr_;
    }

    /// \effects Invokes the function with the referred object followed by the arguments.
    /// \returns A [ts::object_ref]() to the result of the function,
    /// if `*this` is an xvalue reference, the result is as well.
    /// \requires The function must return an lvalue or another [ts::object_ref]() object.
    template <typename Func, typename... Args>
    auto map(Func&& f, Args&&... args)
        -> detail::rebind_object_ref<decltype(detail::map_invoke(std::forward<Func>(f),
                                                                 std::declval<object_ref&>().get(),
                                                                 std::forward<Args>(args)...)),
                                     XValue>
    {
        using result = decltype(
            detail::map_invoke(std::forward<Func>(f), get(), std::forward<Args>(args)...));
        return detail::rebind_object_ref<result, XValue>(
            detail::map_invoke(std::forward<Func>(f), get(), std::forward<Args>(args)...));
    }
};





Add Discussion as Guest

Log in