[optional]

# 22 General utilities library [[utilities]](./#utilities)

## 22.5 Optional objects [optional]

### [22.5.1](#general) General [[optional.general]](optional.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3169)

Subclause [optional] describes class template optional that represents
optional objects[.](#general-1.sentence-1)

An [*optional object*](#def:optional_object "22.5.1 General [optional.general]") is an
object that contains the storage for another object and manages the lifetime of
this contained object, if any[.](#general-1.sentence-2)

The contained object may be initialized after
the optional object has been initialized, and may be destroyed before the
optional object has been destroyed[.](#general-1.sentence-3)

The initialization state of the contained
object is tracked by the optional object[.](#general-1.sentence-4)

### [22.5.2](#syn) Header <optional> synopsis [[optional.syn]](optional.syn)

[ð](#header:%3coptional%3e)

// mostly freestanding#include <compare> // see [[compare.syn]](compare.syn "17.12.1 Header <compare> synopsis")namespace std {// [[optional.optional]](#optional "22.5.3 Class template optional"), class template optionaltemplate<class T>class optional; // partially freestanding// [[optional.optional.ref]](#optional.ref "22.5.4 Partial specialization of optional for reference types"), partial specialization of optional for lvalue reference 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.2 Header <optional> synopsis [optional.syn]") = requires(const T& t) { // *exposition only*[]<class U>(const optional<U>&){ }(t); }; // [[optional.nullopt]](#nullopt "22.5.5 No-value state indicator"), no-value state indicatorstruct nullopt_t{*see below*}; inline constexpr nullopt_t nullopt(*unspecified*); // [[optional.bad.access]](#bad.access "22.5.6 Class bad_­optional_­access"), class bad_optional_accessclass bad_optional_access; // [[optional.relops]](#relops "22.5.7 Relational operators"), relational 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.4 Concept 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.8 Comparison 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.9 Comparison 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.2 Header <optional> synopsis [optional.syn]")<U>) && [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4 Concept 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.10 Specialized 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.11 Hash 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.6 Iterator support")using const_iterator = *implementation-defined*; // see [[optional.iterators]](#iterators "22.5.3.6 Iterator support")// [[optional.ctor]](#ctor "22.5.3.2 Constructors"), constructorsconstexpr optional() noexcept; constexpr optional(nullopt_t) noexcept; constexpr optional(const optional&); constexpr optional(optional&&) noexcept(*see below*); 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.3 Destructor"), destructorconstexpr ~optional(); // [[optional.assign]](#assign "22.5.3.4 Assignment"), assignmentconstexpr optional& operator=(nullopt_t) noexcept; constexpr optional& operator=(const optional&); constexpr optional& operator=(optional&&) noexcept(*see below*); template<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.5 Swap"), swapconstexpr void swap(optional&) noexcept(*see below*); // [[optional.iterators]](#iterators "22.5.3.6 Iterator support"), iterator supportconstexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; // [[optional.observe]](#observe "22.5.3.7 Observers"), observersconstexpr const T* operator->() const noexcept; constexpr T* operator->() noexcept; constexpr const T& operator*() const & noexcept; constexpr T& operator*() & noexcept; constexpr T&& operator*() && noexcept; constexpr const T&& operator*() const && noexcept; constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr const T& value() const &; // freestanding-deletedconstexpr T& value() &; // freestanding-deletedconstexpr T&& value() &&; // freestanding-deletedconstexpr const T&& value() const &&; // freestanding-deletedtemplate<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.8 Monadic operations"), monadic operationstemplate<class F> constexpr auto and_then(F&& f) &; template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &; template<class F> constexpr auto and_then(F&& f) const &&; template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &; template<class F> constexpr auto transform(F&& f) const &&; template<class F> constexpr optional or_else(F&& f) &&; template<class F> constexpr optional or_else(F&& f) const &; // [[optional.mod]](#mod "22.5.3.9 Modifiers"), 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.1 General [optional.optional.general]"),
it means that an object of type T, referred to as the optional object's [*contained value*](#def:contained_value,optional "22.5.3.1 General [optional.optional.general]"),
is nested within ([[intro.object]](intro.object "6.8.2 Object model")) the optional object[.](#optional.general-1.sentence-2)

When an object of type optional<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.1 General [optional.optional.general]") for optional if X is an lvalue reference type or a complete non-array object type,
and remove_cvref_t<X> is a type other than in_place_t or nullopt_t[.](#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.6 The constexpr and consteval specifiers"))[.](#ctor-3.sentence-2)

[ð](#lib:optional,constructor_)

`constexpr optional(const optional& rhs);
`

[4](#ctor-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3424)

*Effects*: If rhs contains a value, direct-non-list-initializes the contained value
with *rhs[.](#ctor-4.sentence-1)

[5](#ctor-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3429)

*Postconditions*: rhs.has_value() == this->has_value()[.](#ctor-5.sentence-1)

[6](#ctor-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3433)

*Throws*: Any exception thrown by the selected constructor of T[.](#ctor-6.sentence-1)

[7](#ctor-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L3437)

*Remarks*: This constructor is defined as deleted unlessis_copy_constructible_v<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.3 Swappable requirements [swappable.requirements]") requirements ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements"))[.](#swap-2.sentence-1)

[3](#swap-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4007)

*Effects*: See Table [71](#tab:optional.swap "Table 71: optional​::​swap(optional&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.14 Concept contiguous_­iterator [iterator.concept.contiguous]") ([[iterator.concept.contiguous]](iterator.concept.contiguous "24.3.4.14 Concept contiguous_­iterator")),
meet the [*Cpp17RandomAccessIterator*](random.access.iterators#:Cpp17RandomAccessIterator "24.3.5.7 Random access iterators [random.access.iterators]") requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7 Random access iterators")), and
meet the requirements for constexpr iterators ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General")),
with value type remove_cv_t<T>[.](#iterators-1.sentence-1)

The reference type is T& for iterator andconst T& for const_iterator[.](#iterators-1.sentence-2)

[2](#iterators-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4068)

All requirements on container iterators ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")) apply tooptional​::​iterator and optional​::​const_iterator as well[.](#iterators-2.sentence-1)

[3](#iterators-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4072)

Any operation that initializes or destroys the contained value of an optional object invalidates all iterators into that object[.](#iterators-3.sentence-1)

[ð](#lib:begin,optional)

`constexpr iterator begin() noexcept;
constexpr const_iterator begin() const noexcept;
`

[4](#iterators-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4083)

*Returns*: If has_value() is true,
an iterator referring to the contained value[.](#iterators-4.sentence-1)

Otherwise, a past-the-end iterator value[.](#iterators-4.sentence-2)

[ð](#lib:end,optional)

`constexpr iterator end() noexcept;
constexpr const_iterator end() const noexcept;
`

[5](#iterators-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4097)

*Returns*: begin() + has_value()[.](#iterators-5.sentence-1)

#### [22.5.3.7](#observe) Observers [[optional.observe]](optional.observe)

[ð](#lib:operator-%3e,optional)

`constexpr const T* operator->() const noexcept;
constexpr T* operator->() noexcept;
`

[1](#observe-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4111)

*Hardened preconditions*: has_value() is true[.](#observe-1.sentence-1)

[2](#observe-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4115)

*Returns*: val[.](#observe-2.sentence-1)

[3](#observe-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4119)

*Remarks*: These functions are constexpr functions[.](#observe-3.sentence-1)

[ð](#lib:operator*,optional)

`constexpr const T& operator*() const & noexcept;
constexpr T& operator*() & noexcept;
`

[4](#observe-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4131)

*Hardened preconditions*: has_value() is true[.](#observe-4.sentence-1)

[5](#observe-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4135)

*Returns*: *val[.](#observe-5.sentence-1)

[6](#observe-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4139)

*Remarks*: These functions are constexpr functions[.](#observe-6.sentence-1)

[ð](#lib:operator*,optional_)

`constexpr T&& operator*() && noexcept;
constexpr const T&& operator*() const && noexcept;
`

[7](#observe-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4151)

*Hardened preconditions*: has_value() is true[.](#observe-7.sentence-1)

[8](#observe-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4155)

*Effects*: Equivalent to: return std​::​move(*val);

[ð](#lib:operator_bool,optional)

`constexpr explicit operator bool() const noexcept;
`

[9](#observe-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4166)

*Returns*: true if and only if *this contains a value[.](#observe-9.sentence-1)

[10](#observe-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4170)

*Remarks*: This function is a constexpr function[.](#observe-10.sentence-1)

[ð](#lib:has_value,optional)

`constexpr bool has_value() const noexcept;
`

[11](#observe-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4181)

*Returns*: true if and only if *this contains a value[.](#observe-11.sentence-1)

[12](#observe-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4185)

*Remarks*: This function is a constexpr function[.](#observe-12.sentence-1)

[ð](#lib:value,optional)

`constexpr const T& value() const &;
constexpr T& value() &;
`

[13](#observe-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4197)

*Effects*: Equivalent to:return has_value() ? *val : throw bad_optional_access();

[ð](#lib:value,optional_)

`constexpr T&& value() &&;
constexpr const T&& value() const &&;
`

[14](#observe-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4213)

*Effects*: Equivalent to:return has_value() ? std::move(*val) : throw bad_optional_access();

[ð](#lib:value_or,optional)

`template<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.1 General"))[.](#monadic-8.sentence-3)

â *end note*]

[9](#monadic-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4333)

*Returns*: If *this contains a value, an optional<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.1 General"))[.](#monadic-11.sentence-3)

â *end note*]

[12](#monadic-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4364)

*Returns*: If *this contains a value, an optional<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.2 Concept invocable [concept.invocable]") andT models [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_­constructible [concept.copyconstructible]")[.](#monadic-13.sentence-1)

[14](#monadic-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4383)

*Mandates*: is_same_v<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.2 Concept invocable [concept.invocable]") andT models [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_­constructible [concept.moveconstructible]")[.](#monadic-16.sentence-1)

[17](#monadic-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4410)

*Mandates*: is_same_v<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.5 Iterator support")public:// [[optional.ref.ctor]](#ref.ctor "22.5.4.2 Constructors"), constructorsconstexpr optional() noexcept = default; constexpr optional(nullopt_t) noexcept : optional() {}constexpr optional(const optional& rhs) noexcept = default; 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.3 Assignment"), 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.4 Swap"), swapconstexpr void swap(optional& rhs) noexcept; // [[optional.ref.iterators]](#ref.iterators "22.5.4.5 Iterator support"), iterator supportconstexpr iterator begin() const noexcept; constexpr iterator end() const noexcept; // [[optional.ref.observe]](#ref.observe "22.5.4.6 Observers"), observersconstexpr T* operator->() const noexcept; constexpr T& operator*() const noexcept; constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr T& value() const; // freestanding-deletedtemplate<class U = remove_cv_t<T>>constexpr remove_cv_t<T> value_or(U&& u) const; // [[optional.ref.monadic]](#ref.monadic "22.5.4.7 Monadic 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.8 Modifiers"), modifiersconstexpr void reset() noexcept; private: T* *val* = nullptr; // *exposition only*// [[optional.ref.expos]](#ref.expos "22.5.4.9 Exposition only helper functions"), exposition only helper 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.1 General [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.1 General [optional.optional.ref.general]") is a reference to **val*[.](#optional.ref.general-1.sentence-2)

#### [22.5.4.2](#ref.ctor) Constructors [[optional.ref.ctor]](optional.ref.ctor)

[ð](#ref.ctor-itemdecl:1)

`template<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.14 Concept contiguous_­iterator [iterator.concept.contiguous]") ([[iterator.concept.contiguous]](iterator.concept.contiguous "24.3.4.14 Concept contiguous_­iterator")),
meets the *Cpp17RandomAccessIterator* requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7 Random access iterators")),
and meets the requirements for constexpr iterators ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General")),
with value type remove_cv_t<T>[.](#ref.iterators-1.sentence-1)

The reference type is T& for iterator[.](#ref.iterators-1.sentence-2)

[2](#ref.iterators-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4769)

All requirements on container iterators ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")) apply tooptional​::​iterator[.](#ref.iterators-2.sentence-1)

[ð](#ref.iterators-itemdecl:2)

`constexpr iterator begin() const noexcept;
`

[3](#ref.iterators-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4779)

*Returns*: If has_value() is true,
 an iterator referring to **val*[.](#ref.iterators-3.sentence-1)

Otherwise, a past-the-end iterator value[.](#ref.iterators-3.sentence-2)

[ð](#ref.iterators-itemdecl:3)

`constexpr iterator end() const noexcept;
`

[4](#ref.iterators-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4791)

*Returns*: begin() + has_value()[.](#ref.iterators-4.sentence-1)

#### [22.5.4.6](#ref.observe) Observers [[optional.ref.observe]](optional.ref.observe)

[ð](#ref.observe-itemdecl:1)

`constexpr T* operator->() const noexcept;
`

[1](#ref.observe-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4803)

*Hardened preconditions*: has_value() is true[.](#ref.observe-1.sentence-1)

[2](#ref.observe-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4807)

*Returns*: *val*[.](#ref.observe-2.sentence-1)

[ð](#ref.observe-itemdecl:2)

`constexpr T& operator*() const noexcept;
`

[3](#ref.observe-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4818)

*Hardened preconditions*: has_value() is true[.](#ref.observe-3.sentence-1)

[4](#ref.observe-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4822)

*Returns*: **val*[.](#ref.observe-4.sentence-1)

[ð](#ref.observe-itemdecl:3)

`constexpr explicit operator bool() const noexcept;
`

[5](#ref.observe-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4832)

*Returns*: *val* != nullptr[.](#ref.observe-5.sentence-1)

[ð](#ref.observe-itemdecl:4)

`constexpr bool has_value() const noexcept;
`

[6](#ref.observe-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4842)

*Returns*: *val* != nullptr[.](#ref.observe-6.sentence-1)

[ð](#ref.observe-itemdecl:5)

`constexpr T& value() const;
`

[7](#ref.observe-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4852)

*Effects*: Equivalent to:return has_value() ? **val* : throw bad_optional_access();

[ð](#ref.observe-itemdecl:6)

`template<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.1 General"))[.](#ref.monadic-5.sentence-2)

â *end note*]

[6](#ref.monadic-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4926)

*Returns*: If *this contains a value, an optional<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.2 Concept invocable [concept.invocable]")[.](#ref.monadic-7.sentence-1)

[8](#ref.monadic-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L4943)

*Mandates*: is_same_v<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.3 Class exception") for the specification of the special member functionsconstexpr const char* what() const noexcept override; };}

[1](#bad.access-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5018)

The class bad_optional_access defines the type of objects thrown as exceptions to report the situation where an attempt is made to access the value of an optional object that does not contain a value[.](#bad.access-1.sentence-1)

[ð](#lib:what,bad_optional_access)

`constexpr const char* what() const noexcept override;
`

[2](#bad.access-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5027)

*Returns*: An implementation-defined ntbs,
which during constant evaluation is encoded with
the ordinary literal encoding ([[lex.ccon]](lex.ccon "5.13.3 Character literals"))[.](#bad.access-2.sentence-1)

### [22.5.7](#relops) Relational operators [[optional.relops]](optional.relops)

[ð](#lib:operator==,optional)

`template<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.2 Template argument requirements [utility.arg.requirements]")[.](#relops-1.sentence-2)

â *end note*]

[2](#relops-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5050)

*Returns*: If x.has_value() != y.has_value(), false; otherwise if x.has_value() == false, true; otherwise *x == *y[.](#relops-2.sentence-1)

[3](#relops-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5054)

*Remarks*: Specializations of this function template
for which *x == *y is a core constant expression
are constexpr functions[.](#relops-3.sentence-1)

[ð](#lib:operator!=,optional)

`template<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.4 Concept 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.2 Template argument requirements [utility.arg.requirements]")[.](#comp.with.t-1.sentence-3)

â *end note*]

[2](#comp.with.t-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5241)

*Effects*: Equivalent to: return x.has_value() ? *x == v : false;

[ð](#lib:operator==,optional___)

`template<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.2 Header <optional> synopsis [optional.syn]")<U>) && [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4 Concept 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.3 Names of template specializations [temp.names]") that
begins with a type [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")[.](#specalg-3.sentence-1)

[4](#specalg-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5480)

*Returns*: optional<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.19 Class 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)
