Assignable wrapper (C++20)

From cppreference.com
Ranges library
Range adaptors
Helper items
copyable-box
movable-box
(until C++23) (C++23)


template < class T >

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

class /*copyable-box*/ ;
(since C++20)
(until C++23)
( exposition only* )
template < class T >

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

class /*movable-box*/ ;
(since C++23)
( exposition only* )

ranges::single_view , ranges::repeat_view , (since C++23) and range adaptors that store an invocable object are specified in terms of an exposition-only class template copyable-box (until C++23) movable-box (since C++23) . The name shown here is for exposition purposes only.

The wrapper 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 augments T with assignability when needed and makes it always satisfy copyable or movable (since C++23) .

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.

(until C++23)

If T

/*movable-box*/ < T > may store only a T object, because it always contains a value.

(since C++23)

Template parameters

T - the type of the contained value, must be an object type that models copy_constructible (until C++23) move_constructible (since C++23)

Member functions

Default constructor

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

requires std:: default_initializable < T >

: /*copyable-box*/ ( std:: in_place ) { }
(since C++20)
(until C++23)
constexpr /*movable-box*/ ( ) noexcept ( std:: is_nothrow_default_constructible_v < T > )

requires std:: default_initializable < T >

: /*movable-box*/ ( std:: in_place ) { }
(since C++23)

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

A default-constructed wrapper contains a value-initialized T object.

Assignment operators

(1)
constexpr /*copyable-box*/ & operator = ( const /*copyable-box*/ & other ) ;
noexcept ( /* see below */ ) ;
(since C++20)
(until C++23)
constexpr /*movable-box*/ & operator = ( const /*movable-box*/ & other ) ;
noexcept ( /* see below */ ) requires std:: copy_constructible < T > ;
(since C++23)
(2)
constexpr /*copyable-box*/ & operator = ( /*copyable-box*/ && other )
noexcept ( std:: is_nothrow_move_constructible_v < T > ) ;
(since C++20)
(until C++23)
constexpr /*movable-box*/ & operator = ( /*movable-box*/ && other )
noexcept ( std:: is_nothrow_move_constructible_v < T > ) ;
(since C++23)
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 ;
}

(until C++23)

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

return * this ;
}

(since C++23)
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 ;
}

(until C++23)

constexpr /*movable-box*/ & operator = ( /*movable-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 ;
}

(since C++23)
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 (until C++23) movable-box (since C++23) 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).

Feature-test macro Value Std Feature
__cpp_lib_ranges 201911L (C++20) Ranges library and constrained algorithms
202106L (C++20)
(DR)
Non- default-initializable views
202207L (C++23) Relaxing range adaptors to allow for move-only types

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 consisting of a generated sequence by repeatedly producing the same 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 results of application of a transformation function to corresponding elements of the adapted views
(class template) (customization point object)
a view consisting of results of application of a transformation function to adjacent elements of the adapted view
(class template) (range adaptor object)