[optional] # 22 General utilities library [[utilities]](./#utilities) ## 22.5 Optional objects [optional] ### [22.5.1](#general) General [[optional.general]](optional.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3169) Subclause [optional] describes class template optional that represents optional objects[.](#general-1.sentence-1) An [*optional object*](#def:optional_object "22.5.1 General [optional.general]") is an object that contains the storage for another object and manages the lifetime of this contained object, if any[.](#general-1.sentence-2) The contained object may be initialized after the optional object has been initialized, and may be destroyed before the optional object has been destroyed[.](#general-1.sentence-3) The initialization state of the contained object is tracked by the optional object[.](#general-1.sentence-4) ### [22.5.2](#syn) Header synopsis [[optional.syn]](optional.syn) [🔗](#header:%3coptional%3e) // mostly freestanding#include // see [[compare.syn]](compare.syn "17.12.1 Header synopsis")namespace std {// [[optional.optional]](#optional "22.5.3 Class template optional"), class template optionaltemplateclass optional; // partially freestanding// [[optional.optional.ref]](#optional.ref "22.5.4 Partial specialization of optional for reference types"), partial specialization of optional for lvalue reference typestemplateclass optional; // partially freestandingtemplateconstexpr bool ranges::enable_view> = true; templateconstexpr auto format_kind> = range_format::disabled; templateconstexpr bool ranges::enable_borrowed_range> = true; templateconcept [*is-derived-from-optional*](#concept:is-derived-from-optional "22.5.2 Header synopsis [optional.syn]") = requires(const T& t) { // *exposition only*[](const optional&){ }(t); }; // [[optional.nullopt]](#nullopt "22.5.5 No-value state indicator"), no-value state indicatorstruct nullopt_t{*see below*}; inline constexpr nullopt_t nullopt(*unspecified*); // [[optional.bad.access]](#bad.access "22.5.6 Class bad_­optional_­access"), class bad_optional_accessclass bad_optional_access; // [[optional.relops]](#relops "22.5.7 Relational operators"), relational operatorstemplateconstexpr bool operator==(const optional&, const optional&); templateconstexpr bool operator!=(const optional&, const optional&); templateconstexpr bool operator<(const optional&, const optional&); templateconstexpr bool operator>(const optional&, const optional&); templateconstexpr bool operator<=(const optional&, const optional&); templateconstexpr bool operator>=(const optional&, const optional&); template U>constexpr compare_three_way_result_toperator<=>(const optional&, const optional&); // [[optional.nullops]](#nullops "22.5.8 Comparison with nullopt"), comparison with nullopttemplate constexpr bool operator==(const optional&, nullopt_t) noexcept; templateconstexpr strong_ordering operator<=>(const optional&, nullopt_t) noexcept; // [[optional.comp.with.t]](#comp.with.t "22.5.9 Comparison with T"), comparison with Ttemplate constexpr bool operator==(const optional&, const U&); template constexpr bool operator==(const T&, const optional&); template constexpr bool operator!=(const optional&, const U&); template constexpr bool operator!=(const T&, const optional&); template constexpr bool operator<(const optional&, const U&); template constexpr bool operator<(const T&, const optional&); template constexpr bool operator>(const optional&, const U&); template constexpr bool operator>(const T&, const optional&); template constexpr bool operator<=(const optional&, const U&); template constexpr bool operator<=(const T&, const optional&); template constexpr bool operator>=(const optional&, const U&); template constexpr bool operator>=(const T&, const optional&); templaterequires (![*is-derived-from-optional*](#concept:is-derived-from-optional "22.5.2 Header synopsis [optional.syn]")) && [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4 Concept three_­way_­comparable [cmp.concept]")constexpr compare_three_way_result_toperator<=>(const optional&, const U&); // [[optional.specalg]](#specalg "22.5.10 Specialized algorithms"), specialized algorithmstemplateconstexpr void swap(optional&, optional&) noexcept(*see below*); templateconstexpr optional> make_optional(T&&); templateconstexpr optional make_optional(Args&&... args); templateconstexpr optional make_optional(initializer_list il, Args&&... args); // [[optional.hash]](#hash "22.5.11 Hash support"), hash supporttemplate struct hash; template struct hash>;} ### [22.5.3](#optional) Class template optional [[optional.optional]](optional.optional) #### [22.5.3.1](#optional.general) General [[optional.optional.general]](optional.optional.general) [🔗](#lib:optional) namespace std {templateclass optional {public:using value_type = T; using iterator = *implementation-defined*; // see [[optional.iterators]](#iterators "22.5.3.6 Iterator support")using const_iterator = *implementation-defined*; // see [[optional.iterators]](#iterators "22.5.3.6 Iterator support")// [[optional.ctor]](#ctor "22.5.3.2 Constructors"), constructorsconstexpr optional() noexcept; constexpr optional(nullopt_t) noexcept; constexpr optional(const optional&); constexpr optional(optional&&) noexcept(*see below*); templateconstexpr explicit optional(in_place_t, Args&&...); templateconstexpr explicit optional(in_place_t, initializer_list, Args&&...); template>constexpr explicit(*see below*) optional(U&&); templateconstexpr explicit(*see below*) optional(const optional&); templateconstexpr explicit(*see below*) optional(optional&&); // [[optional.dtor]](#dtor "22.5.3.3 Destructor"), destructorconstexpr ~optional(); // [[optional.assign]](#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> constexpr optional& operator=(U&&); template constexpr optional& operator=(const optional&); template constexpr optional& operator=(optional&&); template constexpr T& emplace(Args&&...); template constexpr T& emplace(initializer_list, Args&&...); // [[optional.swap]](#swap "22.5.3.5 Swap"), swapconstexpr void swap(optional&) noexcept(*see below*); // [[optional.iterators]](#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]](#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> constexpr T value_or(U&&) const &; template> constexpr T value_or(U&&) &&; // [[optional.monadic]](#monadic "22.5.3.8 Monadic operations"), monadic operationstemplate constexpr auto and_then(F&& f) &; template constexpr auto and_then(F&& f) &&; template constexpr auto and_then(F&& f) const &; template constexpr auto and_then(F&& f) const &&; template constexpr auto transform(F&& f) &; template constexpr auto transform(F&& f) &&; template constexpr auto transform(F&& f) const &; template constexpr auto transform(F&& f) const &&; template constexpr optional or_else(F&& f) &&; template constexpr optional or_else(F&& f) const &; // [[optional.mod]](#mod "22.5.3.9 Modifiers"), modifiersconstexpr void reset() noexcept; private: T* *val*; // *exposition only*}; template optional(T) -> optional;} [1](#optional.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3364) Any instance of optional at any given time either contains a value or does not contain a value[.](#optional.general-1.sentence-1) When an instance of optional [*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[.](#optional.general-1.sentence-2) When an object of type optional is contextually converted to bool, the conversion returns true if the object contains a value; otherwise the conversion returns false[.](#optional.general-1.sentence-3) [2](#optional.general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3373) When an optional object contains a value, member val points to the contained value[.](#optional.general-2.sentence-1) [3](#optional.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 is a type other than in_place_t or nullopt_t[.](#optional.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[.](#optional.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"))[.](#optional.general-3.sentence-3) #### [22.5.3.2](#ctor) Constructors [[optional.ctor]](optional.ctor) [1](#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[.](#ctor-1.sentence-1) templateconstexpr bool *converts-from-any-cvref* = // *exposition only* disjunction_v, is_convertible, is_constructible, is_convertible, is_constructible, is_convertible, is_constructible, is_convertible>; [🔗](#lib:optional,constructor) `constexpr optional() noexcept; constexpr optional(nullopt_t) noexcept; ` [2](#ctor-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3408) *Postconditions*: *this does not contain a value[.](#ctor-2.sentence-1) [3](#ctor-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3412) *Remarks*: No contained value is initialized[.](#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"))[.](#ctor-3.sentence-2) [🔗](#lib:optional,constructor_) `constexpr optional(const optional& rhs); ` [4](#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[.](#ctor-4.sentence-1) [5](#ctor-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3429) *Postconditions*: rhs.has_value() == this->has_value()[.](#ctor-5.sentence-1) [6](#ctor-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3433) *Throws*: Any exception thrown by the selected constructor of T[.](#ctor-6.sentence-1) [7](#ctor-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3437) *Remarks*: This constructor is defined as deleted unlessis_copy_constructible_v is true[.](#ctor-7.sentence-1) If is_trivially_copy_constructible_v is true, this constructor is trivial[.](#ctor-7.sentence-2) [🔗](#lib:optional,constructor__) `constexpr optional(optional&& rhs) noexcept(see below); ` [8](#ctor-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3451) *Constraints*: is_move_constructible_v is true[.](#ctor-8.sentence-1) [9](#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)[.](#ctor-9.sentence-1) rhs.has_value() is unchanged[.](#ctor-9.sentence-2) [10](#ctor-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3461) *Postconditions*: rhs.has_value() == this->has_value()[.](#ctor-10.sentence-1) [11](#ctor-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3465) *Throws*: Any exception thrown by the selected constructor of T[.](#ctor-11.sentence-1) [12](#ctor-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3469) *Remarks*: The exception specification is equivalent tois_nothrow_move_constructible_v[.](#ctor-12.sentence-1) If is_trivially_move_constructible_v is true, this constructor is trivial[.](#ctor-12.sentence-2) [🔗](#lib:optional,constructor___) `template constexpr explicit optional(in_place_t, Args&&... args); ` [13](#ctor-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3483) *Constraints*: is_constructible_v is true[.](#ctor-13.sentence-1) [14](#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)...[.](#ctor-14.sentence-1) [15](#ctor-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3491) *Postconditions*: *this contains a value[.](#ctor-15.sentence-1) [16](#ctor-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3495) *Throws*: Any exception thrown by the selected constructor of T[.](#ctor-16.sentence-1) [17](#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[.](#ctor-17.sentence-1) [🔗](#lib:optional,constructor____) `template constexpr explicit optional(in_place_t, initializer_list il, Args&&... args); ` [18](#ctor-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3511) *Constraints*: is_constructible_v&, Args...> is true[.](#ctor-18.sentence-1) [19](#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)...[.](#ctor-19.sentence-1) [20](#ctor-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3519) *Postconditions*: *this contains a value[.](#ctor-20.sentence-1) [21](#ctor-21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3523) *Throws*: Any exception thrown by the selected constructor of T[.](#ctor-21.sentence-1) [22](#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[.](#ctor-22.sentence-1) [🔗](#lib:optional,constructor_____) `template> constexpr explicit(see below) optional(U&& v); ` [23](#ctor-23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3538) *Constraints*: - [(23.1)](#ctor-23.1) is_constructible_v is true, - [(23.2)](#ctor-23.2) is_same_v, in_place_t> is false, - [(23.3)](#ctor-23.3) is_same_v, optional> is false, and - [(23.4)](#ctor-23.4) if T is cv bool,remove_cvref_t is not a specialization of optional[.](#ctor-23.sentence-1) [24](#ctor-24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3548) *Effects*: Direct-non-list-initializes the contained value with std​::​forward(v)[.](#ctor-24.sentence-1) [25](#ctor-25) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3552) *Postconditions*: *this contains a value[.](#ctor-25.sentence-1) [26](#ctor-26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3556) *Throws*: Any exception thrown by the selected constructor of T[.](#ctor-26.sentence-1) [27](#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[.](#ctor-27.sentence-1) The expression inside explicit is equivalent to:!is_convertible_v [🔗](#lib:optional,constructor______) `template constexpr explicit(see below) optional(const optional& rhs); ` [28](#ctor-28) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3576) *Constraints*: - [(28.1)](#ctor-28.1) is_constructible_v is true, and - [(28.2)](#ctor-28.2) if T is not cv bool,*converts-from-any-cvref*> is false[.](#ctor-28.sentence-1) [29](#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[.](#ctor-29.sentence-1) [30](#ctor-30) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3589) *Postconditions*: rhs.has_value() == this->has_value()[.](#ctor-30.sentence-1) [31](#ctor-31) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3593) *Throws*: Any exception thrown by the selected constructor of T[.](#ctor-31.sentence-1) [32](#ctor-32) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3597) *Remarks*: The expression inside explicit is equivalent to:!is_convertible_v [🔗](#lib:optional,constructor_______) `template constexpr explicit(see below) optional(optional&& rhs); ` [33](#ctor-33) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3611) *Constraints*: - [(33.1)](#ctor-33.1) is_constructible_v is true, and - [(33.2)](#ctor-33.2) if T is not cv bool,*converts-from-any-cvref*> is false[.](#ctor-33.sentence-1) [34](#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)[.](#ctor-34.sentence-1) rhs.has_value() is unchanged[.](#ctor-34.sentence-2) [35](#ctor-35) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3625) *Postconditions*: rhs.has_value() == this->has_value()[.](#ctor-35.sentence-1) [36](#ctor-36) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3629) *Throws*: Any exception thrown by the selected constructor of T[.](#ctor-36.sentence-1) [37](#ctor-37) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3633) *Remarks*: The expression inside explicit is equivalent to:!is_convertible_v #### [22.5.3.3](#dtor) Destructor [[optional.dtor]](optional.dtor) [🔗](#lib:optional,destructor) `constexpr ~optional(); ` [1](#dtor-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3649) *Effects*: If is_trivially_destructible_v != true and *this contains a value, callsval->T::~T() [2](#dtor-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3656) *Remarks*: If is_trivially_destructible_v is true, then this destructor is trivial[.](#dtor-2.sentence-1) #### [22.5.3.4](#assign) Assignment [[optional.assign]](optional.assign) [🔗](#lib:operator=,optional) `constexpr optional& operator=(nullopt_t) noexcept; ` [1](#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[.](#assign-1.sentence-1) [2](#assign-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3673) *Postconditions*: *this does not contain a value[.](#assign-2.sentence-1) [3](#assign-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3677) *Returns*: *this[.](#assign-3.sentence-1) [🔗](#lib:operator=,optional_) `constexpr optional& operator=(const optional& rhs); ` [4](#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")[.](#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)
**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)
**rhs does not contain a value** | | destroys the contained value by calling val->T​::​~T() | no effect | [5](#assign-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3705) *Postconditions*: rhs.has_value() == this->has_value()[.](#assign-5.sentence-1) [6](#assign-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3709) *Returns*: *this[.](#assign-6.sentence-1) [7](#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[.](#assign-7.sentence-1) If an exception is thrown during the call to T's copy constructor, no effect[.](#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[.](#assign-7.sentence-3) This operator is defined as deleted unlessis_copy_constructible_v is true andis_copy_assignable_v is true[.](#assign-7.sentence-4) If is_trivially_copy_constructible_v &&is_trivially_copy_assignable_v &&is_trivially_destructible_v is true, this assignment operator is trivial[.](#assign-7.sentence-5) [🔗](#lib:operator=,optional__) `constexpr optional& operator=(optional&& rhs) noexcept(see below); ` [8](#assign-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3734) *Constraints*: is_move_constructible_v is true andis_move_assignable_v is true[.](#assign-8.sentence-1) [9](#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")[.](#assign-9.sentence-1) The result of the expression rhs.has_value() remains unchanged[.](#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)
**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)
**rhs does not contain a value** | | destroys the contained value by calling val->T​::​~T() | no effect | [10](#assign-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3757) *Postconditions*: rhs.has_value() == this->has_value()[.](#assign-10.sentence-1) [11](#assign-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3761) *Returns*: *this[.](#assign-11.sentence-1) [12](#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 && is_nothrow_move_constructible_v [13](#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[.](#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[.](#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[.](#assign-13.sentence-3) If is_trivially_move_constructible_v &&is_trivially_move_assignable_v &&is_trivially_destructible_v is true, this assignment operator is trivial[.](#assign-13.sentence-4) [🔗](#lib:operator=,optional___) `template> constexpr optional& operator=(U&& v); ` [14](#assign-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3790) *Constraints*: - [(14.1)](#assign-14.1) is_same_v, optional> is false, - [(14.2)](#assign-14.2) conjunction_v, is_same>> is false, - [(14.3)](#assign-14.3) is_constructible_v is true, and - [(14.4)](#assign-14.4) is_assignable_v is true[.](#assign-14.sentence-1) [15](#assign-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3799) *Effects*: If *this contains a value, assigns std​::​forward(v) to the contained value; otherwise direct-non-list-initializes the contained value with std​::​forward(v)[.](#assign-15.sentence-1) [16](#assign-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3803) *Postconditions*: *this contains a value[.](#assign-16.sentence-1) [17](#assign-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3807) *Returns*: *this[.](#assign-17.sentence-1) [18](#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[.](#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[.](#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[.](#assign-18.sentence-3) [🔗](#lib:operator=,optional____) `template constexpr optional& operator=(const optional& rhs); ` [19](#assign-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3822) *Constraints*: - [(19.1)](#assign-19.1) is_constructible_v is true, - [(19.2)](#assign-19.2) is_assignable_v is true, - [(19.3)](#assign-19.3) *converts-from-any-cvref*> is false, - [(19.4)](#assign-19.4) is_assignable_v&> is false, - [(19.5)](#assign-19.5) is_assignable_v&&> is false, - [(19.6)](#assign-19.6) is_assignable_v&> is false, and - [(19.7)](#assign-19.7) is_assignable_v&&> is false[.](#assign-19.sentence-1) [20](#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&) effects")[.](#assign-20.sentence-1) Table [69](#tab:optional.assign.copy.templ) — optional​::​operator=(const optional&) 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)
**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)
**rhs does not contain a value** | | destroys the contained value by calling val->T​::​~T() | no effect | [21](#assign-21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3851) *Postconditions*: rhs.has_value() == this->has_value()[.](#assign-21.sentence-1) [22](#assign-22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3855) *Returns*: *this[.](#assign-22.sentence-1) [23](#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[.](#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[.](#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[.](#assign-23.sentence-3) [🔗](#lib:operator=,optional_____) `template constexpr optional& operator=(optional&& rhs); ` [24](#assign-24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3877) *Constraints*: - [(24.1)](#assign-24.1) is_constructible_v is true, - [(24.2)](#assign-24.2) is_assignable_v is true, - [(24.3)](#assign-24.3) *converts-from-any-cvref*> is false, - [(24.4)](#assign-24.4) is_assignable_v&> is false, - [(24.5)](#assign-24.5) is_assignable_v&&> is false, - [(24.6)](#assign-24.6) is_assignable_v&> is false, and - [(24.7)](#assign-24.7) is_assignable_v&&> is false[.](#assign-24.sentence-1) [25](#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&&) effects")[.](#assign-25.sentence-1) The result of the expression rhs.has_value() remains unchanged[.](#assign-25.sentence-2) Table [70](#tab:optional.assign.move.templ) — optional​::​operator=(optional&&) 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)
**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)
**rhs does not contain a value** | | destroys the contained value by calling val->T​::​~T() | no effect | [26](#assign-26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3907) *Postconditions*: rhs.has_value() == this->has_value()[.](#assign-26.sentence-1) [27](#assign-27) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3911) *Returns*: *this[.](#assign-27.sentence-1) [28](#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[.](#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[.](#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[.](#assign-28.sentence-3) [🔗](#lib:emplace,optional) `template constexpr T& emplace(Args&&... args); ` [29](#assign-29) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3933) *Mandates*: is_constructible_v is true[.](#assign-29.sentence-1) [30](#assign-30) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3937) *Effects*: Calls *this = nullopt[.](#assign-30.sentence-1) Then direct-non-list-initializes the contained value with std​::​forward​(args)...[.](#assign-30.sentence-2) [31](#assign-31) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3942) *Postconditions*: *this contains a value[.](#assign-31.sentence-1) [32](#assign-32) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3946) *Returns*: A reference to the new contained value[.](#assign-32.sentence-1) [33](#assign-33) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3950) *Throws*: Any exception thrown by the selected constructor of T[.](#assign-33.sentence-1) [34](#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[.](#assign-34.sentence-1) [🔗](#lib:emplace,optional_) `template constexpr T& emplace(initializer_list il, Args&&... args); ` [35](#assign-35) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3965) *Constraints*: is_constructible_v&, Args...> is true[.](#assign-35.sentence-1) [36](#assign-36) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3969) *Effects*: Calls *this = nullopt[.](#assign-36.sentence-1) Then direct-non-list-initializes the contained value withil, std​::​​forward(args)...[.](#assign-36.sentence-2) [37](#assign-37) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3974) *Postconditions*: *this contains a value[.](#assign-37.sentence-1) [38](#assign-38) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3978) *Returns*: A reference to the new contained value[.](#assign-38.sentence-1) [39](#assign-39) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3982) *Throws*: Any exception thrown by the selected constructor of T[.](#assign-39.sentence-1) [40](#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[.](#assign-40.sentence-1) #### [22.5.3.5](#swap) Swap [[optional.swap]](optional.swap) [🔗](#lib:swap,optional) `constexpr void swap(optional& rhs) noexcept(see below); ` [1](#swap-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3999) *Mandates*: is_move_constructible_v is true[.](#swap-1.sentence-1) [2](#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"))[.](#swap-2.sentence-1) [3](#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")[.](#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)
**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)
**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](#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")[.](#swap-4.sentence-1) [5](#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 && is_nothrow_swappable_v [6](#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[.](#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[.](#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[.](#swap-6.sentence-3) #### [22.5.3.6](#iterators) Iterator support [[optional.iterators]](optional.iterators) [🔗](#lib:iterator,optional) `using iterator = implementation-defined; using const_iterator = implementation-defined; ` [1](#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[.](#iterators-1.sentence-1) The reference type is T& for iterator andconst T& for const_iterator[.](#iterators-1.sentence-2) [2](#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[.](#iterators-2.sentence-1) [3](#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[.](#iterators-3.sentence-1) [🔗](#lib:begin,optional) `constexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; ` [4](#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[.](#iterators-4.sentence-1) Otherwise, a past-the-end iterator value[.](#iterators-4.sentence-2) [🔗](#lib:end,optional) `constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; ` [5](#iterators-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4097) *Returns*: begin() + has_value()[.](#iterators-5.sentence-1) #### [22.5.3.7](#observe) Observers [[optional.observe]](optional.observe) [🔗](#lib:operator-%3e,optional) `constexpr const T* operator->() const noexcept; constexpr T* operator->() noexcept; ` [1](#observe-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4111) *Hardened preconditions*: has_value() is true[.](#observe-1.sentence-1) [2](#observe-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4115) *Returns*: val[.](#observe-2.sentence-1) [3](#observe-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4119) *Remarks*: These functions are constexpr functions[.](#observe-3.sentence-1) [🔗](#lib:operator*,optional) `constexpr const T& operator*() const & noexcept; constexpr T& operator*() & noexcept; ` [4](#observe-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4131) *Hardened preconditions*: has_value() is true[.](#observe-4.sentence-1) [5](#observe-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4135) *Returns*: *val[.](#observe-5.sentence-1) [6](#observe-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4139) *Remarks*: These functions are constexpr functions[.](#observe-6.sentence-1) [🔗](#lib:operator*,optional_) `constexpr T&& operator*() && noexcept; constexpr const T&& operator*() const && noexcept; ` [7](#observe-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4151) *Hardened preconditions*: has_value() is true[.](#observe-7.sentence-1) [8](#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](#observe-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4166) *Returns*: true if and only if *this contains a value[.](#observe-9.sentence-1) [10](#observe-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4170) *Remarks*: This function is a constexpr function[.](#observe-10.sentence-1) [🔗](#lib:has_value,optional) `constexpr bool has_value() const noexcept; ` [11](#observe-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4181) *Returns*: true if and only if *this contains a value[.](#observe-11.sentence-1) [12](#observe-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4185) *Remarks*: This function is a constexpr function[.](#observe-12.sentence-1) [🔗](#lib:value,optional) `constexpr const T& value() const &; constexpr T& value() &; ` [13](#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](#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> constexpr T value_or(U&& v) const &; ` [15](#observe-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4227) *Mandates*: is_copy_constructible_v && is_convertible_v is true[.](#observe-15.sentence-1) [16](#observe-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4231) *Effects*: Equivalent to:return has_value() ? **this : static_cast(std::forward(v)); [🔗](#lib:value_or,optional_) `template> constexpr T value_or(U&& v) &&; ` [17](#observe-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4245) *Mandates*: is_move_constructible_v && is_convertible_v is true[.](#observe-17.sentence-1) [18](#observe-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4249) *Effects*: Equivalent to:return has_value() ? std::move(**this) : static_cast(std::forward(v)); #### [22.5.3.8](#monadic) Monadic operations [[optional.monadic]](optional.monadic) [🔗](#lib:and_then,optional) `template constexpr auto and_then(F&& f) &; template constexpr auto and_then(F&& f) const &; ` [1](#monadic-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4266) Let U be invoke_result_t[.](#monadic-1.sentence-1) [2](#monadic-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4269) *Mandates*: remove_cvref_t is a specialization of optional[.](#monadic-2.sentence-1) [3](#monadic-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4273) *Effects*: Equivalent to:if (*this) {return invoke(std::forward(f), **val*);} else {return remove_cvref_t();} [🔗](#lib:and_then,optional_) `template constexpr auto and_then(F&& f) &&; template constexpr auto and_then(F&& f) const &&; ` [4](#monadic-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4292) Let U be invoke_result_t[.](#monadic-4.sentence-1) [5](#monadic-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4295) *Mandates*: remove_cvref_t is a specialization of optional[.](#monadic-5.sentence-1) [6](#monadic-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4299) *Effects*: Equivalent to:if (*this) {return invoke(std::forward(f), std::move(**val*));} else {return remove_cvref_t();} [🔗](#lib:transform,optional) `template constexpr auto transform(F&& f) &; template constexpr auto transform(F&& f) const &; ` [7](#monadic-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4318) Let U be remove_cv_t>[.](#monadic-7.sentence-1) [8](#monadic-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4321) *Mandates*: U is a valid contained type for optional[.](#monadic-8.sentence-1) The declarationU u(invoke(std::forward(f), **val*)); is well-formed for some invented variable u[.](#monadic-8.sentence-2) [*Note [1](#monadic-note-1)*: There is no requirement that U is movable ([[dcl.init.general]](dcl.init.general "9.5.1 General"))[.](#monadic-8.sentence-3) — *end note*] [9](#monadic-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4333) *Returns*: If *this contains a value, an optional object whose contained value is direct-non-list-initialized withinvoke(std​::​forward(f), **val*); otherwise, optional()[.](#monadic-9.sentence-1) [🔗](#lib:transform,optional_) `template constexpr auto transform(F&& f) &&; template constexpr auto transform(F&& f) const &&; ` [10](#monadic-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4348) Let U beremove_cv_t>[.](#monadic-10.sentence-1) [11](#monadic-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4352) *Mandates*: U is a valid contained type for optional[.](#monadic-11.sentence-1) The declarationU u(invoke(std::forward(f), std::move(**val*))); is well-formed for some invented variable u[.](#monadic-11.sentence-2) [*Note [2](#monadic-note-2)*: There is no requirement that U is movable ([[dcl.init.general]](dcl.init.general "9.5.1 General"))[.](#monadic-11.sentence-3) — *end note*] [12](#monadic-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4364) *Returns*: If *this contains a value, an optional object whose contained value is direct-non-list-initialized withinvoke(std​::​forward(f), std​::​move(**val*)); otherwise, optional()[.](#monadic-12.sentence-1) [🔗](#lib:or_else,optional) `template constexpr optional or_else(F&& f) const &; ` [13](#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]")[.](#monadic-13.sentence-1) [14](#monadic-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4383) *Mandates*: is_same_v>, optional> is true[.](#monadic-14.sentence-1) [15](#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)();} [🔗](#lib:or_else,optional_) `template constexpr optional or_else(F&& f) &&; ` [16](#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]")[.](#monadic-16.sentence-1) [17](#monadic-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4410) *Mandates*: is_same_v>, optional> is true[.](#monadic-17.sentence-1) [18](#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)();} #### [22.5.3.9](#mod) Modifiers [[optional.mod]](optional.mod) [🔗](#lib:reset,optional) `constexpr void reset() noexcept; ` [1](#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[.](#mod-1.sentence-1) [2](#mod-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4439) *Postconditions*: *this does not contain a value[.](#mod-2.sentence-1) ### [22.5.4](#optional.ref) Partial specialization of optional for reference types [[optional.optional.ref]](optional.optional.ref) #### [22.5.4.1](#optional.ref.general) General [[optional.optional.ref.general]](optional.optional.ref.general) namespace std {templateclass optional {public:using value_type = T; using iterator = *implementation-defined*; // see [[optional.ref.iterators]](#ref.iterators "22.5.4.5 Iterator support")public:// [[optional.ref.ctor]](#ref.ctor "22.5.4.2 Constructors"), constructorsconstexpr optional() noexcept = default; constexpr optional(nullopt_t) noexcept : optional() {}constexpr optional(const optional& rhs) noexcept = default; templateconstexpr explicit optional(in_place_t, Arg&& arg); templateconstexpr explicit(*see below*) optional(U&& u) noexcept(*see below*); templateconstexpr explicit(*see below*) optional(optional& rhs) noexcept(*see below*); templateconstexpr explicit(*see below*) optional(const optional& rhs) noexcept(*see below*); templateconstexpr explicit(*see below*) optional(optional&& rhs) noexcept(*see below*); templateconstexpr explicit(*see below*) optional(const optional&& rhs) noexcept(*see below*); constexpr ~optional() = default; // [[optional.ref.assign]](#ref.assign "22.5.4.3 Assignment"), assignmentconstexpr optional& operator=(nullopt_t) noexcept; constexpr optional& operator=(const optional& rhs) noexcept = default; template constexpr T& emplace(U&& u) noexcept(*see below*); // [[optional.ref.swap]](#ref.swap "22.5.4.4 Swap"), swapconstexpr void swap(optional& rhs) noexcept; // [[optional.ref.iterators]](#ref.iterators "22.5.4.5 Iterator support"), iterator supportconstexpr iterator begin() const noexcept; constexpr iterator end() const noexcept; // [[optional.ref.observe]](#ref.observe "22.5.4.6 Observers"), observersconstexpr T* operator->() const noexcept; constexpr T& operator*() const noexcept; constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr T& value() const; // freestanding-deletedtemplate>constexpr remove_cv_t value_or(U&& u) const; // [[optional.ref.monadic]](#ref.monadic "22.5.4.7 Monadic operations"), monadic operationstemplate constexpr auto and_then(F&& f) const; template constexpr optional> transform(F&& f) const; template constexpr optional or_else(F&& f) const; // [[optional.ref.mod]](#ref.mod "22.5.4.8 Modifiers"), modifiersconstexpr void reset() noexcept; private: T* *val* = nullptr; // *exposition only*// [[optional.ref.expos]](#ref.expos "22.5.4.9 Exposition only helper functions"), exposition only helper functionstemplateconstexpr void *convert-ref-init-val*(U&& u); // *exposition only*};} [1](#optional.ref.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4516) An object of optional[*contains a value*](#def:contains_a_value,optional.ref "22.5.4.1 General [optional.optional.ref.general]") if and only if *val* != nullptr is true[.](#optional.ref.general-1.sentence-1) When an optional contains a value, the [*contained value*](#def:contained_value,optional.ref "22.5.4.1 General [optional.optional.ref.general]") is a reference to **val*[.](#optional.ref.general-1.sentence-2) #### [22.5.4.2](#ref.ctor) Constructors [[optional.ref.ctor]](optional.ref.ctor) [🔗](#ref.ctor-itemdecl:1) `template constexpr explicit optional(in_place_t, Arg&& arg); ` [1](#ref.ctor-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4532) *Constraints*: - [(1.1)](#ref.ctor-1.1) is_constructible_v is true, and - [(1.2)](#ref.ctor-1.2) reference_constructs_from_temporary_v is false[.](#ref.ctor-1.sentence-1) [2](#ref.ctor-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4539) *Effects*: Equivalent to: *convert-ref-init-val*(std​::​forward(arg))[.](#ref.ctor-2.sentence-1) [3](#ref.ctor-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4543) *Postconditions*: *this contains a value[.](#ref.ctor-3.sentence-1) [🔗](#ref.ctor-itemdecl:2) `template constexpr explicit(!is_convertible_v) optional(U&& u) noexcept(is_nothrow_constructible_v); ` [4](#ref.ctor-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4555) *Constraints*: - [(4.1)](#ref.ctor-4.1) is_same_v, optional> is false, - [(4.2)](#ref.ctor-4.2) is_same_v, in_place_t> is false, and - [(4.3)](#ref.ctor-4.3) is_constructible_v is true[.](#ref.ctor-4.sentence-1) [5](#ref.ctor-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4563) *Effects*: Equivalent to: *convert-ref-init-val*(std​::​forward(u))[.](#ref.ctor-5.sentence-1) [6](#ref.ctor-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4567) *Postconditions*: *this contains a value[.](#ref.ctor-6.sentence-1) [7](#ref.ctor-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4571) *Remarks*: This constructor is defined as deleted ifreference_constructs_from_temporary_v is true[.](#ref.ctor-7.sentence-1) [🔗](#ref.ctor-itemdecl:3) `template constexpr explicit(!is_convertible_v) optional(optional& rhs) noexcept(is_nothrow_constructible_v); ` [8](#ref.ctor-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4587) *Constraints*: - [(8.1)](#ref.ctor-8.1) is_same_v, optional> is false, - [(8.2)](#ref.ctor-8.2) is_same_v is false, and - [(8.3)](#ref.ctor-8.3) is_constructible_v is true[.](#ref.ctor-8.sentence-1) [9](#ref.ctor-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4595) *Effects*: Equivalent to:if (rhs.has_value()) *convert-ref-init-val*(*rhs); [10](#ref.ctor-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4602) *Remarks*: This constructor is defined as deleted ifreference_constructs_from_temporary_v is true[.](#ref.ctor-10.sentence-1) [🔗](#ref.ctor-itemdecl:4) `template constexpr explicit(!is_convertible_v) optional(const optional& rhs) noexcept(is_nothrow_constructible_v); ` [11](#ref.ctor-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4618) *Constraints*: - [(11.1)](#ref.ctor-11.1) is_same_v, optional> is false, - [(11.2)](#ref.ctor-11.2) is_same_v is false, and - [(11.3)](#ref.ctor-11.3) is_constructible_v is true[.](#ref.ctor-11.sentence-1) [12](#ref.ctor-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4626) *Effects*: Equivalent to:if (rhs.has_value()) *convert-ref-init-val*(*rhs); [13](#ref.ctor-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4633) *Remarks*: This constructor is defined as deleted ifreference_constructs_from_temporary_v is true[.](#ref.ctor-13.sentence-1) [🔗](#ref.ctor-itemdecl:5) `template constexpr explicit(!is_convertible_v) optional(optional&& rhs) noexcept(is_nothrow_constructible_v); ` [14](#ref.ctor-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4649) *Constraints*: - [(14.1)](#ref.ctor-14.1) is_same_v, optional> is false, - [(14.2)](#ref.ctor-14.2) is_same_v is false, and - [(14.3)](#ref.ctor-14.3) is_constructible_v is true[.](#ref.ctor-14.sentence-1) [15](#ref.ctor-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4657) *Effects*: Equivalent to:if (rhs.has_value()) *convert-ref-init-val*(*std::move(rhs)); [16](#ref.ctor-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4664) *Remarks*: This constructor is defined as deleted ifreference_constructs_from_temporary_v is true[.](#ref.ctor-16.sentence-1) [🔗](#ref.ctor-itemdecl:6) `template constexpr explicit(!is_convertible_v) optional(const optional&& rhs) noexcept(is_nothrow_constructible_v); ` [17](#ref.ctor-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4680) *Constraints*: - [(17.1)](#ref.ctor-17.1) is_same_v, optional> is false, - [(17.2)](#ref.ctor-17.2) is_same_v is false, and - [(17.3)](#ref.ctor-17.3) is_constructible_v is true[.](#ref.ctor-17.sentence-1) [18](#ref.ctor-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4688) *Effects*: Equivalent to:if (rhs.has_value()) *convert-ref-init-val*(*std::move(rhs)); [19](#ref.ctor-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4695) *Remarks*: This constructor is defined as deleted ifreference_constructs_from_temporary_v is true[.](#ref.ctor-19.sentence-1) #### [22.5.4.3](#ref.assign) Assignment [[optional.ref.assign]](optional.ref.assign) [🔗](#ref.assign-itemdecl:1) `constexpr optional& operator=(nullopt_t) noexcept; ` [1](#ref.assign-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4711) *Effects*: Assigns nullptr to *val*[.](#ref.assign-1.sentence-1) [2](#ref.assign-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4715) *Postconditions*: *this does not contain a value[.](#ref.assign-2.sentence-1) [3](#ref.assign-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4719) *Returns*: *this[.](#ref.assign-3.sentence-1) [🔗](#ref.assign-itemdecl:2) `template constexpr T& emplace(U&& u) noexcept(is_nothrow_constructible_v); ` [4](#ref.assign-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4730) *Constraints*: - [(4.1)](#ref.assign-4.1) is_constructible_v is true, and - [(4.2)](#ref.assign-4.2) reference_constructs_from_temporary_v is false[.](#ref.assign-4.sentence-1) [5](#ref.assign-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4737) *Effects*: Equivalent to: *convert-ref-init-val*(std​::​forward(u))[.](#ref.assign-5.sentence-1) #### [22.5.4.4](#ref.swap) Swap [[optional.ref.swap]](optional.ref.swap) [🔗](#ref.swap-itemdecl:1) `constexpr void swap(optional& rhs) noexcept; ` [1](#ref.swap-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4749) *Effects*: Equivalent to: swap(*val*, rhs.*val*)[.](#ref.swap-1.sentence-1) #### [22.5.4.5](#ref.iterators) Iterator support [[optional.ref.iterators]](optional.ref.iterators) [🔗](#ref.iterators-itemdecl:1) `using iterator = implementation-defined; ` [1](#ref.iterators-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4761) This type models [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")), meets the *Cpp17RandomAccessIterator* requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7 Random access iterators")), and meets the requirements for constexpr iterators ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General")), with value type remove_cv_t[.](#ref.iterators-1.sentence-1) The reference type is T& for iterator[.](#ref.iterators-1.sentence-2) [2](#ref.iterators-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4769) All requirements on container iterators ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")) apply tooptional​::​iterator[.](#ref.iterators-2.sentence-1) [🔗](#ref.iterators-itemdecl:2) `constexpr iterator begin() const noexcept; ` [3](#ref.iterators-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4779) *Returns*: If has_value() is true, an iterator referring to **val*[.](#ref.iterators-3.sentence-1) Otherwise, a past-the-end iterator value[.](#ref.iterators-3.sentence-2) [🔗](#ref.iterators-itemdecl:3) `constexpr iterator end() const noexcept; ` [4](#ref.iterators-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4791) *Returns*: begin() + has_value()[.](#ref.iterators-4.sentence-1) #### [22.5.4.6](#ref.observe) Observers [[optional.ref.observe]](optional.ref.observe) [🔗](#ref.observe-itemdecl:1) `constexpr T* operator->() const noexcept; ` [1](#ref.observe-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4803) *Hardened preconditions*: has_value() is true[.](#ref.observe-1.sentence-1) [2](#ref.observe-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4807) *Returns*: *val*[.](#ref.observe-2.sentence-1) [🔗](#ref.observe-itemdecl:2) `constexpr T& operator*() const noexcept; ` [3](#ref.observe-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4818) *Hardened preconditions*: has_value() is true[.](#ref.observe-3.sentence-1) [4](#ref.observe-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4822) *Returns*: **val*[.](#ref.observe-4.sentence-1) [🔗](#ref.observe-itemdecl:3) `constexpr explicit operator bool() const noexcept; ` [5](#ref.observe-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4832) *Returns*: *val* != nullptr[.](#ref.observe-5.sentence-1) [🔗](#ref.observe-itemdecl:4) `constexpr bool has_value() const noexcept; ` [6](#ref.observe-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4842) *Returns*: *val* != nullptr[.](#ref.observe-6.sentence-1) [🔗](#ref.observe-itemdecl:5) `constexpr T& value() const; ` [7](#ref.observe-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4852) *Effects*: Equivalent to:return has_value() ? **val* : throw bad_optional_access(); [🔗](#ref.observe-itemdecl:6) `template> constexpr remove_cv_t value_or(U&& u) const; ` [8](#ref.observe-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4865) Let X be remove_cv_t[.](#ref.observe-8.sentence-1) [9](#ref.observe-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4868) *Mandates*: is_constructible_v && is_convertible_v is true[.](#ref.observe-9.sentence-1) [10](#ref.observe-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4872) *Effects*: Equivalent to:return has_value() ? **val* : static_cast(std::forward(u)); #### [22.5.4.7](#ref.monadic) Monadic operations [[optional.ref.monadic]](optional.ref.monadic) [🔗](#ref.monadic-itemdecl:1) `template constexpr auto and_then(F&& f) const; ` [1](#ref.monadic-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4887) Let U be invoke_result_t[.](#ref.monadic-1.sentence-1) [2](#ref.monadic-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4890) *Mandates*: remove_cvref_t is a specialization of optional[.](#ref.monadic-2.sentence-1) [3](#ref.monadic-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4894) *Effects*: Equivalent to:if (has_value()) {return invoke(std::forward(f), **val*);} else {return remove_cvref_t();} [🔗](#ref.monadic-itemdecl:2) `template constexpr optional>> transform(F&& f) const; ` [4](#ref.monadic-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4912) Let U be remove_cv_t>[.](#ref.monadic-4.sentence-1) [5](#ref.monadic-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4915) *Mandates*: The declarationU u(invoke(std::forward(f), **val*)); is well-formed for some invented variable u[.](#ref.monadic-5.sentence-1) [*Note [1](#ref.monadic-note-1)*: There is no requirement that U is movable ([[dcl.init.general]](dcl.init.general "9.5.1 General"))[.](#ref.monadic-5.sentence-2) — *end note*] [6](#ref.monadic-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4926) *Returns*: If *this contains a value, an optional object whose contained value is direct-non-list-initialized withinvoke(std​::​forward(f), **val*); otherwise, optional()[.](#ref.monadic-6.sentence-1) [🔗](#ref.monadic-itemdecl:3) `template constexpr optional or_else(F&& f) const; ` [7](#ref.monadic-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4939) *Constraints*: F models [invocable](concept.invocable#concept:invocable "18.7.2 Concept invocable [concept.invocable]")[.](#ref.monadic-7.sentence-1) [8](#ref.monadic-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4943) *Mandates*: is_same_v>, optional> is true[.](#ref.monadic-8.sentence-1) [9](#ref.monadic-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4947) *Effects*: Equivalent to:if (has_value()) {return **val*;} else {return std::forward(f)();} #### [22.5.4.8](#ref.mod) Modifiers [[optional.ref.mod]](optional.ref.mod) [🔗](#ref.mod-itemdecl:1) `constexpr void reset() noexcept; ` [1](#ref.mod-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4966) *Effects*: Assigns nullptr to *val*[.](#ref.mod-1.sentence-1) [2](#ref.mod-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4970) *Postconditions*: *this does not contain a value[.](#ref.mod-2.sentence-1) #### [22.5.4.9](#ref.expos) Exposition only helper functions [[optional.ref.expos]](optional.ref.expos) [🔗](#ref.expos-itemdecl:1) `template constexpr void convert-ref-init-val(U&& u); // exposition only ` [1](#ref.expos-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4983) *Effects*: Creates a variable r as if by T& r(std​::​forward(u)); and then initializes *val* with addressof(r)[.](#ref.expos-1.sentence-1) ### [22.5.5](#nullopt) No-value state indicator [[optional.nullopt]](optional.nullopt) [🔗](#lib:nullopt_t) `struct nullopt_t{see below}; inline constexpr nullopt_t nullopt(unspecified); ` [1](#nullopt-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4998) The struct nullopt_t is an empty class type used as a unique type to indicate the state of not containing a value for optional objects[.](#nullopt-1.sentence-1) In particular, optional has a constructor with nullopt_t as a single argument; this indicates that an optional object not containing a value shall be constructed[.](#nullopt-1.sentence-2) [2](#nullopt-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5003) Type nullopt_t shall not have a default constructor or an initializer-list constructor, and shall not be an aggregate[.](#nullopt-2.sentence-1) ### [22.5.6](#bad.access) Class bad_optional_access [[optional.bad.access]](optional.bad.access) namespace std {class bad_optional_access : public exception {public:// see [[exception]](exception "17.9.3 Class exception") for the specification of the special member functionsconstexpr const char* what() const noexcept override; };} [1](#bad.access-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5018) The class bad_optional_access defines the type of objects thrown as exceptions to report the situation where an attempt is made to access the value of an optional object that does not contain a value[.](#bad.access-1.sentence-1) [🔗](#lib:what,bad_optional_access) `constexpr const char* what() const noexcept override; ` [2](#bad.access-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5027) *Returns*: An implementation-defined ntbs, which during constant evaluation is encoded with the ordinary literal encoding ([[lex.ccon]](lex.ccon "5.13.3 Character literals"))[.](#bad.access-2.sentence-1) ### [22.5.7](#relops) Relational operators [[optional.relops]](optional.relops) [🔗](#lib:operator==,optional) `template constexpr bool operator==(const optional& x, const optional& y); ` [1](#relops-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5042) *Constraints*: The expression *x == *y is well-formed and its result is convertible to bool[.](#relops-1.sentence-1) [*Note [1](#relops-note-1)*: T need not be [*Cpp17EqualityComparable*](utility.arg.requirements#:Cpp17EqualityComparable "16.4.4.2 Template argument requirements [utility.arg.requirements]")[.](#relops-1.sentence-2) — *end note*] [2](#relops-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5050) *Returns*: If x.has_value() != y.has_value(), false; otherwise if x.has_value() == false, true; otherwise *x == *y[.](#relops-2.sentence-1) [3](#relops-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5054) *Remarks*: Specializations of this function template for which *x == *y is a core constant expression are constexpr functions[.](#relops-3.sentence-1) [🔗](#lib:operator!=,optional) `template constexpr bool operator!=(const optional& x, const optional& y); ` [4](#relops-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5067) *Constraints*: The expression *x != *y is well-formed and its result is convertible to bool[.](#relops-4.sentence-1) [5](#relops-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5072) *Returns*: If x.has_value() != y.has_value(), true; otherwise, if x.has_value() == false, false; otherwise *x != *y[.](#relops-5.sentence-1) [6](#relops-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5078) *Remarks*: Specializations of this function template for which *x != *y is a core constant expression are constexpr functions[.](#relops-6.sentence-1) [🔗](#lib:operator%3c,optional) `template constexpr bool operator<(const optional& x, const optional& y); ` [7](#relops-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5091) *Constraints*: *x < *y is well-formed and its result is convertible to bool[.](#relops-7.sentence-1) [8](#relops-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5096) *Returns*: If !y, false; otherwise, if !x, true; otherwise *x < *y[.](#relops-8.sentence-1) [9](#relops-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5102) *Remarks*: Specializations of this function template for which *x < *y is a core constant expression are constexpr functions[.](#relops-9.sentence-1) [🔗](#lib:operator%3e,optional) `template constexpr bool operator>(const optional& x, const optional& y); ` [10](#relops-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5115) *Constraints*: The expression *x > *y is well-formed and its result is convertible to bool[.](#relops-10.sentence-1) [11](#relops-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5120) *Returns*: If !x, false; otherwise, if !y, true; otherwise *x > *y[.](#relops-11.sentence-1) [12](#relops-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5126) *Remarks*: Specializations of this function template for which *x > *y is a core constant expression are constexpr functions[.](#relops-12.sentence-1) [🔗](#lib:operator%3c=,optional) `template constexpr bool operator<=(const optional& x, const optional& y); ` [13](#relops-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5139) *Constraints*: The expression *x <= *y is well-formed and its result is convertible to bool[.](#relops-13.sentence-1) [14](#relops-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5144) *Returns*: If !x, true; otherwise, if !y, false; otherwise *x <= *y[.](#relops-14.sentence-1) [15](#relops-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5150) *Remarks*: Specializations of this function template for which *x <= *y is a core constant expression are constexpr functions[.](#relops-15.sentence-1) [🔗](#lib:operator%3e=,optional) `template constexpr bool operator>=(const optional& x, const optional& y); ` [16](#relops-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5163) *Constraints*: The expression *x >= *y is well-formed and its result is convertible to bool[.](#relops-16.sentence-1) [17](#relops-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5168) *Returns*: If !y, true; otherwise, if !x, false; otherwise *x >= *y[.](#relops-17.sentence-1) [18](#relops-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5174) *Remarks*: Specializations of this function template for which *x >= *y is a core constant expression are constexpr functions[.](#relops-18.sentence-1) [🔗](#lib:operator%3c=%3e,optional) `template U> constexpr compare_three_way_result_t operator<=>(const optional& x, const optional& y); ` [19](#relops-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5189) *Returns*: If x && y, *x <=> *y; otherwise x.has_value() <=> y.has_value()[.](#relops-19.sentence-1) [20](#relops-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5193) *Remarks*: Specializations of this function template for which *x <=> *y is a core constant expression are constexpr functions[.](#relops-20.sentence-1) ### [22.5.8](#nullops) Comparison with nullopt [[optional.nullops]](optional.nullops) [🔗](#lib:operator==,optional_) `template constexpr bool operator==(const optional& x, nullopt_t) noexcept; ` [1](#nullops-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5208) *Returns*: !x[.](#nullops-1.sentence-1) [🔗](#lib:operator%3c=%3e,optional_) `template constexpr strong_ordering operator<=>(const optional& x, nullopt_t) noexcept; ` [2](#nullops-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5219) *Returns*: x.has_value() <=> false[.](#nullops-2.sentence-1) ### [22.5.9](#comp.with.t) Comparison with T [[optional.comp.with.t]](optional.comp.with.t) [🔗](#lib:operator==,optional__) `template constexpr bool operator==(const optional& x, const U& v); ` [1](#comp.with.t-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5232) *Constraints*: U is not a specialization of optional[.](#comp.with.t-1.sentence-1) The expression *x == v is well-formed and its result is convertible to bool[.](#comp.with.t-1.sentence-2) [*Note [1](#comp.with.t-note-1)*: T need not be [*Cpp17EqualityComparable*](utility.arg.requirements#:Cpp17EqualityComparable "16.4.4.2 Template argument requirements [utility.arg.requirements]")[.](#comp.with.t-1.sentence-3) — *end note*] [2](#comp.with.t-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5241) *Effects*: Equivalent to: return x.has_value() ? *x == v : false; [🔗](#lib:operator==,optional___) `template constexpr bool operator==(const T& v, const optional& x); ` [3](#comp.with.t-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5252) *Constraints*: T is not a specialization of optional[.](#comp.with.t-3.sentence-1) The expression v == *x is well-formed and its result is convertible to bool[.](#comp.with.t-3.sentence-2) [4](#comp.with.t-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5258) *Effects*: Equivalent to: return x.has_value() ? v == *x : false; [🔗](#lib:operator!=,optional_) `template constexpr bool operator!=(const optional& x, const U& v); ` [5](#comp.with.t-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5269) *Constraints*: U is not a specialization of optional[.](#comp.with.t-5.sentence-1) The expression *x != v is well-formed and its result is convertible to bool[.](#comp.with.t-5.sentence-2) [6](#comp.with.t-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5275) *Effects*: Equivalent to: return x.has_value() ? *x != v : true; [🔗](#lib:operator!=,optional__) `template constexpr bool operator!=(const T& v, const optional& x); ` [7](#comp.with.t-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5286) *Constraints*: T is not a specialization of optional[.](#comp.with.t-7.sentence-1) The expression v != *x is well-formed and its result is convertible to bool[.](#comp.with.t-7.sentence-2) [8](#comp.with.t-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5292) *Effects*: Equivalent to: return x.has_value() ? v != *x : true; [🔗](#lib:operator%3c,optional_) `template constexpr bool operator<(const optional& x, const U& v); ` [9](#comp.with.t-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5303) *Constraints*: U is not a specialization of optional[.](#comp.with.t-9.sentence-1) The expression *x < v is well-formed and its result is convertible to bool[.](#comp.with.t-9.sentence-2) [10](#comp.with.t-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5309) *Effects*: Equivalent to: return x.has_value() ? *x < v : true; [🔗](#lib:operator%3c,optional__) `template constexpr bool operator<(const T& v, const optional& x); ` [11](#comp.with.t-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5320) *Constraints*: T is not a specialization of optional[.](#comp.with.t-11.sentence-1) The expression v < *x is well-formed and its result is convertible to bool[.](#comp.with.t-11.sentence-2) [12](#comp.with.t-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5326) *Effects*: Equivalent to: return x.has_value() ? v < *x : false; [🔗](#lib:operator%3e,optional_) `template constexpr bool operator>(const optional& x, const U& v); ` [13](#comp.with.t-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5337) *Constraints*: U is not a specialization of optional[.](#comp.with.t-13.sentence-1) The expression *x > v is well-formed and its result is convertible to bool[.](#comp.with.t-13.sentence-2) [14](#comp.with.t-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5343) *Effects*: Equivalent to: return x.has_value() ? *x > v : false; [🔗](#lib:operator%3e,optional__) `template constexpr bool operator>(const T& v, const optional& x); ` [15](#comp.with.t-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5354) *Constraints*: T is not a specialization of optional[.](#comp.with.t-15.sentence-1) The expression v > *x is well-formed and its result is convertible to bool[.](#comp.with.t-15.sentence-2) [16](#comp.with.t-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5360) *Effects*: Equivalent to: return x.has_value() ? v > *x : true; [🔗](#lib:operator%3c=,optional_) `template constexpr bool operator<=(const optional& x, const U& v); ` [17](#comp.with.t-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5371) *Constraints*: U is not a specialization of optional[.](#comp.with.t-17.sentence-1) The expression *x <= v is well-formed and its result is convertible to bool[.](#comp.with.t-17.sentence-2) [18](#comp.with.t-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5377) *Effects*: Equivalent to: return x.has_value() ? *x <= v : true; [🔗](#lib:operator%3c=,optional__) `template constexpr bool operator<=(const T& v, const optional& x); ` [19](#comp.with.t-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5388) *Constraints*: T is not a specialization of optional[.](#comp.with.t-19.sentence-1) The expression v <= *x is well-formed and its result is convertible to bool[.](#comp.with.t-19.sentence-2) [20](#comp.with.t-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5394) *Effects*: Equivalent to: return x.has_value() ? v <= *x : false; [🔗](#lib:operator%3e=,optional_) `template constexpr bool operator>=(const optional& x, const U& v); ` [21](#comp.with.t-21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5405) *Constraints*: U is not a specialization of optional[.](#comp.with.t-21.sentence-1) The expression *x >= v is well-formed and its result is convertible to bool[.](#comp.with.t-21.sentence-2) [22](#comp.with.t-22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5411) *Effects*: Equivalent to: return x.has_value() ? *x >= v : false; [🔗](#lib:operator%3e=,optional__) `template constexpr bool operator>=(const T& v, const optional& x); ` [23](#comp.with.t-23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5422) *Constraints*: T is not a specialization of optional[.](#comp.with.t-23.sentence-1) The expression v >= *x is well-formed and its result is convertible to bool[.](#comp.with.t-23.sentence-2) [24](#comp.with.t-24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5428) *Effects*: Equivalent to: return x.has_value() ? v >= *x : true; [🔗](#lib:operator%3c=%3e,optional__) `template requires (![is-derived-from-optional](#concept:is-derived-from-optional "22.5.2 Header synopsis [optional.syn]")) && [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4 Concept three_­way_­comparable [cmp.concept]") constexpr compare_three_way_result_t operator<=>(const optional& x, const U& v); ` [25](#comp.with.t-25) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5442) *Effects*: Equivalent to: return x.has_value() ? *x <=> v : strong_ordering​::​less; ### [22.5.10](#specalg) Specialized algorithms [[optional.specalg]](optional.specalg) [🔗](#lib:swap,optional_) `template constexpr void swap(optional& x, optional& y) noexcept(noexcept(x.swap(y))); ` [1](#specalg-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5456) *Constraints*: is_reference_v || (is_move_constructible_v && is_swappable_v) is true[.](#specalg-1.sentence-1) [2](#specalg-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5463) *Effects*: Calls x.swap(y)[.](#specalg-2.sentence-1) [🔗](#lib:make_optional) `template constexpr optional> make_optional(T&& v); ` [3](#specalg-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5474) *Constraints*: The call to make_optional does not use an explicit [*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]") that begins with a type [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")[.](#specalg-3.sentence-1) [4](#specalg-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5480) *Returns*: optional>(std​::​forward(v))[.](#specalg-4.sentence-1) [🔗](#lib:make_optional_) `template constexpr optional make_optional(Args&&... args); ` [5](#specalg-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5492) *Effects*: Equivalent to: return optional(in_place, std​::​forward(args)...); [🔗](#lib:make_optional__) `template constexpr optional make_optional(initializer_list il, Args&&... args); ` [6](#specalg-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5504) *Effects*: Equivalent to: return optional(in_place, il, std​::​forward(args)...); ### [22.5.11](#hash) Hash support [[optional.hash]](optional.hash) [🔗](#lib:hash,optional) `template struct hash>; ` [1](#hash-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5517) The specialization hash> is enabled ([[unord.hash]](unord.hash "22.10.19 Class template hash")) if and only if hash> is enabled[.](#hash-1.sentence-1) When enabled, for an object o of type optional, if o.has_value() == true, then hash>()(o) evaluates to the same value as hash>()(*o); otherwise it evaluates to an unspecified value[.](#hash-1.sentence-2) The member functions are not guaranteed to be noexcept[.](#hash-1.sentence-3)