Copyable wrapper (C++20)
template<class T> requires std::copy_constructible<T> && std::is_object_v<T> |
(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> |
(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) |
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;
}
std::optional
.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;
}
std::optional
.Notes
A copyable-box
does not contain a value only if
-
T
does not modelmovable
orcopyable
, 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 constructorconstructs 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) |