Copyable wrapper (C++20)

From cppreference.com
< cpp‎ | ranges
 
 
Ranges library
Range access
Range conversions
(C++23)
Range primitives



Dangling iterator handling
Range concepts
Views

Factories






Adaptors
Range adaptor objects
Range adaptor closure objects
Helper items
copyable-box
 
template<class T>

    requires std::copy_constructible<T> && std::is_object_v<T>

class /*copyable-box*/;
(since C++20)

ranges::single_view and range adaptors that store an invocable object are specified in terms of an exposition-only class template copyable-box. The name copyable-box is for exposition purposes only.

/*copyable-box*/<T> behaves exactly like std::optional<T>, except that the default constructor, copy assignment operator, and move assignment operator are (conditionally) different from those of std::optional, which makes it always satisfy copyable.

If T is already copyable, or both std::is_nothrow_move_constructible_v<T> and std::is_nothrow_copy_constructible_v<T> are true, /*copyable-box*/<T> may store only a T object, because it always contains a value.

Template parameters

T - the type of the contained value, must be a object type that models copy_constructible

Member functions

copyable-box::copyable-box

constexpr /*copyable-box*/() noexcept(std::is_nothrow_default_constructible_v<T>)

    requires std::default_initializable<T>

    : /*copyable-box*/(std::in_place) { }
(since C++20)

The default constructor is provided if and only if T models default_initializable.

A default-constructed /*copyable-box*/<T> contains a value-initialized T object.

copyable-box::operator=

constexpr /*copyable-box*/& operator=(const /*copyable-box*/& other);
    noexcept(/* see below */);
(1) (since C++20)
constexpr /*copyable-box*/& operator=(/*copyable-box*/&& other)
    noexcept(std::is_nothrow_move_constructible_v<T>);
(2) (since C++20)
1) If std::copyable<T> is not modeled, the copy assignment operator is equivalently defined as:

constexpr /*copyable-box*/& operator=(const /*copyable-box*/& other)
    noexcept(std::is_nothrow_copy_constructible_v<T>)
{
    if (this != std::addressof(other)) {
        if (other) emplace(*other);
        else reset();
    }
    return *this;
}

Otherwise, it is identical to the copy assignment operator of std::optional.
2) If std::movable<T> is not modeled, the move assignment operator is equivalently defined as:

constexpr /*copyable-box*/& operator=(/*copyable-box*/&& other)
    noexcept(std::is_nothrow_move_constructible_v<T>)
{
    if (this != std::addressof(other)) {
        if (other) emplace(std::move(*other));
        else reset();
    }
    return *this;
}

Otherwise, it is identical to the move assignment operator of std::optional.

Members identical to std::optional

Member functions

constructs the optional object
(public member function of std::optional<T>)
destroys the contained value, if there is one
(public member function of std::optional<T>)
assigns contents
(public member function of std::optional<T>)
Observers
accesses the contained value
(public member function of std::optional<T>)
checks whether the object contains a value
(public member function of std::optional<T>)
Modifiers
destroys any contained value
(public member function of std::optional<T>)
constructs the contained value in-place
(public member function of std::optional<T>)

Notes

A copyable-box does not contain a value only if

  • T does not model movable or copyable, and an exception is thrown on move assignment or copy assignment respectively, or
  • it is initialized/assigned from another valueless wrapper.

Before P2325R3, the wrapper was called semiregular-box in the standard and always satisfied semiregular, as the default constructor was always provided (which might construct a valueless wrapper).

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
P2325R3 C++20 if T is not default_initializable, the default constructor
constructs a wrapper which does not contain a value
the wrapper is also
not default_initializable
LWG 3572 C++20 conditionally different assignment operators were not constexpr made constexpr

See also

a view that contains a single element of a specified value
(class template) (customization point object)
a view that consists of the elements of a range that satisfies a predicate
(class template) (range adaptor object)
a view of a sequence that applies a transformation function to each element
(class template) (range adaptor object)
a view consisting of the initial elements of another view, until the first element on which a predicate returns false
(class template) (range adaptor object)
a view consisting of the elements of another view, skipping the initial subsequence of elements until the first element where the predicate returns false
(class template) (range adaptor object)
a view consisting of tuples of results of application of a transformation function to corresponding elements of the adapted views
(class template) (customization point object)
a view consisting of tuples of results of application of a transformation function to adjacent elements of the adapted view
(class template) (range adaptor object)