1278 lines
52 KiB
Markdown
1278 lines
52 KiB
Markdown
[optional.optional]
|
||
|
||
# 22 General utilities library [[utilities]](./#utilities)
|
||
|
||
## 22.5 Optional objects [[optional]](optional#optional)
|
||
|
||
### 22.5.3 Class template optional [optional.optional]
|
||
|
||
#### [22.5.3.1](#general) General [[optional.optional.general]](optional.optional.general)
|
||
|
||
[ð](#lib:optional)
|
||
|
||
namespace std {template<class T>class optional {public:using value_type = T; using iterator = *implementation-defined*; // see [[optional.iterators]](#optional.iterators "22.5.3.6 Iterator support")using const_iterator = *implementation-defined*; // see [[optional.iterators]](#optional.iterators "22.5.3.6 Iterator support")// [[optional.ctor]](#optional.ctor "22.5.3.2 Constructors"), constructorsconstexpr optional() noexcept; constexpr optional(nullopt_t) noexcept; constexpr optional(const optional&); constexpr optional(optional&&) noexcept(*see below*); template<class... Args>constexpr explicit optional(in_place_t, Args&&...); template<class U, class... Args>constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...); template<class U = remove_cv_t<T>>constexpr explicit(*see below*) optional(U&&); template<class U>constexpr explicit(*see below*) optional(const optional<U>&); template<class U>constexpr explicit(*see below*) optional(optional<U>&&); // [[optional.dtor]](#optional.dtor "22.5.3.3 Destructor"), destructorconstexpr ~optional(); // [[optional.assign]](#optional.assign "22.5.3.4 Assignment"), assignmentconstexpr optional& operator=(nullopt_t) noexcept; constexpr optional& operator=(const optional&); constexpr optional& operator=(optional&&) noexcept(*see below*); template<class U = remove_cv_t<T>> constexpr optional& operator=(U&&); template<class U> constexpr optional& operator=(const optional<U>&); template<class U> constexpr optional& operator=(optional<U>&&); template<class... Args> constexpr T& emplace(Args&&...); template<class U, class... Args> constexpr T& emplace(initializer_list<U>, Args&&...); // [[optional.swap]](#optional.swap "22.5.3.5 Swap"), swapconstexpr void swap(optional&) noexcept(*see below*); // [[optional.iterators]](#optional.iterators "22.5.3.6 Iterator support"), iterator supportconstexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; // [[optional.observe]](#optional.observe "22.5.3.7 Observers"), observersconstexpr const T* operator->() const noexcept; constexpr T* operator->() noexcept; constexpr const T& operator*() const & noexcept; constexpr T& operator*() & noexcept; constexpr T&& operator*() && noexcept; constexpr const T&& operator*() const && noexcept; constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr const T& value() const &; // freestanding-deletedconstexpr T& value() &; // freestanding-deletedconstexpr T&& value() &&; // freestanding-deletedconstexpr const T&& value() const &&; // freestanding-deletedtemplate<class U = remove_cv_t<T>> constexpr T value_or(U&&) const &; template<class U = remove_cv_t<T>> constexpr T value_or(U&&) &&; // [[optional.monadic]](#optional.monadic "22.5.3.8 Monadic operations"), monadic operationstemplate<class F> constexpr auto and_then(F&& f) &; template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &; template<class F> constexpr auto and_then(F&& f) const &&; template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &; template<class F> constexpr auto transform(F&& f) const &&; template<class F> constexpr optional or_else(F&& f) &&; template<class F> constexpr optional or_else(F&& f) const &; // [[optional.mod]](#optional.mod "22.5.3.9 Modifiers"), modifiersconstexpr void reset() noexcept; private: T* *val*; // *exposition only*}; template<class T> optional(T) -> optional<T>;}
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3364)
|
||
|
||
Any instance of optional<T> at any given time either contains a value or does not contain a value[.](#general-1.sentence-1)
|
||
|
||
When an instance of optional<T> [*contains a value*](#def:contains_a_value,optional "22.5.3.1 General [optional.optional.general]"),
|
||
it means that an object of type T, referred to as the optional object's [*contained value*](#def:contained_value,optional "22.5.3.1 General [optional.optional.general]"),
|
||
is nested within ([[intro.object]](intro.object "6.8.2 Object model")) the optional object[.](#general-1.sentence-2)
|
||
|
||
When an object of type optional<T> is contextually converted to bool,
|
||
the conversion returns true if the object contains a value;
|
||
otherwise the conversion returns false[.](#general-1.sentence-3)
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3373)
|
||
|
||
When an optional<T> object contains a value,
|
||
member val points to the contained value[.](#general-2.sentence-1)
|
||
|
||
[3](#general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3377)
|
||
|
||
A type X is a[*valid contained type*](#def:valid_contained_type,optional "22.5.3.1 General [optional.optional.general]") for optional if X is an lvalue reference type or a complete non-array object type,
|
||
and remove_cvref_t<X> is a type other than in_place_t or nullopt_t[.](#general-3.sentence-1)
|
||
|
||
If a specialization of optional is instantiated with a type T that is not a valid contained type for optional, the program is ill-formed[.](#general-3.sentence-2)
|
||
|
||
If T is an object type,T shall meet the *Cpp17Destructible* requirements (Table [35](utility.arg.requirements#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements"))[.](#general-3.sentence-3)
|
||
|
||
#### [22.5.3.2](#optional.ctor) Constructors [[optional.ctor]](optional.ctor)
|
||
|
||
[1](#optional.ctor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3389)
|
||
|
||
The exposition-only variable template *converts-from-any-cvref* is used by some constructors for optional[.](#optional.ctor-1.sentence-1)
|
||
|
||
template<class T, class W>constexpr bool *converts-from-any-cvref* = // *exposition only* disjunction_v<is_constructible<T, W&>, is_convertible<W&, T>,
|
||
is_constructible<T, W>, is_convertible<W, T>,
|
||
is_constructible<T, const W&>, is_convertible<const W&, T>,
|
||
is_constructible<T, const W>, is_convertible<const W, T>>;
|
||
|
||
[ð](#lib:optional,constructor)
|
||
|
||
`constexpr optional() noexcept;
|
||
constexpr optional(nullopt_t) noexcept;
|
||
`
|
||
|
||
[2](#optional.ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3408)
|
||
|
||
*Postconditions*: *this does not contain a value[.](#optional.ctor-2.sentence-1)
|
||
|
||
[3](#optional.ctor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3412)
|
||
|
||
*Remarks*: No contained value is initialized[.](#optional.ctor-3.sentence-1)
|
||
|
||
For every object type T these constructors are constexpr constructors ([[dcl.constexpr]](dcl.constexpr "9.2.6 The constexpr and consteval specifiers"))[.](#optional.ctor-3.sentence-2)
|
||
|
||
[ð](#lib:optional,constructor_)
|
||
|
||
`constexpr optional(const optional& rhs);
|
||
`
|
||
|
||
[4](#optional.ctor-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3424)
|
||
|
||
*Effects*: If rhs contains a value, direct-non-list-initializes the contained value
|
||
with *rhs[.](#optional.ctor-4.sentence-1)
|
||
|
||
[5](#optional.ctor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3429)
|
||
|
||
*Postconditions*: rhs.has_value() == this->has_value()[.](#optional.ctor-5.sentence-1)
|
||
|
||
[6](#optional.ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3433)
|
||
|
||
*Throws*: Any exception thrown by the selected constructor of T[.](#optional.ctor-6.sentence-1)
|
||
|
||
[7](#optional.ctor-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3437)
|
||
|
||
*Remarks*: This constructor is defined as deleted unlessis_copy_constructible_v<T> is true[.](#optional.ctor-7.sentence-1)
|
||
|
||
If is_trivially_copy_constructible_v<T> is true,
|
||
this constructor is trivial[.](#optional.ctor-7.sentence-2)
|
||
|
||
[ð](#lib:optional,constructor__)
|
||
|
||
`constexpr optional(optional&& rhs) noexcept(see below);
|
||
`
|
||
|
||
[8](#optional.ctor-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3451)
|
||
|
||
*Constraints*: is_move_constructible_v<T> is true[.](#optional.ctor-8.sentence-1)
|
||
|
||
[9](#optional.ctor-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3455)
|
||
|
||
*Effects*: If rhs contains a value, direct-non-list-initializes the contained value
|
||
with *std::move(rhs)[.](#optional.ctor-9.sentence-1)
|
||
|
||
rhs.has_value() is unchanged[.](#optional.ctor-9.sentence-2)
|
||
|
||
[10](#optional.ctor-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3461)
|
||
|
||
*Postconditions*: rhs.has_value() == this->has_value()[.](#optional.ctor-10.sentence-1)
|
||
|
||
[11](#optional.ctor-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3465)
|
||
|
||
*Throws*: Any exception thrown by the selected constructor of T[.](#optional.ctor-11.sentence-1)
|
||
|
||
[12](#optional.ctor-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3469)
|
||
|
||
*Remarks*: The exception specification is equivalent tois_nothrow_move_constructible_v<T>[.](#optional.ctor-12.sentence-1)
|
||
|
||
If is_trivially_move_constructible_v<T> is true,
|
||
this constructor is trivial[.](#optional.ctor-12.sentence-2)
|
||
|
||
[ð](#lib:optional,constructor___)
|
||
|
||
`template<class... Args> constexpr explicit optional(in_place_t, Args&&... args);
|
||
`
|
||
|
||
[13](#optional.ctor-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3483)
|
||
|
||
*Constraints*: is_constructible_v<T, Args...> is true[.](#optional.ctor-13.sentence-1)
|
||
|
||
[14](#optional.ctor-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3487)
|
||
|
||
*Effects*: Direct-non-list-initializes the contained value with std::forward<Args>(args)...[.](#optional.ctor-14.sentence-1)
|
||
|
||
[15](#optional.ctor-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3491)
|
||
|
||
*Postconditions*: *this contains a value[.](#optional.ctor-15.sentence-1)
|
||
|
||
[16](#optional.ctor-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3495)
|
||
|
||
*Throws*: Any exception thrown by the selected constructor of T[.](#optional.ctor-16.sentence-1)
|
||
|
||
[17](#optional.ctor-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3499)
|
||
|
||
*Remarks*: If T's constructor selected for the initialization is a constexpr constructor, this constructor is a constexpr constructor[.](#optional.ctor-17.sentence-1)
|
||
|
||
[ð](#lib:optional,constructor____)
|
||
|
||
`template<class U, class... Args>
|
||
constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
|
||
`
|
||
|
||
[18](#optional.ctor-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3511)
|
||
|
||
*Constraints*: is_constructible_v<T, initializer_list<U>&, Args...> is true[.](#optional.ctor-18.sentence-1)
|
||
|
||
[19](#optional.ctor-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3515)
|
||
|
||
*Effects*: Direct-non-list-initializes the contained value with il, std::forward<Args>(args)...[.](#optional.ctor-19.sentence-1)
|
||
|
||
[20](#optional.ctor-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3519)
|
||
|
||
*Postconditions*: *this contains a value[.](#optional.ctor-20.sentence-1)
|
||
|
||
[21](#optional.ctor-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3523)
|
||
|
||
*Throws*: Any exception thrown by the selected constructor of T[.](#optional.ctor-21.sentence-1)
|
||
|
||
[22](#optional.ctor-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3527)
|
||
|
||
*Remarks*: If T's constructor selected for the initialization is a constexpr constructor, this constructor is a constexpr constructor[.](#optional.ctor-22.sentence-1)
|
||
|
||
[ð](#lib:optional,constructor_____)
|
||
|
||
`template<class U = remove_cv_t<T>> constexpr explicit(see below) optional(U&& v);
|
||
`
|
||
|
||
[23](#optional.ctor-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3538)
|
||
|
||
*Constraints*:
|
||
|
||
- [(23.1)](#optional.ctor-23.1)
|
||
|
||
is_constructible_v<T, U> is true,
|
||
|
||
- [(23.2)](#optional.ctor-23.2)
|
||
|
||
is_same_v<remove_cvref_t<U>, in_place_t> is false,
|
||
|
||
- [(23.3)](#optional.ctor-23.3)
|
||
|
||
is_same_v<remove_cvref_t<U>, optional> is false, and
|
||
|
||
- [(23.4)](#optional.ctor-23.4)
|
||
|
||
if T is cv bool,remove_cvref_t<U> is not a specialization of optional[.](#optional.ctor-23.sentence-1)
|
||
|
||
[24](#optional.ctor-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3548)
|
||
|
||
*Effects*: Direct-non-list-initializes the contained value with std::forward<U>(v)[.](#optional.ctor-24.sentence-1)
|
||
|
||
[25](#optional.ctor-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3552)
|
||
|
||
*Postconditions*: *this contains a value[.](#optional.ctor-25.sentence-1)
|
||
|
||
[26](#optional.ctor-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3556)
|
||
|
||
*Throws*: Any exception thrown by the selected constructor of T[.](#optional.ctor-26.sentence-1)
|
||
|
||
[27](#optional.ctor-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3560)
|
||
|
||
*Remarks*: If T's selected constructor is a constexpr constructor,
|
||
this constructor is a constexpr constructor[.](#optional.ctor-27.sentence-1)
|
||
|
||
The expression inside explicit is equivalent to:!is_convertible_v<U, T>
|
||
|
||
[ð](#lib:optional,constructor______)
|
||
|
||
`template<class U> constexpr explicit(see below) optional(const optional<U>& rhs);
|
||
`
|
||
|
||
[28](#optional.ctor-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3576)
|
||
|
||
*Constraints*:
|
||
|
||
- [(28.1)](#optional.ctor-28.1)
|
||
|
||
is_constructible_v<T, const U&> is true, and
|
||
|
||
- [(28.2)](#optional.ctor-28.2)
|
||
|
||
if T is not cv bool,*converts-from-any-cvref*<T, optional<U>> is false[.](#optional.ctor-28.sentence-1)
|
||
|
||
[29](#optional.ctor-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3584)
|
||
|
||
*Effects*: If rhs contains a value,
|
||
direct-non-list-initializes the contained value with *rhs[.](#optional.ctor-29.sentence-1)
|
||
|
||
[30](#optional.ctor-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3589)
|
||
|
||
*Postconditions*: rhs.has_value() == this->has_value()[.](#optional.ctor-30.sentence-1)
|
||
|
||
[31](#optional.ctor-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3593)
|
||
|
||
*Throws*: Any exception thrown by the selected constructor of T[.](#optional.ctor-31.sentence-1)
|
||
|
||
[32](#optional.ctor-32)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3597)
|
||
|
||
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<const U&, T>
|
||
|
||
[ð](#lib:optional,constructor_______)
|
||
|
||
`template<class U> constexpr explicit(see below) optional(optional<U>&& rhs);
|
||
`
|
||
|
||
[33](#optional.ctor-33)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3611)
|
||
|
||
*Constraints*:
|
||
|
||
- [(33.1)](#optional.ctor-33.1)
|
||
|
||
is_constructible_v<T, U> is true, and
|
||
|
||
- [(33.2)](#optional.ctor-33.2)
|
||
|
||
if T is not cv bool,*converts-from-any-cvref*<T, optional<U>> is false[.](#optional.ctor-33.sentence-1)
|
||
|
||
[34](#optional.ctor-34)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3619)
|
||
|
||
*Effects*: If rhs contains a value,
|
||
direct-non-list-initializes the contained value with *std::move(rhs)[.](#optional.ctor-34.sentence-1)
|
||
|
||
rhs.has_value() is unchanged[.](#optional.ctor-34.sentence-2)
|
||
|
||
[35](#optional.ctor-35)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3625)
|
||
|
||
*Postconditions*: rhs.has_value() == this->has_value()[.](#optional.ctor-35.sentence-1)
|
||
|
||
[36](#optional.ctor-36)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3629)
|
||
|
||
*Throws*: Any exception thrown by the selected constructor of T[.](#optional.ctor-36.sentence-1)
|
||
|
||
[37](#optional.ctor-37)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3633)
|
||
|
||
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<U, T>
|
||
|
||
#### [22.5.3.3](#optional.dtor) Destructor [[optional.dtor]](optional.dtor)
|
||
|
||
[ð](#lib:optional,destructor)
|
||
|
||
`constexpr ~optional();
|
||
`
|
||
|
||
[1](#optional.dtor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3649)
|
||
|
||
*Effects*: If is_trivially_destructible_v<T> != true and *this contains a value, callsval->T::~T()
|
||
|
||
[2](#optional.dtor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3656)
|
||
|
||
*Remarks*: If is_trivially_destructible_v<T> is true, then this destructor is trivial[.](#optional.dtor-2.sentence-1)
|
||
|
||
#### [22.5.3.4](#optional.assign) Assignment [[optional.assign]](optional.assign)
|
||
|
||
[ð](#lib:operator=,optional)
|
||
|
||
`constexpr optional<T>& operator=(nullopt_t) noexcept;
|
||
`
|
||
|
||
[1](#optional.assign-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3669)
|
||
|
||
*Effects*: If *this contains a value, calls val->T::~T() to destroy the contained value; otherwise no effect[.](#optional.assign-1.sentence-1)
|
||
|
||
[2](#optional.assign-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3673)
|
||
|
||
*Postconditions*: *this does not contain a value[.](#optional.assign-2.sentence-1)
|
||
|
||
[3](#optional.assign-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3677)
|
||
|
||
*Returns*: *this[.](#optional.assign-3.sentence-1)
|
||
|
||
[ð](#lib:operator=,optional_)
|
||
|
||
`constexpr optional<T>& operator=(const optional& rhs);
|
||
`
|
||
|
||
[4](#optional.assign-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3688)
|
||
|
||
*Effects*: See Table [67](#tab:optional.assign.copy "Table 67: optional::operator=(const optional&) effects")[.](#optional.assign-4.sentence-1)
|
||
|
||
Table [67](#tab:optional.assign.copy) — optional::operator=(const optional&) effects [[tab:optional.assign.copy]](./tab:optional.assign.copy)
|
||
|
||
| [ð](#tab:optional.assign.copy-row-1) | | ***this contains a value** | ***this does not contain a value** |
|
||
| --- | --- | --- | --- |
|
||
| [ð](#tab:optional.assign.copy-row-2)<br>**rhs contains a value** | | assigns *rhs to the contained value | direct-non-list-initializes the contained value with *rhs |
|
||
| [ð](#tab:optional.assign.copy-row-3)<br>**rhs does not contain a value** | | destroys the contained value by calling val->T::~T() | no effect |
|
||
|
||
[5](#optional.assign-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3705)
|
||
|
||
*Postconditions*: rhs.has_value() == this->has_value()[.](#optional.assign-5.sentence-1)
|
||
|
||
[6](#optional.assign-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3709)
|
||
|
||
*Returns*: *this[.](#optional.assign-6.sentence-1)
|
||
|
||
[7](#optional.assign-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3713)
|
||
|
||
*Remarks*: If any exception is thrown, the result of the expression this->has_value() remains unchanged[.](#optional.assign-7.sentence-1)
|
||
|
||
If an exception is thrown during the call to T's copy constructor, no effect[.](#optional.assign-7.sentence-2)
|
||
|
||
If an exception is thrown during the call to T's copy assignment,
|
||
the state of its contained value is as defined by the exception safety guarantee of T's copy assignment[.](#optional.assign-7.sentence-3)
|
||
|
||
This operator is defined as deleted unlessis_copy_constructible_v<T> is true andis_copy_assignable_v<T> is true[.](#optional.assign-7.sentence-4)
|
||
|
||
If is_trivially_copy_constructible_v<T> &&is_trivially_copy_assignable_v<T> &&is_trivially_destructible_v<T> is true,
|
||
this assignment operator is trivial[.](#optional.assign-7.sentence-5)
|
||
|
||
[ð](#lib:operator=,optional__)
|
||
|
||
`constexpr optional& operator=(optional&& rhs) noexcept(see below);
|
||
`
|
||
|
||
[8](#optional.assign-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3734)
|
||
|
||
*Constraints*: is_move_constructible_v<T> is true andis_move_assignable_v<T> is true[.](#optional.assign-8.sentence-1)
|
||
|
||
[9](#optional.assign-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3739)
|
||
|
||
*Effects*: See Table [68](#tab:optional.assign.move "Table 68: optional::operator=(optional&&) effects")[.](#optional.assign-9.sentence-1)
|
||
|
||
The result of the expression rhs.has_value() remains unchanged[.](#optional.assign-9.sentence-2)
|
||
|
||
Table [68](#tab:optional.assign.move) — optional::operator=(optional&&) effects [[tab:optional.assign.move]](./tab:optional.assign.move)
|
||
|
||
| [ð](#tab:optional.assign.move-row-1) | | ***this contains a value** | ***this does not contain a value** |
|
||
| --- | --- | --- | --- |
|
||
| [ð](#tab:optional.assign.move-row-2)<br>**rhs contains a value** | | assigns *std::move(rhs) to the contained value | direct-non-list-initializes the contained value with *std::move(rhs) |
|
||
| [ð](#tab:optional.assign.move-row-3)<br>**rhs does not contain a value** | | destroys the contained value by calling val->T::~T() | no effect |
|
||
|
||
[10](#optional.assign-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3757)
|
||
|
||
*Postconditions*: rhs.has_value() == this->has_value()[.](#optional.assign-10.sentence-1)
|
||
|
||
[11](#optional.assign-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3761)
|
||
|
||
*Returns*: *this[.](#optional.assign-11.sentence-1)
|
||
|
||
[12](#optional.assign-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3765)
|
||
|
||
*Remarks*: The exception specification is equivalent to:is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T>
|
||
|
||
[13](#optional.assign-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3772)
|
||
|
||
If any exception is thrown, the result of the expression this->has_value() remains unchanged[.](#optional.assign-13.sentence-1)
|
||
|
||
If an exception is thrown during the call to T's move constructor,
|
||
the state of *rhs.val is determined by the exception safety guarantee of T's move constructor[.](#optional.assign-13.sentence-2)
|
||
|
||
If an exception is thrown during the call to T's move assignment,
|
||
the state of *val and *rhs.val is determined by the exception safety guarantee of T's move assignment[.](#optional.assign-13.sentence-3)
|
||
|
||
If is_trivially_move_constructible_v<T> &&is_trivially_move_assignable_v<T> &&is_trivially_destructible_v<T> is true,
|
||
this assignment operator is trivial[.](#optional.assign-13.sentence-4)
|
||
|
||
[ð](#lib:operator=,optional___)
|
||
|
||
`template<class U = remove_cv_t<T>> constexpr optional& operator=(U&& v);
|
||
`
|
||
|
||
[14](#optional.assign-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3790)
|
||
|
||
*Constraints*:
|
||
|
||
- [(14.1)](#optional.assign-14.1)
|
||
|
||
is_same_v<remove_cvref_t<U>, optional> is false,
|
||
|
||
- [(14.2)](#optional.assign-14.2)
|
||
|
||
conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>> is false,
|
||
|
||
- [(14.3)](#optional.assign-14.3)
|
||
|
||
is_constructible_v<T, U> is true, and
|
||
|
||
- [(14.4)](#optional.assign-14.4)
|
||
|
||
is_assignable_v<T&, U> is true[.](#optional.assign-14.sentence-1)
|
||
|
||
[15](#optional.assign-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3799)
|
||
|
||
*Effects*: If *this contains a value, assigns std::forward<U>(v) to the contained value; otherwise direct-non-list-initializes the contained value with std::forward<U>(v)[.](#optional.assign-15.sentence-1)
|
||
|
||
[16](#optional.assign-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3803)
|
||
|
||
*Postconditions*: *this contains a value[.](#optional.assign-16.sentence-1)
|
||
|
||
[17](#optional.assign-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3807)
|
||
|
||
*Returns*: *this[.](#optional.assign-17.sentence-1)
|
||
|
||
[18](#optional.assign-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3811)
|
||
|
||
*Remarks*: If any exception is thrown, the result of the expression this->has_value() remains unchanged[.](#optional.assign-18.sentence-1)
|
||
|
||
If an exception is thrown during the call to T's constructor, the state of v is determined by the exception safety guarantee of T's constructor[.](#optional.assign-18.sentence-2)
|
||
|
||
If an exception is thrown during the call to T's assignment, the state of *val and v is determined by the exception safety guarantee of T's assignment[.](#optional.assign-18.sentence-3)
|
||
|
||
[ð](#lib:operator=,optional____)
|
||
|
||
`template<class U> constexpr optional<T>& operator=(const optional<U>& rhs);
|
||
`
|
||
|
||
[19](#optional.assign-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3822)
|
||
|
||
*Constraints*:
|
||
|
||
- [(19.1)](#optional.assign-19.1)
|
||
|
||
is_constructible_v<T, const U&> is true,
|
||
|
||
- [(19.2)](#optional.assign-19.2)
|
||
|
||
is_assignable_v<T&, const U&> is true,
|
||
|
||
- [(19.3)](#optional.assign-19.3)
|
||
|
||
*converts-from-any-cvref*<T, optional<U>> is false,
|
||
|
||
- [(19.4)](#optional.assign-19.4)
|
||
|
||
is_assignable_v<T&, optional<U>&> is false,
|
||
|
||
- [(19.5)](#optional.assign-19.5)
|
||
|
||
is_assignable_v<T&, optional<U>&&> is false,
|
||
|
||
- [(19.6)](#optional.assign-19.6)
|
||
|
||
is_assignable_v<T&, const optional<U>&> is false, and
|
||
|
||
- [(19.7)](#optional.assign-19.7)
|
||
|
||
is_assignable_v<T&, const optional<U>&&> is false[.](#optional.assign-19.sentence-1)
|
||
|
||
[20](#optional.assign-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3834)
|
||
|
||
*Effects*: See Table [69](#tab:optional.assign.copy.templ "Table 69: optional::operator=(const optional<U>&) effects")[.](#optional.assign-20.sentence-1)
|
||
|
||
Table [69](#tab:optional.assign.copy.templ) — optional::operator=(const optional<U>&) effects [[tab:optional.assign.copy.templ]](./tab:optional.assign.copy.templ)
|
||
|
||
| [ð](#tab:optional.assign.copy.templ-row-1) | | ***this contains a value** | ***this does not contain a value** |
|
||
| --- | --- | --- | --- |
|
||
| [ð](#tab:optional.assign.copy.templ-row-2)<br>**rhs contains a value** | | assigns *rhs to the contained value | direct-non-list-initializes the contained value with *rhs |
|
||
| [ð](#tab:optional.assign.copy.templ-row-3)<br>**rhs does not contain a value** | | destroys the contained value by calling val->T::~T() | no effect |
|
||
|
||
[21](#optional.assign-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3851)
|
||
|
||
*Postconditions*: rhs.has_value() == this->has_value()[.](#optional.assign-21.sentence-1)
|
||
|
||
[22](#optional.assign-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3855)
|
||
|
||
*Returns*: *this[.](#optional.assign-22.sentence-1)
|
||
|
||
[23](#optional.assign-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3859)
|
||
|
||
*Remarks*: If any exception is thrown,
|
||
the result of the expression this->has_value() remains unchanged[.](#optional.assign-23.sentence-1)
|
||
|
||
If an exception is thrown during the call to T's constructor,
|
||
the state of *rhs.val is determined by
|
||
the exception safety guarantee of T's constructor[.](#optional.assign-23.sentence-2)
|
||
|
||
If an exception is thrown during the call to T's assignment,
|
||
the state of *val and *rhs.val is determined by
|
||
the exception safety guarantee of T's assignment[.](#optional.assign-23.sentence-3)
|
||
|
||
[ð](#lib:operator=,optional_____)
|
||
|
||
`template<class U> constexpr optional<T>& operator=(optional<U>&& rhs);
|
||
`
|
||
|
||
[24](#optional.assign-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3877)
|
||
|
||
*Constraints*:
|
||
|
||
- [(24.1)](#optional.assign-24.1)
|
||
|
||
is_constructible_v<T, U> is true,
|
||
|
||
- [(24.2)](#optional.assign-24.2)
|
||
|
||
is_assignable_v<T&, U> is true,
|
||
|
||
- [(24.3)](#optional.assign-24.3)
|
||
|
||
*converts-from-any-cvref*<T, optional<U>> is false,
|
||
|
||
- [(24.4)](#optional.assign-24.4)
|
||
|
||
is_assignable_v<T&, optional<U>&> is false,
|
||
|
||
- [(24.5)](#optional.assign-24.5)
|
||
|
||
is_assignable_v<T&, optional<U>&&> is false,
|
||
|
||
- [(24.6)](#optional.assign-24.6)
|
||
|
||
is_assignable_v<T&, const optional<U>&> is false, and
|
||
|
||
- [(24.7)](#optional.assign-24.7)
|
||
|
||
is_assignable_v<T&, const optional<U>&&> is false[.](#optional.assign-24.sentence-1)
|
||
|
||
[25](#optional.assign-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3889)
|
||
|
||
*Effects*: See Table [70](#tab:optional.assign.move.templ "Table 70: optional::operator=(optional<U>&&) effects")[.](#optional.assign-25.sentence-1)
|
||
|
||
The result of the expression rhs.has_value() remains unchanged[.](#optional.assign-25.sentence-2)
|
||
|
||
Table [70](#tab:optional.assign.move.templ) — optional::operator=(optional<U>&&) effects [[tab:optional.assign.move.templ]](./tab:optional.assign.move.templ)
|
||
|
||
| [ð](#tab:optional.assign.move.templ-row-1) | | ***this contains a value** | ***this does not contain a value** |
|
||
| --- | --- | --- | --- |
|
||
| [ð](#tab:optional.assign.move.templ-row-2)<br>**rhs contains a value** | | assigns *std::move(rhs) to the contained value | direct-non-list-initializes the contained value with *std::move(rhs) |
|
||
| [ð](#tab:optional.assign.move.templ-row-3)<br>**rhs does not contain a value** | | destroys the contained value by calling val->T::~T() | no effect |
|
||
|
||
[26](#optional.assign-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3907)
|
||
|
||
*Postconditions*: rhs.has_value() == this->has_value()[.](#optional.assign-26.sentence-1)
|
||
|
||
[27](#optional.assign-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3911)
|
||
|
||
*Returns*: *this[.](#optional.assign-27.sentence-1)
|
||
|
||
[28](#optional.assign-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3915)
|
||
|
||
*Remarks*: If any exception is thrown,
|
||
the result of the expression this->has_value() remains unchanged[.](#optional.assign-28.sentence-1)
|
||
|
||
If an exception is thrown during the call to T's constructor,
|
||
the state of *rhs.val is determined by
|
||
the exception safety guarantee of T's constructor[.](#optional.assign-28.sentence-2)
|
||
|
||
If an exception is thrown during the call to T's assignment,
|
||
the state of *val and *rhs.val is determined by
|
||
the exception safety guarantee of T's assignment[.](#optional.assign-28.sentence-3)
|
||
|
||
[ð](#lib:emplace,optional)
|
||
|
||
`template<class... Args> constexpr T& emplace(Args&&... args);
|
||
`
|
||
|
||
[29](#optional.assign-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3933)
|
||
|
||
*Mandates*: is_constructible_v<T, Args...> is true[.](#optional.assign-29.sentence-1)
|
||
|
||
[30](#optional.assign-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3937)
|
||
|
||
*Effects*: Calls *this = nullopt[.](#optional.assign-30.sentence-1)
|
||
|
||
Then direct-non-list-initializes the contained value
|
||
with std::forward<Args>(args)...[.](#optional.assign-30.sentence-2)
|
||
|
||
[31](#optional.assign-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3942)
|
||
|
||
*Postconditions*: *this contains a value[.](#optional.assign-31.sentence-1)
|
||
|
||
[32](#optional.assign-32)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3946)
|
||
|
||
*Returns*: A reference to the new contained value[.](#optional.assign-32.sentence-1)
|
||
|
||
[33](#optional.assign-33)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3950)
|
||
|
||
*Throws*: Any exception thrown by the selected constructor of T[.](#optional.assign-33.sentence-1)
|
||
|
||
[34](#optional.assign-34)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3954)
|
||
|
||
*Remarks*: If an exception is thrown during the call to T's constructor, *this does not contain a value, and the previous *val (if any) has been destroyed[.](#optional.assign-34.sentence-1)
|
||
|
||
[ð](#lib:emplace,optional_)
|
||
|
||
`template<class U, class... Args> constexpr T& emplace(initializer_list<U> il, Args&&... args);
|
||
`
|
||
|
||
[35](#optional.assign-35)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3965)
|
||
|
||
*Constraints*: is_constructible_v<T, initializer_list<U>&, Args...> is true[.](#optional.assign-35.sentence-1)
|
||
|
||
[36](#optional.assign-36)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3969)
|
||
|
||
*Effects*: Calls *this = nullopt[.](#optional.assign-36.sentence-1)
|
||
|
||
Then direct-non-list-initializes the contained value withil, std::forward<Args>(args)...[.](#optional.assign-36.sentence-2)
|
||
|
||
[37](#optional.assign-37)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3974)
|
||
|
||
*Postconditions*: *this contains a value[.](#optional.assign-37.sentence-1)
|
||
|
||
[38](#optional.assign-38)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3978)
|
||
|
||
*Returns*: A reference to the new contained value[.](#optional.assign-38.sentence-1)
|
||
|
||
[39](#optional.assign-39)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3982)
|
||
|
||
*Throws*: Any exception thrown by the selected constructor of T[.](#optional.assign-39.sentence-1)
|
||
|
||
[40](#optional.assign-40)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3986)
|
||
|
||
*Remarks*: If an exception is thrown during the call to T's constructor, *this does not contain a value, and the previous *val (if any) has been destroyed[.](#optional.assign-40.sentence-1)
|
||
|
||
#### [22.5.3.5](#optional.swap) Swap [[optional.swap]](optional.swap)
|
||
|
||
[ð](#lib:swap,optional)
|
||
|
||
`constexpr void swap(optional& rhs) noexcept(see below);
|
||
`
|
||
|
||
[1](#optional.swap-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3999)
|
||
|
||
*Mandates*: is_move_constructible_v<T> is true[.](#optional.swap-1.sentence-1)
|
||
|
||
[2](#optional.swap-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4003)
|
||
|
||
*Preconditions*: T meets the [*Cpp17Swappable*](swappable.requirements#:Cpp17Swappable "16.4.4.3 Swappable requirements [swappable.requirements]") requirements ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements"))[.](#optional.swap-2.sentence-1)
|
||
|
||
[3](#optional.swap-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4007)
|
||
|
||
*Effects*: See Table [71](#tab:optional.swap "Table 71: optional::swap(optional&) effects")[.](#optional.swap-3.sentence-1)
|
||
|
||
Table [71](#tab:optional.swap) — optional::swap(optional&) effects [[tab:optional.swap]](./tab:optional.swap)
|
||
|
||
| [ð](#tab:optional.swap-row-1) | | ***this contains a value** | ***this does not contain a value** |
|
||
| --- | --- | --- | --- |
|
||
| [ð](#tab:optional.swap-row-2)<br>**rhs contains a value** | | calls swap(*(*this), *rhs) | direct-non-list-initializes the contained value of *this with std::move(*rhs), followed by rhs.val->T::~T(); postcondition is that *this contains a value and rhs does not contain a value |
|
||
| [ð](#tab:optional.swap-row-3)<br>**rhs does not contain a value** | | direct-non-list-initializes the contained value of rhs with std::move(*(*this)), followed by val->T::~T(); postcondition is that *this does not contain a value and rhs contains a value | no effect |
|
||
|
||
[4](#optional.swap-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4030)
|
||
|
||
*Throws*: Any exceptions thrown by the operations in the relevant part of Table [71](#tab:optional.swap "Table 71: optional::swap(optional&) effects")[.](#optional.swap-4.sentence-1)
|
||
|
||
[5](#optional.swap-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4034)
|
||
|
||
*Remarks*: The exception specification is equivalent to:is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T>
|
||
|
||
[6](#optional.swap-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4041)
|
||
|
||
If any exception is thrown, the results of the expressions this->has_value() and rhs.has_value() remain unchanged[.](#optional.swap-6.sentence-1)
|
||
|
||
If an exception is thrown during the call to function swap,
|
||
the state of *val and *rhs.val is determined by the exception safety guarantee of swap for lvalues of T[.](#optional.swap-6.sentence-2)
|
||
|
||
If an exception is thrown during the call to T's move constructor,
|
||
the state of *val and *rhs.val is determined by the exception safety guarantee of T's move constructor[.](#optional.swap-6.sentence-3)
|
||
|
||
#### [22.5.3.6](#optional.iterators) Iterator support [[optional.iterators]](optional.iterators)
|
||
|
||
[ð](#lib:iterator,optional)
|
||
|
||
`using iterator = implementation-defined;
|
||
using const_iterator = implementation-defined;
|
||
`
|
||
|
||
[1](#optional.iterators-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4059)
|
||
|
||
These types
|
||
model [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14 Concept contiguous_iterator [iterator.concept.contiguous]") ([[iterator.concept.contiguous]](iterator.concept.contiguous "24.3.4.14 Concept contiguous_iterator")),
|
||
meet the [*Cpp17RandomAccessIterator*](random.access.iterators#:Cpp17RandomAccessIterator "24.3.5.7 Random access iterators [random.access.iterators]") requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7 Random access iterators")), and
|
||
meet the requirements for constexpr iterators ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General")),
|
||
with value type remove_cv_t<T>[.](#optional.iterators-1.sentence-1)
|
||
|
||
The reference type is T& for iterator andconst T& for const_iterator[.](#optional.iterators-1.sentence-2)
|
||
|
||
[2](#optional.iterators-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4068)
|
||
|
||
All requirements on container iterators ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")) apply tooptional::iterator and optional::const_iterator as well[.](#optional.iterators-2.sentence-1)
|
||
|
||
[3](#optional.iterators-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4072)
|
||
|
||
Any operation that initializes or destroys the contained value of an optional object invalidates all iterators into that object[.](#optional.iterators-3.sentence-1)
|
||
|
||
[ð](#lib:begin,optional)
|
||
|
||
`constexpr iterator begin() noexcept;
|
||
constexpr const_iterator begin() const noexcept;
|
||
`
|
||
|
||
[4](#optional.iterators-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4083)
|
||
|
||
*Returns*: If has_value() is true,
|
||
an iterator referring to the contained value[.](#optional.iterators-4.sentence-1)
|
||
|
||
Otherwise, a past-the-end iterator value[.](#optional.iterators-4.sentence-2)
|
||
|
||
[ð](#lib:end,optional)
|
||
|
||
`constexpr iterator end() noexcept;
|
||
constexpr const_iterator end() const noexcept;
|
||
`
|
||
|
||
[5](#optional.iterators-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4097)
|
||
|
||
*Returns*: begin() + has_value()[.](#optional.iterators-5.sentence-1)
|
||
|
||
#### [22.5.3.7](#optional.observe) Observers [[optional.observe]](optional.observe)
|
||
|
||
[ð](#lib:operator-%3e,optional)
|
||
|
||
`constexpr const T* operator->() const noexcept;
|
||
constexpr T* operator->() noexcept;
|
||
`
|
||
|
||
[1](#optional.observe-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4111)
|
||
|
||
*Hardened preconditions*: has_value() is true[.](#optional.observe-1.sentence-1)
|
||
|
||
[2](#optional.observe-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4115)
|
||
|
||
*Returns*: val[.](#optional.observe-2.sentence-1)
|
||
|
||
[3](#optional.observe-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4119)
|
||
|
||
*Remarks*: These functions are constexpr functions[.](#optional.observe-3.sentence-1)
|
||
|
||
[ð](#lib:operator*,optional)
|
||
|
||
`constexpr const T& operator*() const & noexcept;
|
||
constexpr T& operator*() & noexcept;
|
||
`
|
||
|
||
[4](#optional.observe-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4131)
|
||
|
||
*Hardened preconditions*: has_value() is true[.](#optional.observe-4.sentence-1)
|
||
|
||
[5](#optional.observe-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4135)
|
||
|
||
*Returns*: *val[.](#optional.observe-5.sentence-1)
|
||
|
||
[6](#optional.observe-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4139)
|
||
|
||
*Remarks*: These functions are constexpr functions[.](#optional.observe-6.sentence-1)
|
||
|
||
[ð](#lib:operator*,optional_)
|
||
|
||
`constexpr T&& operator*() && noexcept;
|
||
constexpr const T&& operator*() const && noexcept;
|
||
`
|
||
|
||
[7](#optional.observe-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4151)
|
||
|
||
*Hardened preconditions*: has_value() is true[.](#optional.observe-7.sentence-1)
|
||
|
||
[8](#optional.observe-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4155)
|
||
|
||
*Effects*: Equivalent to: return std::move(*val);
|
||
|
||
[ð](#lib:operator_bool,optional)
|
||
|
||
`constexpr explicit operator bool() const noexcept;
|
||
`
|
||
|
||
[9](#optional.observe-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4166)
|
||
|
||
*Returns*: true if and only if *this contains a value[.](#optional.observe-9.sentence-1)
|
||
|
||
[10](#optional.observe-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4170)
|
||
|
||
*Remarks*: This function is a constexpr function[.](#optional.observe-10.sentence-1)
|
||
|
||
[ð](#lib:has_value,optional)
|
||
|
||
`constexpr bool has_value() const noexcept;
|
||
`
|
||
|
||
[11](#optional.observe-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4181)
|
||
|
||
*Returns*: true if and only if *this contains a value[.](#optional.observe-11.sentence-1)
|
||
|
||
[12](#optional.observe-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4185)
|
||
|
||
*Remarks*: This function is a constexpr function[.](#optional.observe-12.sentence-1)
|
||
|
||
[ð](#lib:value,optional)
|
||
|
||
`constexpr const T& value() const &;
|
||
constexpr T& value() &;
|
||
`
|
||
|
||
[13](#optional.observe-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4197)
|
||
|
||
*Effects*: Equivalent to:return has_value() ? *val : throw bad_optional_access();
|
||
|
||
[ð](#lib:value,optional_)
|
||
|
||
`constexpr T&& value() &&;
|
||
constexpr const T&& value() const &&;
|
||
`
|
||
|
||
[14](#optional.observe-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4213)
|
||
|
||
*Effects*: Equivalent to:return has_value() ? std::move(*val) : throw bad_optional_access();
|
||
|
||
[ð](#lib:value_or,optional)
|
||
|
||
`template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;
|
||
`
|
||
|
||
[15](#optional.observe-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4227)
|
||
|
||
*Mandates*: is_copy_constructible_v<T> && is_convertible_v<U&&, T> is true[.](#optional.observe-15.sentence-1)
|
||
|
||
[16](#optional.observe-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4231)
|
||
|
||
*Effects*: Equivalent to:return has_value() ? **this : static_cast<T>(std::forward<U>(v));
|
||
|
||
[ð](#lib:value_or,optional_)
|
||
|
||
`template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;
|
||
`
|
||
|
||
[17](#optional.observe-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4245)
|
||
|
||
*Mandates*: is_move_constructible_v<T> && is_convertible_v<U&&, T> is true[.](#optional.observe-17.sentence-1)
|
||
|
||
[18](#optional.observe-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4249)
|
||
|
||
*Effects*: Equivalent to:return has_value() ? std::move(**this) : static_cast<T>(std::forward<U>(v));
|
||
|
||
#### [22.5.3.8](#optional.monadic) Monadic operations [[optional.monadic]](optional.monadic)
|
||
|
||
[ð](#lib:and_then,optional)
|
||
|
||
`template<class F> constexpr auto and_then(F&& f) &;
|
||
template<class F> constexpr auto and_then(F&& f) const &;
|
||
`
|
||
|
||
[1](#optional.monadic-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4266)
|
||
|
||
Let U be invoke_result_t<F, decltype(**val*)>[.](#optional.monadic-1.sentence-1)
|
||
|
||
[2](#optional.monadic-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4269)
|
||
|
||
*Mandates*: remove_cvref_t<U> is a specialization of optional[.](#optional.monadic-2.sentence-1)
|
||
|
||
[3](#optional.monadic-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4273)
|
||
|
||
*Effects*: Equivalent to:if (*this) {return invoke(std::forward<F>(f), **val*);} else {return remove_cvref_t<U>();}
|
||
|
||
[ð](#lib:and_then,optional_)
|
||
|
||
`template<class F> constexpr auto and_then(F&& f) &&;
|
||
template<class F> constexpr auto and_then(F&& f) const &&;
|
||
`
|
||
|
||
[4](#optional.monadic-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4292)
|
||
|
||
Let U be invoke_result_t<F, decltype(std::move(**val*))>[.](#optional.monadic-4.sentence-1)
|
||
|
||
[5](#optional.monadic-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4295)
|
||
|
||
*Mandates*: remove_cvref_t<U> is a specialization of optional[.](#optional.monadic-5.sentence-1)
|
||
|
||
[6](#optional.monadic-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4299)
|
||
|
||
*Effects*: Equivalent to:if (*this) {return invoke(std::forward<F>(f), std::move(**val*));} else {return remove_cvref_t<U>();}
|
||
|
||
[ð](#lib:transform,optional)
|
||
|
||
`template<class F> constexpr auto transform(F&& f) &;
|
||
template<class F> constexpr auto transform(F&& f) const &;
|
||
`
|
||
|
||
[7](#optional.monadic-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4318)
|
||
|
||
Let U be remove_cv_t<invoke_result_t<F, decltype(**val*)>>[.](#optional.monadic-7.sentence-1)
|
||
|
||
[8](#optional.monadic-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4321)
|
||
|
||
*Mandates*: U is a valid contained type for optional[.](#optional.monadic-8.sentence-1)
|
||
|
||
The declarationU u(invoke(std::forward<F>(f), **val*)); is well-formed for some invented variable u[.](#optional.monadic-8.sentence-2)
|
||
|
||
[*Note [1](#optional.monadic-note-1)*:
|
||
|
||
There is no requirement that U is movable ([[dcl.init.general]](dcl.init.general "9.5.1 General"))[.](#optional.monadic-8.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[9](#optional.monadic-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4333)
|
||
|
||
*Returns*: If *this contains a value, an optional<U> object
|
||
whose contained value is direct-non-list-initialized withinvoke(std::forward<F>(f), **val*);
|
||
otherwise, optional<U>()[.](#optional.monadic-9.sentence-1)
|
||
|
||
[ð](#lib:transform,optional_)
|
||
|
||
`template<class F> constexpr auto transform(F&& f) &&;
|
||
template<class F> constexpr auto transform(F&& f) const &&;
|
||
`
|
||
|
||
[10](#optional.monadic-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4348)
|
||
|
||
Let U beremove_cv_t<invoke_result_t<F, decltype(std::move(**val*))>>[.](#optional.monadic-10.sentence-1)
|
||
|
||
[11](#optional.monadic-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4352)
|
||
|
||
*Mandates*: U is a valid contained type for optional[.](#optional.monadic-11.sentence-1)
|
||
|
||
The declarationU u(invoke(std::forward<F>(f), std::move(**val*))); is well-formed for some invented variable u[.](#optional.monadic-11.sentence-2)
|
||
|
||
[*Note [2](#optional.monadic-note-2)*:
|
||
|
||
There is no requirement that U is movable ([[dcl.init.general]](dcl.init.general "9.5.1 General"))[.](#optional.monadic-11.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[12](#optional.monadic-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4364)
|
||
|
||
*Returns*: If *this contains a value, an optional<U> object
|
||
whose contained value is direct-non-list-initialized withinvoke(std::forward<F>(f), std::move(**val*));
|
||
otherwise, optional<U>()[.](#optional.monadic-12.sentence-1)
|
||
|
||
[ð](#lib:or_else,optional)
|
||
|
||
`template<class F> constexpr optional or_else(F&& f) const &;
|
||
`
|
||
|
||
[13](#optional.monadic-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4378)
|
||
|
||
*Constraints*: F models [invocable](concept.invocable#concept:invocable "18.7.2 Concept invocable [concept.invocable]") andT models [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")[.](#optional.monadic-13.sentence-1)
|
||
|
||
[14](#optional.monadic-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4383)
|
||
|
||
*Mandates*: is_same_v<remove_cvref_t<invoke_result_t<F>>, optional> is true[.](#optional.monadic-14.sentence-1)
|
||
|
||
[15](#optional.monadic-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4387)
|
||
|
||
*Effects*: Equivalent to:if (*this) {return *this;} else {return std::forward<F>(f)();}
|
||
|
||
[ð](#lib:or_else,optional_)
|
||
|
||
`template<class F> constexpr optional or_else(F&& f) &&;
|
||
`
|
||
|
||
[16](#optional.monadic-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4405)
|
||
|
||
*Constraints*: F models [invocable](concept.invocable#concept:invocable "18.7.2 Concept invocable [concept.invocable]") andT models [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]")[.](#optional.monadic-16.sentence-1)
|
||
|
||
[17](#optional.monadic-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4410)
|
||
|
||
*Mandates*: is_same_v<remove_cvref_t<invoke_result_t<F>>, optional> is true[.](#optional.monadic-17.sentence-1)
|
||
|
||
[18](#optional.monadic-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4414)
|
||
|
||
*Effects*: Equivalent to:if (*this) {return std::move(*this);} else {return std::forward<F>(f)();}
|
||
|
||
#### [22.5.3.9](#optional.mod) Modifiers [[optional.mod]](optional.mod)
|
||
|
||
[ð](#lib:reset,optional)
|
||
|
||
`constexpr void reset() noexcept;
|
||
`
|
||
|
||
[1](#optional.mod-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4434)
|
||
|
||
*Effects*: If *this contains a value, calls val->T::~T() to destroy the contained value;
|
||
otherwise no effect[.](#optional.mod-1.sentence-1)
|
||
|
||
[2](#optional.mod-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4439)
|
||
|
||
*Postconditions*: *this does not contain a value[.](#optional.mod-2.sentence-1)
|