Files
cppdraft_translate/cppdraft/optional.md
2025-10-25 03:02:53 +03:00

2473 lines
95 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.1General[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 <optional> synopsis [[optional.syn]](optional.syn)
[🔗](#header:%3coptional%3e)
// mostly freestanding#include <compare> // see [[compare.syn]](compare.syn "17.12.1Header <compare> synopsis")namespace std {// [[optional.optional]](#optional "22.5.3Class template optional"), class template optionaltemplate<class T>class optional; // partially freestanding// [[optional.optional.ref]](#optional.ref "22.5.4Partial specialization of optional for reference types"), partial specialization of optional for lvalue reference typestemplate<class T>class optional<T&>; // partially freestandingtemplate<class T>constexpr bool ranges::enable_view<optional<T>> = true; template<class T>constexpr auto format_kind<optional<T>> = range_format::disabled; template<class T>constexpr bool ranges::enable_borrowed_range<optional<T&>> = true; template<class T>concept [*is-derived-from-optional*](#concept:is-derived-from-optional "22.5.2Header <optional> synopsis[optional.syn]") = requires(const T& t) { // *exposition only*[]<class U>(const optional<U>&){ }(t); }; // [[optional.nullopt]](#nullopt "22.5.5No-value state indicator"), no-value state indicatorstruct nullopt_t{*see below*}; inline constexpr nullopt_t nullopt(*unspecified*); // [[optional.bad.access]](#bad.access "22.5.6Class bad_­optional_­access"), class bad_optional_accessclass bad_optional_access; // [[optional.relops]](#relops "22.5.7Relational operators"), relational operatorstemplate<class T, class U>constexpr bool operator==(const optional<T>&, const optional<U>&); template<class T, class U>constexpr bool operator!=(const optional<T>&, const optional<U>&); template<class T, class U>constexpr bool operator<(const optional<T>&, const optional<U>&); template<class T, class U>constexpr bool operator>(const optional<T>&, const optional<U>&); template<class T, class U>constexpr bool operator<=(const optional<T>&, const optional<U>&); template<class T, class U>constexpr bool operator>=(const optional<T>&, const optional<U>&); template<class T, [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4Concept three_­way_­comparable[cmp.concept]")<T> U>constexpr compare_three_way_result_t<T, U>operator<=>(const optional<T>&, const optional<U>&); // [[optional.nullops]](#nullops "22.5.8Comparison with nullopt"), comparison with nullopttemplate<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; template<class T>constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept; // [[optional.comp.with.t]](#comp.with.t "22.5.9Comparison with T"), comparison with Ttemplate<class T, class U> constexpr bool operator==(const optional<T>&, const U&); template<class T, class U> constexpr bool operator==(const T&, const optional<U>&); template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&); template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&); template<class T, class U> constexpr bool operator<(const optional<T>&, const U&); template<class T, class U> constexpr bool operator<(const T&, const optional<U>&); template<class T, class U> constexpr bool operator>(const optional<T>&, const U&); template<class T, class U> constexpr bool operator>(const T&, const optional<U>&); template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&); template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&); template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&); template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&); template<class T, class U>requires (![*is-derived-from-optional*](#concept:is-derived-from-optional "22.5.2Header <optional> synopsis[optional.syn]")<U>) && [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4Concept three_­way_­comparable[cmp.concept]")<T, U>constexpr compare_three_way_result_t<T, U>operator<=>(const optional<T>&, const U&); // [[optional.specalg]](#specalg "22.5.10Specialized algorithms"), specialized algorithmstemplate<class T>constexpr void swap(optional<T>&, optional<T>&) noexcept(*see below*); template<class T>constexpr optional<decay_t<T>> make_optional(T&&); template<class T, class... Args>constexpr optional<T> make_optional(Args&&... args); template<class T, class U, class... Args>constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args); // [[optional.hash]](#hash "22.5.11Hash support"), hash supporttemplate<class T> struct hash; template<class T> struct hash<optional<T>>;}
### [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 {template<class T>class optional {public:using value_type = T; using iterator = *implementation-defined*; // see [[optional.iterators]](#iterators "22.5.3.6Iterator support")using const_iterator = *implementation-defined*; // see [[optional.iterators]](#iterators "22.5.3.6Iterator support")// [[optional.ctor]](#ctor "22.5.3.2Constructors"), 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]](#dtor "22.5.3.3Destructor"), destructorconstexpr ~optional(); // [[optional.assign]](#assign "22.5.3.4Assignment"), 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]](#swap "22.5.3.5Swap"), swapconstexpr void swap(optional&) noexcept(*see below*); // [[optional.iterators]](#iterators "22.5.3.6Iterator 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.7Observers"), 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]](#monadic "22.5.3.8Monadic 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]](#mod "22.5.3.9Modifiers"), modifiersconstexpr void reset() noexcept; private: T* *val*; // *exposition only*}; template<class T> optional(T) -> optional<T>;}
[1](#optional.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[.](#optional.general-1.sentence-1)
When an instance of optional<T> [*contains a value*](#def:contains_a_value,optional "22.5.3.1General[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.1General[optional.optional.general]"),
is nested within ([[intro.object]](intro.object "6.8.2Object model")) the optional object[.](#optional.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[.](#optional.general-1.sentence-3)
[2](#optional.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[.](#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.1General[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[.](#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)
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](#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.6The 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<T> is true[.](#ctor-7.sentence-1)
If is_trivially_copy_constructible_v<T> 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<T> 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<T>[.](#ctor-12.sentence-1)
If is_trivially_move_constructible_v<T> is true,
this constructor is trivial[.](#ctor-12.sentence-2)
[🔗](#lib:optional,constructor___)
`template<class... Args> 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<T, Args...> 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>(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<class U, class... Args>
constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
`
[18](#ctor-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3511)
*Constraints*: is_constructible_v<T, initializer_list<U>&, 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>(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<class U = remove_cv_t<T>> 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<T, U> is true,
- [(23.2)](#ctor-23.2)
is_same_v<remove_cvref_t<U>, in_place_t> is false,
- [(23.3)](#ctor-23.3)
is_same_v<remove_cvref_t<U>, optional> is false, and
- [(23.4)](#ctor-23.4)
if T is cv bool,remove_cvref_t<U> 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<U>(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<U, T>
[🔗](#lib:optional,constructor______)
`template<class U> constexpr explicit(see below) optional(const optional<U>& rhs);
`
[28](#ctor-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3576)
*Constraints*:
- [(28.1)](#ctor-28.1)
is_constructible_v<T, const U&> is true, and
- [(28.2)](#ctor-28.2)
if T is not cv bool,*converts-from-any-cvref*<T, optional<U>> 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<const U&, T>
[🔗](#lib:optional,constructor_______)
`template<class U> constexpr explicit(see below) optional(optional<U>&& rhs);
`
[33](#ctor-33)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3611)
*Constraints*:
- [(33.1)](#ctor-33.1)
is_constructible_v<T, U> is true, and
- [(33.2)](#ctor-33.2)
if T is not cv bool,*converts-from-any-cvref*<T, optional<U>> 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<U, T>
#### [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<T> != 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<T> 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<T>& 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<T>& 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&amp;) 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)<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](#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<T> is true andis_copy_assignable_v<T> is true[.](#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[.](#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<T> is true andis_move_assignable_v<T> 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&amp;&amp;) 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)<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](#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<T> && is_nothrow_move_constructible_v<T>
[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<T> &&is_trivially_move_assignable_v<T> &&is_trivially_destructible_v<T> is true,
this assignment operator is trivial[.](#assign-13.sentence-4)
[🔗](#lib:operator=,optional___)
`template<class U = remove_cv_t<T>> 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<remove_cvref_t<U>, optional> is false,
- [(14.2)](#assign-14.2)
conjunction_v<is_scalar<T>, is_same<T, decay_t<U>>> is false,
- [(14.3)](#assign-14.3)
is_constructible_v<T, U> is true, and
- [(14.4)](#assign-14.4)
is_assignable_v<T&, U> 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<U>(v) to the contained value; otherwise direct-non-list-initializes the contained value with std::forward<U>(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<class U> constexpr optional<T>& operator=(const optional<U>& rhs);
`
[19](#assign-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3822)
*Constraints*:
- [(19.1)](#assign-19.1)
is_constructible_v<T, const U&> is true,
- [(19.2)](#assign-19.2)
is_assignable_v<T&, const U&> is true,
- [(19.3)](#assign-19.3)
*converts-from-any-cvref*<T, optional<U>> is false,
- [(19.4)](#assign-19.4)
is_assignable_v<T&, optional<U>&> is false,
- [(19.5)](#assign-19.5)
is_assignable_v<T&, optional<U>&&> is false,
- [(19.6)](#assign-19.6)
is_assignable_v<T&, const optional<U>&> is false, and
- [(19.7)](#assign-19.7)
is_assignable_v<T&, const optional<U>&&> 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<U>&amp;) effects")[.](#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](#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<class U> constexpr optional<T>& operator=(optional<U>&& rhs);
`
[24](#assign-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3877)
*Constraints*:
- [(24.1)](#assign-24.1)
is_constructible_v<T, U> is true,
- [(24.2)](#assign-24.2)
is_assignable_v<T&, U> is true,
- [(24.3)](#assign-24.3)
*converts-from-any-cvref*<T, optional<U>> is false,
- [(24.4)](#assign-24.4)
is_assignable_v<T&, optional<U>&> is false,
- [(24.5)](#assign-24.5)
is_assignable_v<T&, optional<U>&&> is false,
- [(24.6)](#assign-24.6)
is_assignable_v<T&, const optional<U>&> is false, and
- [(24.7)](#assign-24.7)
is_assignable_v<T&, const optional<U>&&> 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<U>&amp;&amp;) 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<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](#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<class... Args> constexpr T& emplace(Args&&... args);
`
[29](#assign-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3933)
*Mandates*: is_constructible_v<T, Args...> 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>(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<class U, class... Args> constexpr T& emplace(initializer_list<U> il, Args&&... args);
`
[35](#assign-35)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3965)
*Constraints*: is_constructible_v<T, initializer_list<U>&, 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>(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<T> 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.3Swappable requirements[swappable.requirements]") requirements ([[swappable.requirements]](swappable.requirements "16.4.4.3Swappable 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&amp;) 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)<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](#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&amp;) 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<T> && is_nothrow_swappable_v<T>
[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.14Concept contiguous_­iterator[iterator.concept.contiguous]") ([[iterator.concept.contiguous]](iterator.concept.contiguous "24.3.4.14Concept contiguous_­iterator")),
meet the [*Cpp17RandomAccessIterator*](random.access.iterators#:Cpp17RandomAccessIterator "24.3.5.7Random access iterators[random.access.iterators]") requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7Random access iterators")), and
meet the requirements for constexpr iterators ([[iterator.requirements.general]](iterator.requirements.general "24.3.1General")),
with value type remove_cv_t<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.2Container 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<class U = remove_cv_t<T>> 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<T> && is_convertible_v<U&&, T> 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<T>(std::forward<U>(v));
[🔗](#lib:value_or,optional_)
`template<class U = remove_cv_t<T>> 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<T> && is_convertible_v<U&&, T> 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<T>(std::forward<U>(v));
#### [22.5.3.8](#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](#monadic-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4266)
Let U be invoke_result_t<F, decltype(**val*)>[.](#monadic-1.sentence-1)
[2](#monadic-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4269)
*Mandates*: remove_cvref_t<U> 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>(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](#monadic-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4292)
Let U be invoke_result_t<F, decltype(std::move(**val*))>[.](#monadic-4.sentence-1)
[5](#monadic-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4295)
*Mandates*: remove_cvref_t<U> 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>(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](#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*)>>[.](#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>(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.1General"))[.](#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<U> object
whose contained value is direct-non-list-initialized withinvoke(std::forward<F>(f), **val*);
otherwise, optional<U>()[.](#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](#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*))>>[.](#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>(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.1General"))[.](#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<U> object
whose contained value is direct-non-list-initialized withinvoke(std::forward<F>(f), std::move(**val*));
otherwise, optional<U>()[.](#monadic-12.sentence-1)
[🔗](#lib:or_else,optional)
`template<class F> 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.2Concept invocable[concept.invocable]") andT models [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14Concept 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<remove_cvref_t<invoke_result_t<F>>, 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>(f)();}
[🔗](#lib:or_else,optional_)
`template<class F> 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.2Concept invocable[concept.invocable]") andT models [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13Concept 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<remove_cvref_t<invoke_result_t<F>>, 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>(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 {template<class T>class optional<T&> {public:using value_type = T; using iterator = *implementation-defined*; // see [[optional.ref.iterators]](#ref.iterators "22.5.4.5Iterator support")public:// [[optional.ref.ctor]](#ref.ctor "22.5.4.2Constructors"), constructorsconstexpr optional() noexcept = default; constexpr optional(nullopt_t) noexcept : optional() {}constexpr optional(const optional& rhs) noexcept = default; template<class Arg>constexpr explicit optional(in_place_t, Arg&& arg); template<class U>constexpr explicit(*see below*) optional(U&& u) noexcept(*see below*); template<class U>constexpr explicit(*see below*) optional(optional<U>& rhs) noexcept(*see below*); template<class U>constexpr explicit(*see below*) optional(const optional<U>& rhs) noexcept(*see below*); template<class U>constexpr explicit(*see below*) optional(optional<U>&& rhs) noexcept(*see below*); template<class U>constexpr explicit(*see below*) optional(const optional<U>&& rhs) noexcept(*see below*); constexpr ~optional() = default; // [[optional.ref.assign]](#ref.assign "22.5.4.3Assignment"), assignmentconstexpr optional& operator=(nullopt_t) noexcept; constexpr optional& operator=(const optional& rhs) noexcept = default; template<class U> constexpr T& emplace(U&& u) noexcept(*see below*); // [[optional.ref.swap]](#ref.swap "22.5.4.4Swap"), swapconstexpr void swap(optional& rhs) noexcept; // [[optional.ref.iterators]](#ref.iterators "22.5.4.5Iterator support"), iterator supportconstexpr iterator begin() const noexcept; constexpr iterator end() const noexcept; // [[optional.ref.observe]](#ref.observe "22.5.4.6Observers"), 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<class U = remove_cv_t<T>>constexpr remove_cv_t<T> value_or(U&& u) const; // [[optional.ref.monadic]](#ref.monadic "22.5.4.7Monadic operations"), monadic operationstemplate<class F> constexpr auto and_then(F&& f) const; template<class F> constexpr optional<invoke_result_t<F, T&>> transform(F&& f) const; template<class F> constexpr optional or_else(F&& f) const; // [[optional.ref.mod]](#ref.mod "22.5.4.8Modifiers"), modifiersconstexpr void reset() noexcept; private: T* *val* = nullptr; // *exposition only*// [[optional.ref.expos]](#ref.expos "22.5.4.9Exposition only helper functions"), exposition only helper functionstemplate<class U>constexpr 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<T&>[*contains a value*](#def:contains_a_value,optional.ref "22.5.4.1General[optional.optional.ref.general]") if and only if *val* != nullptr is true[.](#optional.ref.general-1.sentence-1)
When an optional<T&> contains a value,
the [*contained value*](#def:contained_value,optional.ref "22.5.4.1General[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<class Arg>
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<T&, Arg> is true, and
- [(1.2)](#ref.ctor-1.2)
reference_constructs_from_temporary_v<T&, Arg> 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>(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<class U>
constexpr explicit(!is_convertible_v<U, T&>)
optional(U&& u) noexcept(is_nothrow_constructible_v<T&, U>);
`
[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<remove_cvref_t<U>, optional> is false,
- [(4.2)](#ref.ctor-4.2)
is_same_v<remove_cvref_t<U>, in_place_t> is false, and
- [(4.3)](#ref.ctor-4.3)
is_constructible_v<T&, U> 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>(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<T&, U> is true[.](#ref.ctor-7.sentence-1)
[🔗](#ref.ctor-itemdecl:3)
`template<class U>
constexpr explicit(!is_convertible_v<U&, T&>)
optional(optional<U>& rhs) noexcept(is_nothrow_constructible_v<T&, U&>);
`
[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<remove_cv_t<T>, optional<U>> is false,
- [(8.2)](#ref.ctor-8.2)
is_same_v<T&, U> is false, and
- [(8.3)](#ref.ctor-8.3)
is_constructible_v<T&, U&> 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<T&, U&> is true[.](#ref.ctor-10.sentence-1)
[🔗](#ref.ctor-itemdecl:4)
`template<class U>
constexpr explicit(!is_convertible_v<const U&, T&>)
optional(const optional<U>& rhs) noexcept(is_nothrow_constructible_v<T&, const U&>);
`
[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<remove_cv_t<T>, optional<U>> is false,
- [(11.2)](#ref.ctor-11.2)
is_same_v<T&, U> is false, and
- [(11.3)](#ref.ctor-11.3)
is_constructible_v<T&, const U&> 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<T&, const U&> is true[.](#ref.ctor-13.sentence-1)
[🔗](#ref.ctor-itemdecl:5)
`template<class U>
constexpr explicit(!is_convertible_v<U, T&>)
optional(optional<U>&& rhs) noexcept(is_nothrow_constructible_v<T&, U>);
`
[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<remove_cv_t<T>, optional<U>> is false,
- [(14.2)](#ref.ctor-14.2)
is_same_v<T&, U> is false, and
- [(14.3)](#ref.ctor-14.3)
is_constructible_v<T&, U> 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<T&, U> is true[.](#ref.ctor-16.sentence-1)
[🔗](#ref.ctor-itemdecl:6)
`template<class U>
constexpr explicit(!is_convertible_v<const U, T&>)
optional(const optional<U>&& rhs) noexcept(is_nothrow_constructible_v<T&, const U>);
`
[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<remove_cv_t<T>, optional<U>> is false,
- [(17.2)](#ref.ctor-17.2)
is_same_v<T&, U> is false, and
- [(17.3)](#ref.ctor-17.3)
is_constructible_v<T&, const U> 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<T&, const U> 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<class U>
constexpr T& emplace(U&& u) noexcept(is_nothrow_constructible_v<T&, U>);
`
[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<T&, U> is true, and
- [(4.2)](#ref.assign-4.2)
reference_constructs_from_temporary_v<T&, U> 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>(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.14Concept contiguous_­iterator[iterator.concept.contiguous]") ([[iterator.concept.contiguous]](iterator.concept.contiguous "24.3.4.14Concept contiguous_­iterator")),
meets the *Cpp17RandomAccessIterator* requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7Random access iterators")),
and meets the requirements for constexpr iterators ([[iterator.requirements.general]](iterator.requirements.general "24.3.1General")),
with value type remove_cv_t<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.2Container 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<class U = remove_cv_t<T>> constexpr remove_cv_t<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<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<X, T&> && is_convertible_v<U, X> 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<X>(std::forward<U>(u));
#### [22.5.4.7](#ref.monadic) Monadic operations [[optional.ref.monadic]](optional.ref.monadic)
[🔗](#ref.monadic-itemdecl:1)
`template<class F> 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<F, 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<U> 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>(f), **val*);} else {return remove_cvref_t<U>();}
[🔗](#ref.monadic-itemdecl:2)
`template<class F>
constexpr optional<remove_cv_t<invoke_result_t<F, T&>>> 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<invoke_result_t<F, 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>(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.1General"))[.](#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<U> object
whose contained value is direct-non-list-initialized withinvoke(std::forward<F>(f), **val*);
otherwise, optional<U>()[.](#ref.monadic-6.sentence-1)
[🔗](#ref.monadic-itemdecl:3)
`template<class F> 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.2Concept 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<remove_cvref_t<invoke_result_t<F>>, 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>(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<class U>
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>(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<T> 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.3Class 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.3Character literals"))[.](#bad.access-2.sentence-1)
### [22.5.7](#relops) Relational operators [[optional.relops]](optional.relops)
[🔗](#lib:operator==,optional)
`template<class T, class U> constexpr bool operator==(const optional<T>& x, const optional<U>& 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.2Template 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<class T, class U> constexpr bool operator!=(const optional<T>& x, const optional<U>& 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<class T, class U> constexpr bool operator<(const optional<T>& x, const optional<U>& 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<class T, class U> constexpr bool operator>(const optional<T>& x, const optional<U>& 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<class T, class U> constexpr bool operator<=(const optional<T>& x, const optional<U>& 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<class T, class U> constexpr bool operator>=(const optional<T>& x, const optional<U>& 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<class T, [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4Concept three_­way_­comparable[cmp.concept]")<T> U>
constexpr compare_three_way_result_t<T, U>
operator<=>(const optional<T>& x, const optional<U>& 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<class T> constexpr bool operator==(const optional<T>& 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<class T> constexpr strong_ordering operator<=>(const optional<T>& 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<class T, class U> constexpr bool operator==(const optional<T>& 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.2Template 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<class T, class U> constexpr bool operator==(const T& v, const optional<U>& 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<class T, class U> constexpr bool operator!=(const optional<T>& 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<class T, class U> constexpr bool operator!=(const T& v, const optional<U>& 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<class T, class U> constexpr bool operator<(const optional<T>& 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<class T, class U> constexpr bool operator<(const T& v, const optional<U>& 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<class T, class U> constexpr bool operator>(const optional<T>& 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<class T, class U> constexpr bool operator>(const T& v, const optional<U>& 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<class T, class U> constexpr bool operator<=(const optional<T>& 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<class T, class U> constexpr bool operator<=(const T& v, const optional<U>& 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<class T, class U> constexpr bool operator>=(const optional<T>& 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<class T, class U> constexpr bool operator>=(const T& v, const optional<U>& 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<class T, class U>
requires (![is-derived-from-optional](#concept:is-derived-from-optional "22.5.2Header <optional> synopsis[optional.syn]")<U>) && [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4Concept three_­way_­comparable[cmp.concept]")<T, U>
constexpr compare_three_way_result_t<T, U>
operator<=>(const optional<T>& 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<class T>
constexpr void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)));
`
[1](#specalg-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5456)
*Constraints*: is_reference_v<T> || (is_move_constructible_v<T> && is_swappable_v<T>) 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<class T> constexpr optional<decay_t<T>> 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.3Names of template specializations[temp.names]") that
begins with a type [*template-argument*](temp.names#nt:template-argument "13.3Names 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<decay_t<T>>(std::forward<T>(v))[.](#specalg-4.sentence-1)
[🔗](#lib:make_optional_)
`template<class T, class...Args>
constexpr optional<T> make_optional(Args&&... args);
`
[5](#specalg-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5492)
*Effects*: Equivalent to: return optional<T>(in_place, std::forward<Args>(args)...);
[🔗](#lib:make_optional__)
`template<class T, class U, class... Args>
constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
`
[6](#specalg-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5504)
*Effects*: Equivalent to: return optional<T>(in_place, il, std::forward<Args>(args)...);
### [22.5.11](#hash) Hash support [[optional.hash]](optional.hash)
[🔗](#lib:hash,optional)
`template<class T> struct hash<optional<T>>;
`
[1](#hash-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5517)
The specialization hash<optional<T>> is enabled ([[unord.hash]](unord.hash "22.10.19Class template hash"))
if and only if hash<remove_const_t<T>> is enabled[.](#hash-1.sentence-1)
When enabled, for an object o of type optional<T>,
if o.has_value() == true, then hash<optional<T>>()(o) evaluates to the same value as hash<remove_const_t<T>>()(*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)