24 Ranges library [ranges]

24.7 Range adaptors [range.adaptors]

24.7.3 Copyable wrapper [range.copy.wrap]

Many types in this subclause are specified in terms of an exposition-only class template copyable-box.
copyable-box<T> behaves exactly like optional<T> with the following differences:
  • copyable-box<T> constrains its type parameter T with copy_­constructible<T> && is_­object_­v<T>.
  • The default constructor of copyable-box<T> is equivalent to: constexpr copyable-box() noexcept(is_nothrow_default_constructible_v<T>) requires default_­initializable<T> : copyable-box{in_place} { }
  • If copyable<T> is not modeled, the copy assignment operator is equivalent to: copyable-box& operator=(const copyable-box& that) noexcept(is_nothrow_copy_constructible_v<T>) { if (this != addressof(that)) { if (that) emplace(*that); else reset(); } return *this; }
  • If movable<T> is not modeled, the move assignment operator is equivalent to: copyable-box& operator=(copyable-box&& that) noexcept(is_nothrow_move_constructible_v<T>) { if (this != addressof(that)) { if (that) emplace(std::move(*that)); else reset(); } return *this; }
Recommended practice: copyable-box<T> should store only a T if either T models copyable or is_­nothrow_­move_­constructible_­v<T> && is_­nothrow_­copy_­constructible_­v<T> is true.