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

2657 lines
101 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

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

[expected]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [expected]
### [22.8.1](#general) General [[expected.general]](expected.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7656)
Subclause [expected] describes the class template expected that represents expected objects[.](#general-1.sentence-1)
An expected<T, E> object holds
an object of type T or an object of type E and
manages the lifetime of the contained objects[.](#general-1.sentence-2)
### [22.8.2](#syn) Header <expected> synopsis [[expected.syn]](expected.syn)
[🔗](#header:%3cexpected%3e)
// mostly freestandingnamespace std {// [[expected.unexpected]](#unexpected "22.8.3Class template unexpected"), class template unexpectedtemplate<class E> class unexpected; // [[expected.bad]](#bad "22.8.4Class template bad_­expected_­access"), class template bad_expected_accesstemplate<class E> class bad_expected_access; // [[expected.bad.void]](#bad.void "22.8.5Class template specialization bad_­expected_­access<void>"), specialization for voidtemplate<> class bad_expected_access<void>; // in-place construction of unexpected valuesstruct unexpect_t {explicit unexpect_t() = default; }; inline constexpr unexpect_t unexpect{}; // [[expected.expected]](#expected "22.8.6Class template expected"), class template expectedtemplate<class T, class E> class expected; // partially freestanding// [[expected.void]](#void "22.8.7Partial specialization of expected for void types"), partial specialization of expected for void typestemplate<class T, class E> requires is_void_v<T> class expected<T, E>; // partially freestanding}
### [22.8.3](#unexpected) Class template unexpected [[expected.unexpected]](expected.unexpected)
#### [22.8.3.1](#un.general) General [[expected.un.general]](expected.un.general)
[1](#un.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7698)
Subclause [[expected.unexpected]](#unexpected "22.8.3Class template unexpected") describes the class template unexpected that represents unexpected objects stored in expected objects[.](#un.general-1.sentence-1)
[🔗](#lib:unexpected)
namespace std {template<class E>class unexpected {public:// [[expected.un.cons]](#un.cons "22.8.3.2Constructors"), constructorsconstexpr unexpected(const unexpected&) = default; constexpr unexpected(unexpected&&) = default; template<class Err = E>constexpr explicit unexpected(Err&&); template<class... Args>constexpr explicit unexpected(in_place_t, Args&&...); template<class U, class... Args>constexpr explicit unexpected(in_place_t, initializer_list<U>, Args&&...); constexpr unexpected& operator=(const unexpected&) = default; constexpr unexpected& operator=(unexpected&&) = default; constexpr const E& error() const & noexcept; constexpr E& error() & noexcept; constexpr const E&& error() const && noexcept; constexpr E&& error() && noexcept; constexpr void swap(unexpected& other) noexcept(*see below*); template<class E2>friend constexpr bool operator==(const unexpected&, const unexpected<E2>&); friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y))); private: E *unex*; // *exposition only*}; template<class E> unexpected(E) -> unexpected<E>;}
[2](#un.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7741)
A program that instantiates the definition of unexpected for
a non-object type,
an array type,
a specialization of unexpected, or
a cv-qualified type
is ill-formed[.](#un.general-2.sentence-1)
#### [22.8.3.2](#un.cons) Constructors [[expected.un.cons]](expected.un.cons)
[🔗](#lib:unexpected,constructor)
`template<class Err = E>
constexpr explicit unexpected(Err&& e);
`
[1](#un.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7758)
*Constraints*:
- [(1.1)](#un.cons-1.1)
is_same_v<remove_cvref_t<Err>, unexpected> is false; and
- [(1.2)](#un.cons-1.2)
is_same_v<remove_cvref_t<Err>, in_place_t> is false; and
- [(1.3)](#un.cons-1.3)
is_constructible_v<E, Err> is true[.](#un.cons-1.sentence-1)
[2](#un.cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7769)
*Effects*: Direct-non-list-initializes *unex* with std::forward<Err>(e)[.](#un.cons-2.sentence-1)
[3](#un.cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7773)
*Throws*: Any exception thrown by the initialization of *unex*[.](#un.cons-3.sentence-1)
[🔗](#lib:unexpected,constructor_)
`template<class... Args>
constexpr explicit unexpected(in_place_t, Args&&... args);
`
[4](#un.cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7785)
*Constraints*: is_constructible_v<E, Args...> is true[.](#un.cons-4.sentence-1)
[5](#un.cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7789)
*Effects*: Direct-non-list-initializes*unex* with std::forward<Args>(args)...[.](#un.cons-5.sentence-1)
[6](#un.cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7794)
*Throws*: Any exception thrown by the initialization of *unex*[.](#un.cons-6.sentence-1)
[🔗](#lib:unexpected,constructor__)
`template<class U, class... Args>
constexpr explicit unexpected(in_place_t, initializer_list<U> il, Args&&... args);
`
[7](#un.cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7806)
*Constraints*: is_constructible_v<E, initializer_list<U>&, Args...> is true[.](#un.cons-7.sentence-1)
[8](#un.cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7810)
*Effects*: Direct-non-list-initializes*unex* with il, std::forward<Args>(args)...[.](#un.cons-8.sentence-1)
[9](#un.cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7815)
*Throws*: Any exception thrown by the initialization of *unex*[.](#un.cons-9.sentence-1)
#### [22.8.3.3](#un.obs) Observers [[expected.un.obs]](expected.un.obs)
[🔗](#lib:error,unexpected)
`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`
[1](#un.obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7829)
*Returns*: *unex*[.](#un.obs-1.sentence-1)
[🔗](#lib:error,unexpected_)
`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`
[2](#un.obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7841)
*Returns*: std::move(*unex*)[.](#un.obs-2.sentence-1)
#### [22.8.3.4](#un.swap) Swap [[expected.un.swap]](expected.un.swap)
[🔗](#lib:swap,unexpected)
`constexpr void swap(unexpected& other) noexcept(is_nothrow_swappable_v<E>);
`
[1](#un.swap-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7854)
*Mandates*: is_swappable_v<E> is true[.](#un.swap-1.sentence-1)
[2](#un.swap-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7858)
*Effects*: Equivalent to:using std::swap; swap(*unex*, other.*unex*);
[🔗](#un.swap-itemdecl:2)
`friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y)));
`
[3](#un.swap-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7869)
*Constraints*: is_swappable_v<E> is true[.](#un.swap-3.sentence-1)
[4](#un.swap-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7873)
*Effects*: Equivalent to x.swap(y)[.](#un.swap-4.sentence-1)
#### [22.8.3.5](#un.eq) Equality operator [[expected.un.eq]](expected.un.eq)
[🔗](#lib:operator==,unexpected)
`template<class E2>
friend constexpr bool operator==(const unexpected& x, const unexpected<E2>& y);
`
[1](#un.eq-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7887)
*Mandates*: The expression x.error() == y.error() is well-formed and
its result is convertible to bool[.](#un.eq-1.sentence-1)
[2](#un.eq-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7892)
*Returns*: x.error() == y.error()[.](#un.eq-2.sentence-1)
### [22.8.4](#bad) Class template bad_expected_access [[expected.bad]](expected.bad)
[🔗](#lib:bad_expected_access)
namespace std {template<class E>class bad_expected_access : public bad_expected_access<void> {public:constexpr explicit bad_expected_access(E); constexpr const char* what() const noexcept override; constexpr E& error() & noexcept; constexpr const E& error() const & noexcept; constexpr E&& error() && noexcept; constexpr const E&& error() const && noexcept; private: E *unex*; // *exposition only*};}
[1](#bad-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7918)
The class template bad_expected_access defines the type of objects thrown as exceptions to report the situation
where an attempt is made to access the value of an expected<T, E> object
for which has_value() is false[.](#bad-1.sentence-1)
[🔗](#lib:bad_expected_access,constructor)
`constexpr explicit bad_expected_access(E e);
`
[2](#bad-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7930)
*Effects*: Initializes *unex* with std::move(e)[.](#bad-2.sentence-1)
[🔗](#lib:error,bad_expected_access)
`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`
[3](#bad-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7942)
*Returns*: *unex*[.](#bad-3.sentence-1)
[🔗](#lib:error,bad_expected_access_)
`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`
[4](#bad-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7954)
*Returns*: std::move(*unex*)[.](#bad-4.sentence-1)
[🔗](#lib:what,bad_expected_access)
`constexpr const char* what() const noexcept override;
`
[5](#bad-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7965)
*Returns*: An implementation-defined ntbs,
which during constant evaluation is encoded with
the ordinary literal encoding ([[lex.ccon]](lex.ccon "5.13.3Character literals"))[.](#bad-5.sentence-1)
### [22.8.5](#bad.void) Class template specialization bad_expected_access<void> [[expected.bad.void]](expected.bad.void)
namespace std {template<>class bad_expected_access<void> : public exception {protected:constexpr bad_expected_access() noexcept; constexpr bad_expected_access(const bad_expected_access&) noexcept; constexpr bad_expected_access(bad_expected_access&&) noexcept; constexpr bad_expected_access& operator=(const bad_expected_access&) noexcept; constexpr bad_expected_access& operator=(bad_expected_access&&) noexcept; constexpr ~bad_expected_access(); public:constexpr const char* what() const noexcept override; };}
[🔗](#lib:what,bad_expected_access_)
`constexpr const char* what() const noexcept override;
`
[1](#bad.void-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7998)
*Returns*: An implementation-defined ntbs,
which during constant evaluation is encoded with
the ordinary literal encoding ([[lex.ccon]](lex.ccon "5.13.3Character literals"))[.](#bad.void-1.sentence-1)
### [22.8.6](#expected) Class template expected [[expected.expected]](expected.expected)
#### [22.8.6.1](#object.general) General [[expected.object.general]](expected.object.general)
namespace std {template<class T, class E>class expected {public:using [value_type](#lib:expected,value_type "22.8.6.1General[expected.object.general]") = T; using [error_type](#lib:expected,error_type "22.8.6.1General[expected.object.general]") = E; using [unexpected_type](#lib:expected,unexpected_type "22.8.6.1General[expected.object.general]") = unexpected<E>; template<class U>using [rebind](#lib:expected,rebind "22.8.6.1General[expected.object.general]") = expected<U, error_type>; // [[expected.object.cons]](#object.cons "22.8.6.2Constructors"), constructorsconstexpr expected(); constexpr expected(const expected&); constexpr expected(expected&&) noexcept(*see below*); template<class U, class G>constexpr explicit(*see below*) expected(const expected<U, G>&); template<class U, class G>constexpr explicit(*see below*) expected(expected<U, G>&&); template<class U = remove_cv_t<T>>constexpr explicit(*see below*) expected(U&& v); template<class G>constexpr explicit(*see below*) expected(const unexpected<G>&); template<class G>constexpr explicit(*see below*) expected(unexpected<G>&&); template<class... Args>constexpr explicit expected(in_place_t, Args&&...); template<class U, class... Args>constexpr explicit expected(in_place_t, initializer_list<U>, Args&&...); template<class... Args>constexpr explicit expected(unexpect_t, Args&&...); template<class U, class... Args>constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...); // [[expected.object.dtor]](#object.dtor "22.8.6.3Destructor"), destructorconstexpr ~expected(); // [[expected.object.assign]](#object.assign "22.8.6.4Assignment"), assignmentconstexpr expected& operator=(const expected&); constexpr expected& operator=(expected&&) noexcept(*see below*); template<class U = remove_cv_t<T>> constexpr expected& operator=(U&&); template<class G>constexpr expected& operator=(const unexpected<G>&); template<class G>constexpr expected& operator=(unexpected<G>&&); template<class... Args>constexpr T& emplace(Args&&...) noexcept; template<class U, class... Args>constexpr T& emplace(initializer_list<U>, Args&&...) noexcept; // [[expected.object.swap]](#object.swap "22.8.6.5Swap"), swapconstexpr void swap(expected&) noexcept(*see below*); friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y))); // [[expected.object.obs]](#object.obs "22.8.6.6Observers"), observersconstexpr const T* operator->() const noexcept; constexpr T* operator->() noexcept; constexpr const T& operator*() const & noexcept; constexpr T& operator*() & noexcept; constexpr const T&& operator*() const && noexcept; constexpr T&& operator*() && noexcept; constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr const T& value() const &; // freestanding-deletedconstexpr T& value() &; // freestanding-deletedconstexpr const T&& value() const &&; // freestanding-deletedconstexpr T&& value() &&; // freestanding-deletedconstexpr const E& error() const & noexcept; constexpr E& error() & noexcept; constexpr const E&& error() const && noexcept; constexpr E&& error() && noexcept; template<class U = remove_cv_t<T>> constexpr T value_or(U&&) const &; template<class U = remove_cv_t<T>> constexpr T value_or(U&&) &&; template<class G = E> constexpr E error_or(G&&) const &; template<class G = E> constexpr E error_or(G&&) &&; // [[expected.object.monadic]](#object.monadic "22.8.6.7Monadic 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 or_else(F&& f) &; template<class F> constexpr auto or_else(F&& f) &&; template<class F> constexpr auto or_else(F&& f) const &; template<class F> constexpr auto or_else(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 auto transform_error(F&& f) &; template<class F> constexpr auto transform_error(F&& f) &&; template<class F> constexpr auto transform_error(F&& f) const &; template<class F> constexpr auto transform_error(F&& f) const &&; // [[expected.object.eq]](#object.eq "22.8.6.8Equality operators"), equality operatorstemplate<class T2, class E2> requires (!is_void_v<T2>)friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y); template<class T2>friend constexpr bool operator==(const expected&, const T2&); template<class E2>friend constexpr bool operator==(const expected&, const unexpected<E2>&); private:bool *has_val*; // *exposition only*union { T *val*; // *exposition only* E *unex*; // *exposition only*}; };}
[1](#object.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8126)
Any object of type expected<T, E> either
contains a value of type T or
a value of type E nested within ([[intro.object]](intro.object "6.8.2Object model")) it[.](#object.general-1.sentence-1)
Member *has_val* indicates whether the expected<T, E> object
contains an object of type T[.](#object.general-1.sentence-2)
[2](#object.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8134)
A type T is a [*valid value type for expected*](#def:valid_value_type_for_expected),
if remove_cv_t<T> is void or a complete non-array object type that is not in_place_t,unexpect_t,
or a specialization of unexpected[.](#object.general-2.sentence-1)
A program which instantiates class template expected<T, E> with an argument T that is not a valid value
type for expected is ill-formed[.](#object.general-2.sentence-2)
A program that instantiates
the definition of the template expected<T, E> with a type for the E parameter
that is not a valid template argument for unexpected is ill-formed[.](#object.general-2.sentence-3)
[3](#object.general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8148)
When T is not cv void, it shall meet
the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements (Table [35](utility.arg.requirements#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements"))[.](#object.general-3.sentence-1)
E shall meet
the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#object.general-3.sentence-2)
#### [22.8.6.2](#object.cons) Constructors [[expected.object.cons]](expected.object.cons)
[1](#object.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8156)
The exposition-only variable template *converts-from-any-cvref* defined in [[optional.ctor]](optional.ctor "22.5.3.2Constructors") is used by some constructors for expected[.](#object.cons-1.sentence-1)
[🔗](#lib:expected,constructor)
`constexpr expected();
`
[2](#object.cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8167)
*Constraints*: is_default_constructible_v<T> is true[.](#object.cons-2.sentence-1)
[3](#object.cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8171)
*Effects*: Value-initializes *val*[.](#object.cons-3.sentence-1)
[4](#object.cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8175)
*Postconditions*: has_value() is true[.](#object.cons-4.sentence-1)
[5](#object.cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8179)
*Throws*: Any exception thrown by the initialization of *val*[.](#object.cons-5.sentence-1)
[🔗](#lib:expected,constructor_)
`constexpr expected(const expected& rhs);
`
[6](#object.cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8190)
*Effects*: If rhs.has_value() is true,
direct-non-list-initializes *val* with *rhs[.](#object.cons-6.sentence-1)
Otherwise, direct-non-list-initializes *unex* with rhs.error()[.](#object.cons-6.sentence-2)
[7](#object.cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8196)
*Postconditions*: rhs.has_value() == this->has_value()[.](#object.cons-7.sentence-1)
[8](#object.cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8200)
*Throws*: Any exception thrown by the initialization of *val* or *unex*[.](#object.cons-8.sentence-1)
[9](#object.cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8204)
*Remarks*: This constructor is defined as deleted unless
- [(9.1)](#object.cons-9.1)
is_copy_constructible_v<T> is true and
- [(9.2)](#object.cons-9.2)
is_copy_constructible_v<E> is true[.](#object.cons-9.sentence-1)
[10](#object.cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8214)
This constructor is trivial if
- [(10.1)](#object.cons-10.1)
is_trivially_copy_constructible_v<T> is true and
- [(10.2)](#object.cons-10.2)
is_trivially_copy_constructible_v<E> is true[.](#object.cons-10.sentence-1)
[🔗](#lib:expected,constructor__)
`constexpr expected(expected&& rhs) noexcept(see below);
`
[11](#object.cons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8230)
*Constraints*:
- [(11.1)](#object.cons-11.1)
is_move_constructible_v<T> is true and
- [(11.2)](#object.cons-11.2)
is_move_constructible_v<E> is true[.](#object.cons-11.sentence-1)
[12](#object.cons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8239)
*Effects*: If rhs.has_value() is true,
direct-non-list-initializes *val* with std::move(*rhs)[.](#object.cons-12.sentence-1)
Otherwise,
direct-non-list-initializes *unex* with std::move(rhs.error())[.](#object.cons-12.sentence-2)
[13](#object.cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8246)
*Postconditions*: rhs.has_value() is unchanged;rhs.has_value() == this->has_value() is true[.](#object.cons-13.sentence-1)
[14](#object.cons-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8251)
*Throws*: Any exception thrown by the initialization of *val* or *unex*[.](#object.cons-14.sentence-1)
[15](#object.cons-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8255)
*Remarks*: The exception specification is equivalent tois_nothrow_move_constructible_v<T> && is_nothrow_move_constructible_v<E>[.](#object.cons-15.sentence-1)
[16](#object.cons-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8261)
This constructor is trivial if
- [(16.1)](#object.cons-16.1)
is_trivially_move_constructible_v<T> is true and
- [(16.2)](#object.cons-16.2)
is_trivially_move_constructible_v<E> is true[.](#object.cons-16.sentence-1)
[🔗](#lib:expected,constructor___)
`template<class U, class G>
constexpr explicit(see below) expected(const expected<U, G>& rhs);
template<class U, class G>
constexpr explicit(see below) expected(expected<U, G>&& rhs);
`
[17](#object.cons-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8280)
Let:
- [(17.1)](#object.cons-17.1)
UF be const U& for the first overload andU for the second overload[.](#object.cons-17.1.sentence-1)
- [(17.2)](#object.cons-17.2)
GF be const G& for the first overload andG for the second overload[.](#object.cons-17.2.sentence-1)
[18](#object.cons-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8291)
*Constraints*:
- [(18.1)](#object.cons-18.1)
is_constructible_v<T, UF> is true; and
- [(18.2)](#object.cons-18.2)
is_constructible_v<E, GF> is true; and
- [(18.3)](#object.cons-18.3)
if T is not cv bool,*converts-from-any-cvref*<T, expected<U, G>> is false; and
- [(18.4)](#object.cons-18.4)
is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
- [(18.5)](#object.cons-18.5)
is_constructible_v<unexpected<E>, expected<U, G>> is false; and
- [(18.6)](#object.cons-18.6)
is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
- [(18.7)](#object.cons-18.7)
is_constructible_v<unexpected<E>, const expected<U, G>> is false[.](#object.cons-18.sentence-1)
[19](#object.cons-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8311)
*Effects*: If rhs.has_value(),
direct-non-list-initializes *val* with std::forward<UF>(*rhs)[.](#object.cons-19.sentence-1)
Otherwise,
direct-non-list-initializes *unex* with std::forward<GF>(rhs.error())[.](#object.cons-19.sentence-2)
[20](#object.cons-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8318)
*Postconditions*: rhs.has_value() is unchanged;rhs.has_value() == this->has_value() is true[.](#object.cons-20.sentence-1)
[21](#object.cons-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8323)
*Throws*: Any exception thrown by the initialization of *val* or *unex*[.](#object.cons-21.sentence-1)
[22](#object.cons-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8327)
*Remarks*: The expression inside explicit is equivalent to!is_convertible_v<UF, T> || !is_convertible_v<GF, E>[.](#object.cons-22.sentence-1)
[🔗](#lib:expected,constructor____)
`template<class U = remove_cv_t<T>>
constexpr explicit(!is_convertible_v<U, T>) expected(U&& v);
`
[23](#object.cons-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8340)
*Constraints*:
- [(23.1)](#object.cons-23.1)
is_same_v<remove_cvref_t<U>, in_place_t> is false; and
- [(23.2)](#object.cons-23.2)
is_same_v<remove_cvref_t<U>, expected> is false; and
- [(23.3)](#object.cons-23.3)
is_same_v<remove_cvref_t<U>, unexpect_t> is false; and
- [(23.4)](#object.cons-23.4)
remove_cvref_t<U> is not a specialization of unexpected; and
- [(23.5)](#object.cons-23.5)
is_constructible_v<T, U> is true; and
- [(23.6)](#object.cons-23.6)
if T is cv bool,remove_cvref_t<U> is not a specialization of expected[.](#object.cons-23.sentence-1)
[24](#object.cons-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8358)
*Effects*: Direct-non-list-initializes *val* with std::forward<U>(v)[.](#object.cons-24.sentence-1)
[25](#object.cons-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8362)
*Postconditions*: has_value() is true[.](#object.cons-25.sentence-1)
[26](#object.cons-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8366)
*Throws*: Any exception thrown by the initialization of *val*[.](#object.cons-26.sentence-1)
[🔗](#lib:expected,constructor_____)
`template<class G>
constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);
template<class G>
constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);
`
[27](#object.cons-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8380)
Let GF be const G& for the first overload andG for the second overload[.](#object.cons-27.sentence-1)
[28](#object.cons-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8384)
*Constraints*: is_constructible_v<E, GF> is true[.](#object.cons-28.sentence-1)
[29](#object.cons-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8388)
*Effects*: Direct-non-list-initializes *unex* with std::forward<GF>(e.error())[.](#object.cons-29.sentence-1)
[30](#object.cons-30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8392)
*Postconditions*: has_value() is false[.](#object.cons-30.sentence-1)
[31](#object.cons-31)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8396)
*Throws*: Any exception thrown by the initialization of *unex*[.](#object.cons-31.sentence-1)
[🔗](#lib:expected,constructor______)
`template<class... Args>
constexpr explicit expected(in_place_t, Args&&... args);
`
[32](#object.cons-32)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8408)
*Constraints*: is_constructible_v<T, Args...> is true[.](#object.cons-32.sentence-1)
[33](#object.cons-33)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8412)
*Effects*: Direct-non-list-initializes *val* with std::forward<Args>(args)...[.](#object.cons-33.sentence-1)
[34](#object.cons-34)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8416)
*Postconditions*: has_value() is true[.](#object.cons-34.sentence-1)
[35](#object.cons-35)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8420)
*Throws*: Any exception thrown by the initialization of *val*[.](#object.cons-35.sentence-1)
[🔗](#lib:expected,constructor_______)
`template<class U, class... Args>
constexpr explicit expected(in_place_t, initializer_list<U> il, Args&&... args);
`
[36](#object.cons-36)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8432)
*Constraints*: is_constructible_v<T, initializer_list<U>&, Args...> is true[.](#object.cons-36.sentence-1)
[37](#object.cons-37)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8436)
*Effects*: Direct-non-list-initializes *val* withil, std::forward<Args>(args)...[.](#object.cons-37.sentence-1)
[38](#object.cons-38)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8441)
*Postconditions*: has_value() is true[.](#object.cons-38.sentence-1)
[39](#object.cons-39)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8445)
*Throws*: Any exception thrown by the initialization of *val*[.](#object.cons-39.sentence-1)
[🔗](#lib:expected,constructor________)
`template<class... Args>
constexpr explicit expected(unexpect_t, Args&&... args);
`
[40](#object.cons-40)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8457)
*Constraints*: is_constructible_v<E, Args...> is true[.](#object.cons-40.sentence-1)
[41](#object.cons-41)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8461)
*Effects*: Direct-non-list-initializes *unex* withstd::forward<Args>(args)...[.](#object.cons-41.sentence-1)
[42](#object.cons-42)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8466)
*Postconditions*: has_value() is false[.](#object.cons-42.sentence-1)
[43](#object.cons-43)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8470)
*Throws*: Any exception thrown by the initialization of *unex*[.](#object.cons-43.sentence-1)
[🔗](#lib:expected,constructor_________)
`template<class U, class... Args>
constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
`
[44](#object.cons-44)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8482)
*Constraints*: is_constructible_v<E, initializer_list<U>&, Args...> is true[.](#object.cons-44.sentence-1)
[45](#object.cons-45)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8486)
*Effects*: Direct-non-list-initializes *unex* withil, std::forward<Args>(args)...[.](#object.cons-45.sentence-1)
[46](#object.cons-46)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8491)
*Postconditions*: has_value() is false[.](#object.cons-46.sentence-1)
[47](#object.cons-47)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8495)
*Throws*: Any exception thrown by the initialization of *unex*[.](#object.cons-47.sentence-1)
#### [22.8.6.3](#object.dtor) Destructor [[expected.object.dtor]](expected.object.dtor)
[🔗](#lib:expected,destructor)
`constexpr ~expected();
`
[1](#object.dtor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8508)
*Effects*: If has_value() is true, destroys *val*,
otherwise destroys *unex*[.](#object.dtor-1.sentence-1)
[2](#object.dtor-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8513)
*Remarks*: If is_trivially_destructible_v<T> is true, andis_trivially_destructible_v<E> is true,
then this destructor is a trivial destructor[.](#object.dtor-2.sentence-1)
#### [22.8.6.4](#object.assign) Assignment [[expected.object.assign]](expected.object.assign)
[1](#object.assign-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8522)
This subclause makes use of the following exposition-only function template:template<class T, class U, class... Args>constexpr void *reinit-expected*(T& newval, U& oldval, Args&&... args) { // *exposition only*if constexpr (is_nothrow_constructible_v<T, Args...>) { destroy_at(addressof(oldval));
construct_at(addressof(newval), std::forward<Args>(args)...); } else if constexpr (is_nothrow_move_constructible_v<T>) { T tmp(std::forward<Args>(args)...);
destroy_at(addressof(oldval));
construct_at(addressof(newval), std::move(tmp)); } else { U tmp(std::move(oldval));
destroy_at(addressof(oldval)); try { construct_at(addressof(newval), std::forward<Args>(args)...); } catch (...) { construct_at(addressof(oldval), std::move(tmp)); throw; }}}
[🔗](#lib:operator=,expected)
`constexpr expected& operator=(const expected& rhs);
`
[2](#object.assign-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8553)
*Effects*:
- [(2.1)](#object.assign-2.1)
If this->has_value() && rhs.has_value() is true,
equivalent to *val* = *rhs[.](#object.assign-2.1.sentence-1)
- [(2.2)](#object.assign-2.2)
Otherwise, if this->has_value() is true, equivalent to:*reinit-expected*(*unex*, *val*, rhs.error())
- [(2.3)](#object.assign-2.3)
Otherwise, if rhs.has_value() is true, equivalent to:*reinit-expected*(*val*, *unex*, *rhs)
- [(2.4)](#object.assign-2.4)
Otherwise, equivalent to *unex* = rhs.error()[.](#object.assign-2.4.sentence-1)
Then, if no exception was thrown,
equivalent to: *has_val* = rhs.has_value(); return *this;
[3](#object.assign-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8575)
*Returns*: *this[.](#object.assign-3.sentence-1)
[4](#object.assign-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8579)
*Remarks*: This operator is defined as deleted unless:
- [(4.1)](#object.assign-4.1)
is_copy_assignable_v<T> is true and
- [(4.2)](#object.assign-4.2)
is_copy_constructible_v<T> is true and
- [(4.3)](#object.assign-4.3)
is_copy_assignable_v<E> is true and
- [(4.4)](#object.assign-4.4)
is_copy_constructible_v<E> is true and
- [(4.5)](#object.assign-4.5)
is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true[.](#object.assign-4.sentence-1)
[🔗](#lib:operator=,expected_)
`constexpr expected& operator=(expected&& rhs) noexcept(see below);
`
[5](#object.assign-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8603)
*Constraints*:
- [(5.1)](#object.assign-5.1)
is_move_constructible_v<T> is true and
- [(5.2)](#object.assign-5.2)
is_move_assignable_v<T> is true and
- [(5.3)](#object.assign-5.3)
is_move_constructible_v<E> is true and
- [(5.4)](#object.assign-5.4)
is_move_assignable_v<E> is true and
- [(5.5)](#object.assign-5.5)
is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true[.](#object.assign-5.sentence-1)
[6](#object.assign-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8619)
*Effects*:
- [(6.1)](#object.assign-6.1)
If this->has_value() && rhs.has_value() is true,
equivalent to *val* = std::move(*rhs)[.](#object.assign-6.1.sentence-1)
- [(6.2)](#object.assign-6.2)
Otherwise, if this->has_value() is true, equivalent to:*reinit-expected*(*unex*, *val*, std::move(rhs.error()))
- [(6.3)](#object.assign-6.3)
Otherwise, if rhs.has_value() is true, equivalent to:*reinit-expected*(*val*, *unex*, std::move(*rhs))
- [(6.4)](#object.assign-6.4)
Otherwise, equivalent to *unex* = std::move(rhs.error())[.](#object.assign-6.4.sentence-1)
Then, if no exception was thrown,
equivalent to: has_val = rhs.has_value(); return *this;
[7](#object.assign-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8641)
*Returns*: *this[.](#object.assign-7.sentence-1)
[8](#object.assign-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8645)
*Remarks*: The exception specification is equivalent to:is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>
[🔗](#lib:operator=,expected__)
`template<class U = remove_cv_t<T>>
constexpr expected& operator=(U&& v);
`
[9](#object.assign-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8661)
*Constraints*:
- [(9.1)](#object.assign-9.1)
is_same_v<expected, remove_cvref_t<U>> is false; and
- [(9.2)](#object.assign-9.2)
remove_cvref_t<U> is not a specialization of unexpected; and
- [(9.3)](#object.assign-9.3)
is_constructible_v<T, U> is true; and
- [(9.4)](#object.assign-9.4)
is_assignable_v<T&, U> is true; and
- [(9.5)](#object.assign-9.5)
is_nothrow_constructible_v<T, U> || is_nothrow_move_constructible_v<T> ||
is_nothrow_move_constructible_v<E> is true[.](#object.assign-9.sentence-1)
[10](#object.assign-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8678)
*Effects*:
- [(10.1)](#object.assign-10.1)
If has_value() is true,
equivalent to: *val* = std::forward<U>(v);
- [(10.2)](#object.assign-10.2)
Otherwise, equivalent to:*reinit-expected*(*val*, *unex*, std::forward<U>(v));*has_val* = true;
[11](#object.assign-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8692)
*Returns*: *this[.](#object.assign-11.sentence-1)
[🔗](#lib:operator=,expected___)
`template<class G>
constexpr expected& operator=(const unexpected<G>& e);
template<class G>
constexpr expected& operator=(unexpected<G>&& e);
`
[12](#object.assign-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8706)
Let GF be const G& for the first overload andG for the second overload[.](#object.assign-12.sentence-1)
[13](#object.assign-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8710)
*Constraints*:
- [(13.1)](#object.assign-13.1)
is_constructible_v<E, GF> is true; and
- [(13.2)](#object.assign-13.2)
is_assignable_v<E&, GF> is true; and
- [(13.3)](#object.assign-13.3)
is_nothrow_constructible_v<E, GF> || is_nothrow_move_constructible_v<T> ||
is_nothrow_move_constructible_v<E> is true[.](#object.assign-13.sentence-1)
[14](#object.assign-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8722)
*Effects*:
- [(14.1)](#object.assign-14.1)
If has_value() is true, equivalent to:*reinit-expected*(*unex*, *val*, std::forward<GF>(e.error()));*has_val* = false;
- [(14.2)](#object.assign-14.2)
Otherwise, equivalent to:*unex* = std::forward<GF>(e.error());
[15](#object.assign-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8736)
*Returns*: *this[.](#object.assign-15.sentence-1)
[🔗](#lib:emplace,expected)
`template<class... Args>
constexpr T& emplace(Args&&... args) noexcept;
`
[16](#object.assign-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8748)
*Constraints*: is_nothrow_constructible_v<T, Args...> is true[.](#object.assign-16.sentence-1)
[17](#object.assign-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8752)
*Effects*: Equivalent to:if (has_value()) { destroy_at(addressof(*val*));} else { destroy_at(addressof(*unex*)); *has_val* = true;}return *construct_at(addressof(*val*), std::forward<Args>(args)...);
[🔗](#lib:emplace,expected_)
`template<class U, class... Args>
constexpr T& emplace(initializer_list<U> il, Args&&... args) noexcept;
`
[18](#object.assign-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8773)
*Constraints*: is_nothrow_constructible_v<T, initializer_list<U>&, Args...> is true[.](#object.assign-18.sentence-1)
[19](#object.assign-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8778)
*Effects*: Equivalent to:if (has_value()) { destroy_at(addressof(*val*));} else { destroy_at(addressof(*unex*)); *has_val* = true;}return *construct_at(addressof(*val*), il, std::forward<Args>(args)...);
#### [22.8.6.5](#object.swap) Swap [[expected.object.swap]](expected.object.swap)
[🔗](#lib:swap,expected)
`constexpr void swap(expected& rhs) noexcept(see below);
`
[1](#object.swap-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8800)
*Constraints*:
- [(1.1)](#object.swap-1.1)
is_swappable_v<T> is true and
- [(1.2)](#object.swap-1.2)
is_swappable_v<E> is true and
- [(1.3)](#object.swap-1.3)
is_move_constructible_v<T> && is_move_constructible_v<E> is true, and
- [(1.4)](#object.swap-1.4)
is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true[.](#object.swap-1.sentence-1)
[2](#object.swap-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8815)
*Effects*: See Table [72](#tab:expected.object.swap "Table 72: swap(expected&amp;) effects")[.](#object.swap-2.sentence-1)
Table [72](#tab:expected.object.swap) — swap(expected&) effects [[tab:expected.object.swap]](./tab:expected.object.swap)
| [🔗](#tab:expected.object.swap-row-1) | **this->has_value()** | **!this->has_value()** |
| --- | --- | --- |
| [🔗](#tab:expected.object.swap-row-2)<br>**rhs.has_value()** | equivalent to: using std::swap; swap(*val*, rhs.*val*); | calls rhs.swap(*this) |
| [🔗](#tab:expected.object.swap-row-3)<br>**!rhs.has_value()** | *see below* | equivalent to: using std::swap; swap(*unex*, rhs.*unex*); |
For the case where rhs.has_value() is false andthis->has_value() is true, equivalent to:if constexpr (is_nothrow_move_constructible_v<E>) { E tmp(std::move(rhs.*unex*));
destroy_at(addressof(rhs.*unex*)); try { construct_at(addressof(rhs.*val*), std::move(*val*));
destroy_at(addressof(*val*));
construct_at(addressof(*unex*), std::move(tmp)); } catch(...) { construct_at(addressof(rhs.*unex*), std::move(tmp)); throw; }} else { T tmp(std::move(*val*));
destroy_at(addressof(*val*)); try { construct_at(addressof(*unex*), std::move(rhs.*unex*));
destroy_at(addressof(rhs.*unex*));
construct_at(addressof(rhs.*val*), std::move(tmp)); } catch (...) { construct_at(addressof(*val*), std::move(tmp)); throw; }}*has_val* = false;
rhs.*has_val* = true;
[3](#object.swap-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8861)
*Throws*: Any exception thrown by the expressions in the *Effects*[.](#object.swap-3.sentence-1)
[4](#object.swap-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8865)
*Remarks*: The exception specification is equivalent to:is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T> && is_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>
[🔗](#lib:swap,expected_)
`friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
`
[5](#object.swap-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8880)
*Effects*: Equivalent to x.swap(y)[.](#object.swap-5.sentence-1)
#### [22.8.6.6](#object.obs) Observers [[expected.object.obs]](expected.object.obs)
[🔗](#lib:operator-%3e,expected)
`constexpr const T* operator->() const noexcept;
constexpr T* operator->() noexcept;
`
[1](#object.obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8894)
*Hardened preconditions*: has_value() is true[.](#object.obs-1.sentence-1)
[2](#object.obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8898)
*Returns*: addressof(*val*)[.](#object.obs-2.sentence-1)
[🔗](#lib:operator*,expected)
`constexpr const T& operator*() const & noexcept;
constexpr T& operator*() & noexcept;
`
[3](#object.obs-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8910)
*Hardened preconditions*: has_value() is true[.](#object.obs-3.sentence-1)
[4](#object.obs-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8914)
*Returns*: *val*[.](#object.obs-4.sentence-1)
[🔗](#lib:operator*,expected_)
`constexpr T&& operator*() && noexcept;
constexpr const T&& operator*() const && noexcept;
`
[5](#object.obs-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8926)
*Hardened preconditions*: has_value() is true[.](#object.obs-5.sentence-1)
[6](#object.obs-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8930)
*Returns*: std::move(*val*)[.](#object.obs-6.sentence-1)
[🔗](#lib:operator_bool,expected)
`constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
`
[7](#object.obs-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8943)
*Returns*: *has_val*[.](#object.obs-7.sentence-1)
[🔗](#lib:value,expected)
`constexpr const T& value() const &;
constexpr T& value() &;
`
[8](#object.obs-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8955)
*Mandates*: is_copy_constructible_v<E> is true[.](#object.obs-8.sentence-1)
[9](#object.obs-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8959)
*Returns*: *val*, if has_value() is true[.](#object.obs-9.sentence-1)
[10](#object.obs-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8963)
*Throws*: bad_expected_access(as_const(error())) if has_value() is false[.](#object.obs-10.sentence-1)
[🔗](#lib:value,expected_)
`constexpr T&& value() &&;
constexpr const T&& value() const &&;
`
[11](#object.obs-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8975)
*Mandates*: is_copy_constructible_v<E> is true andis_constructible_v<E, decltype(std::move(error()))> is true[.](#object.obs-11.sentence-1)
[12](#object.obs-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8980)
*Returns*: std::move(*val*), if has_value() is true[.](#object.obs-12.sentence-1)
[13](#object.obs-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8984)
*Throws*: bad_expected_access(std::move(error())) if has_value() is false[.](#object.obs-13.sentence-1)
[🔗](#lib:error,expected)
`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`
[14](#object.obs-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8997)
*Hardened preconditions*: has_value() is false[.](#object.obs-14.sentence-1)
[15](#object.obs-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9001)
*Returns*: *unex*[.](#object.obs-15.sentence-1)
[🔗](#lib:error,expected_)
`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`
[16](#object.obs-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9013)
*Hardened preconditions*: has_value() is false[.](#object.obs-16.sentence-1)
[17](#object.obs-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9017)
*Returns*: std::move(*unex*)[.](#object.obs-17.sentence-1)
[🔗](#lib:value_or,expected)
`template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;
`
[18](#object.obs-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9028)
*Mandates*: is_copy_constructible_v<T> is true andis_convertible_v<U, T> is true[.](#object.obs-18.sentence-1)
[19](#object.obs-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9033)
*Returns*: has_value() ? **this : static_cast<T>(std::forward<U>(v))[.](#object.obs-19.sentence-1)
[🔗](#lib:value_or,expected_)
`template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;
`
[20](#object.obs-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9044)
*Mandates*: is_move_constructible_v<T> is true andis_convertible_v<U, T> is true[.](#object.obs-20.sentence-1)
[21](#object.obs-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9049)
*Returns*: has_value() ? std::move(**this) : static_cast<T>(std::forward<U>(v))[.](#object.obs-21.sentence-1)
[🔗](#lib:error_or,expected)
`template<class G = E> constexpr E error_or(G&& e) const &;
`
[22](#object.obs-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9060)
*Mandates*: is_copy_constructible_v<E> is true andis_convertible_v<G, E> is true[.](#object.obs-22.sentence-1)
[23](#object.obs-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9065)
*Returns*: std::forward<G>(e) if has_value() is true,error() otherwise[.](#object.obs-23.sentence-1)
[🔗](#lib:error_or,expected_)
`template<class G = E> constexpr E error_or(G&& e) &&;
`
[24](#object.obs-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9077)
*Mandates*: is_move_constructible_v<E> is true andis_convertible_v<G, E> is true[.](#object.obs-24.sentence-1)
[25](#object.obs-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9082)
*Returns*: std::forward<G>(e) if has_value() is true,std::move(error()) otherwise[.](#object.obs-25.sentence-1)
#### [22.8.6.7](#object.monadic) Monadic operations [[expected.object.monadic]](expected.object.monadic)
[🔗](#lib:and_then,expected)
`template<class F> constexpr auto and_then(F&& f) &;
template<class F> constexpr auto and_then(F&& f) const &;
`
[1](#object.monadic-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9097)
Let U be remove_cvref_t<invoke_result_t<F, decltype((*val*))>>[.](#object.monadic-1.sentence-1)
[2](#object.monadic-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9100)
*Constraints*: is_constructible_v<E, decltype(error())> is true[.](#object.monadic-2.sentence-1)
[3](#object.monadic-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9104)
*Mandates*: U is a specialization of expected andis_same_v<U::error_type, E> is true[.](#object.monadic-3.sentence-1)
[4](#object.monadic-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9109)
*Effects*: Equivalent to:if (has_value())return invoke(std::forward<F>(f), *val*);elsereturn U(unexpect, error());
[🔗](#lib:and_then,expected_)
`template<class F> constexpr auto and_then(F&& f) &&;
template<class F> constexpr auto and_then(F&& f) const &&;
`
[5](#object.monadic-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9127)
Let U beremove_cvref_t<invoke_result_t<F, decltype(std::move(*val*))>>[.](#object.monadic-5.sentence-1)
[6](#object.monadic-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9131)
*Constraints*: is_constructible_v<E, decltype(std::move(error()))> is true[.](#object.monadic-6.sentence-1)
[7](#object.monadic-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9135)
*Mandates*: U is a specialization of expected andis_same_v<U::error_type, E> is true[.](#object.monadic-7.sentence-1)
[8](#object.monadic-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9140)
*Effects*: Equivalent to:if (has_value())return invoke(std::forward<F>(f), std::move(*val*));elsereturn U(unexpect, std::move(error()));
[🔗](#lib:or_else,expected)
`template<class F> constexpr auto or_else(F&& f) &;
template<class F> constexpr auto or_else(F&& f) const &;
`
[9](#object.monadic-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9158)
Let G be remove_cvref_t<invoke_result_t<F, decltype(error())>>[.](#object.monadic-9.sentence-1)
[10](#object.monadic-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9161)
*Constraints*: is_constructible_v<T, decltype((*val*))> is true[.](#object.monadic-10.sentence-1)
[11](#object.monadic-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9165)
*Mandates*: G is a specialization of expected andis_same_v<G::value_type, T> is true[.](#object.monadic-11.sentence-1)
[12](#object.monadic-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9170)
*Effects*: Equivalent to:if (has_value())return G(in_place, *val*);elsereturn invoke(std::forward<F>(f), error());
[🔗](#lib:or_else,expected_)
`template<class F> constexpr auto or_else(F&& f) &&;
template<class F> constexpr auto or_else(F&& f) const &&;
`
[13](#object.monadic-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9188)
Let G beremove_cvref_t<invoke_result_t<F, decltype(std::move(error()))>>[.](#object.monadic-13.sentence-1)
[14](#object.monadic-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9192)
*Constraints*: is_constructible_v<T, decltype(std::move(*val*))> is true[.](#object.monadic-14.sentence-1)
[15](#object.monadic-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9196)
*Mandates*: G is a specialization of expected andis_same_v<G::value_type, T> is true[.](#object.monadic-15.sentence-1)
[16](#object.monadic-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9201)
*Effects*: Equivalent to:if (has_value())return G(in_place, std::move(*val*));elsereturn invoke(std::forward<F>(f), std::move(error()));
[🔗](#lib:transform,expected)
`template<class F> constexpr auto transform(F&& f) &;
template<class F> constexpr auto transform(F&& f) const &;
`
[17](#object.monadic-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9219)
Let U beremove_cv_t<invoke_result_t<F, decltype((*val*))>>[.](#object.monadic-17.sentence-1)
[18](#object.monadic-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9223)
*Constraints*: is_constructible_v<E, decltype(error())> is true[.](#object.monadic-18.sentence-1)
[19](#object.monadic-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9227)
*Mandates*: U is a valid value type for expected[.](#object.monadic-19.sentence-1)
If is_void_v<U> is false,
the declarationU u(invoke(std::forward<F>(f), *val*)); is well-formed[.](#object.monadic-19.sentence-2)
[20](#object.monadic-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9237)
*Effects*:
- [(20.1)](#object.monadic-20.1)
If has_value() is false, returnsexpected<U, E>(unexpect, error())[.](#object.monadic-20.1.sentence-1)
- [(20.2)](#object.monadic-20.2)
Otherwise, if is_void_v<U> is false, returns anexpected<U, E> object whose *has_val* member is true and *val* member is direct-non-list-initialized withinvoke(std::forward<F>(f), *val*)[.](#object.monadic-20.2.sentence-1)
- [(20.3)](#object.monadic-20.3)
Otherwise, evaluates invoke(std::forward<F>(f), *val*) and then
returns expected<U, E>()[.](#object.monadic-20.3.sentence-1)
[🔗](#lib:transform,expected_)
`template<class F> constexpr auto transform(F&& f) &&;
template<class F> constexpr auto transform(F&& f) const &&;
`
[21](#object.monadic-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9261)
Let U beremove_cv_t<invoke_result_t<F, decltype(std::move(*val*))>>[.](#object.monadic-21.sentence-1)
[22](#object.monadic-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9265)
*Constraints*: is_constructible_v<E, decltype(std::move(error()))> is true[.](#object.monadic-22.sentence-1)
[23](#object.monadic-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9269)
*Mandates*: U is a valid value type for expected[.](#object.monadic-23.sentence-1)
If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f), std::move(*val*))); is well-formed[.](#object.monadic-23.sentence-2)
[24](#object.monadic-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9278)
*Effects*:
- [(24.1)](#object.monadic-24.1)
If has_value() is false, returnsexpected<U, E>(unexpect, std::move(error()))[.](#object.monadic-24.1.sentence-1)
- [(24.2)](#object.monadic-24.2)
Otherwise, if is_void_v<U> is false, returns anexpected<U, E> object whose *has_val* member is true and *val* member is direct-non-list-initialized withinvoke(std::forward<F>(f), std::move(*val*))[.](#object.monadic-24.2.sentence-1)
- [(24.3)](#object.monadic-24.3)
Otherwise, evaluates invoke(std::forward<F>(f), std::move(*val*)) and
then returns expected<U, E>()[.](#object.monadic-24.3.sentence-1)
[🔗](#lib:transform_error,expected)
`template<class F> constexpr auto transform_error(F&& f) &;
template<class F> constexpr auto transform_error(F&& f) const &;
`
[25](#object.monadic-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9302)
Let G be remove_cv_t<invoke_result_t<F, decltype(error())>>[.](#object.monadic-25.sentence-1)
[26](#object.monadic-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9305)
*Constraints*: is_constructible_v<T, decltype((*val*))> is true[.](#object.monadic-26.sentence-1)
[27](#object.monadic-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9309)
*Mandates*: G is a valid template argument
for unexpected ([[expected.un.general]](#un.general "22.8.3.1General")) and the declarationG g(invoke(std::forward<F>(f), error())); is well-formed[.](#object.monadic-27.sentence-1)
[28](#object.monadic-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9318)
*Returns*: If has_value() is true,expected<T, G>(in_place, *val*); otherwise, an expected<T, G> object whose *has_val* member is false and *unex* member
is direct-non-list-initialized with invoke(std::forward<F>(f), error())[.](#object.monadic-28.sentence-1)
[🔗](#lib:transform_error,expected_)
`template<class F> constexpr auto transform_error(F&& f) &&;
template<class F> constexpr auto transform_error(F&& f) const &&;
`
[29](#object.monadic-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9333)
Let G beremove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>[.](#object.monadic-29.sentence-1)
[30](#object.monadic-30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9337)
*Constraints*: is_constructible_v<T, decltype(std::move(*val*))> is true[.](#object.monadic-30.sentence-1)
[31](#object.monadic-31)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9341)
*Mandates*: G is a valid template argument
for unexpected ([[expected.un.general]](#un.general "22.8.3.1General")) and the declarationG g(invoke(std::forward<F>(f), std::move(error()))); is well-formed[.](#object.monadic-31.sentence-1)
[32](#object.monadic-32)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9350)
*Returns*: If has_value() is true,expected<T, G>(in_place, std::move(*val*)); otherwise, anexpected<T, G> object whose *has_val* member is false and *unex* member is direct-non-list-initialized withinvoke(std::forward<F>(f), std::move(error()))[.](#object.monadic-32.sentence-1)
#### [22.8.6.8](#object.eq) Equality operators [[expected.object.eq]](expected.object.eq)
[🔗](#lib:operator==,expected)
`template<class T2, class E2> requires (!is_void_v<T2>)
friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
`
[1](#object.eq-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9368)
*Constraints*: The expressions *x == *y and x.error() == y.error() are well-formed and their results are convertible to bool[.](#object.eq-1.sentence-1)
[2](#object.eq-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9373)
*Returns*: If x.has_value() does not equal y.has_value(), false;
otherwise if x.has_value() is true, *x == *y;
otherwise x.error() == y.error()[.](#object.eq-2.sentence-1)
[🔗](#lib:operator==,expected_)
`template<class T2> friend constexpr bool operator==(const expected& x, const T2& v);
`
[3](#object.eq-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9386)
*Constraints*: T2 is not a specialization of expected[.](#object.eq-3.sentence-1)
The expression *x == v is well-formed and
its result is convertible to bool[.](#object.eq-3.sentence-2)
[*Note [1](#object.eq-note-1)*:
T need not be [*Cpp17EqualityComparable*](utility.arg.requirements#:Cpp17EqualityComparable "16.4.4.2Template argument requirements[utility.arg.requirements]")[.](#object.eq-3.sentence-3)
— *end note*]
[4](#object.eq-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9395)
*Returns*: x.has_value() && static_cast<bool>(*x == v)[.](#object.eq-4.sentence-1)
[🔗](#lib:operator==,expected__)
`template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
`
[5](#object.eq-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9406)
*Constraints*: The expression x.error() == e.error() is well-formed and
its result is convertible to bool[.](#object.eq-5.sentence-1)
[6](#object.eq-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9411)
*Returns*: !x.has_value() && static_cast<bool>(x.error() == e.error())[.](#object.eq-6.sentence-1)
### [22.8.7](#void) Partial specialization of expected for void types [[expected.void]](expected.void)
#### [22.8.7.1](#void.general) General [[expected.void.general]](expected.void.general)
template<class T, class E> requires is_void_v<T>class expected<T, E> {public:using [value_type](#lib:expected%3cvoid%3e,value_type "22.8.7.1General[expected.void.general]") = T; using [error_type](#lib:expected%3cvoid%3e,error_type "22.8.7.1General[expected.void.general]") = E; using [unexpected_type](#lib:expected%3cvoid%3e,unexpected_type "22.8.7.1General[expected.void.general]") = unexpected<E>; template<class U>using [rebind](#lib:expected%3cvoid%3e,rebind "22.8.7.1General[expected.void.general]") = expected<U, error_type>; // [[expected.void.cons]](#void.cons "22.8.7.2Constructors"), constructorsconstexpr expected() noexcept; constexpr expected(const expected&); constexpr expected(expected&&) noexcept(*see below*); template<class U, class G>constexpr explicit(*see below*) expected(const expected<U, G>&); template<class U, class G>constexpr explicit(*see below*) expected(expected<U, G>&&); template<class G>constexpr explicit(*see below*) expected(const unexpected<G>&); template<class G>constexpr explicit(*see below*) expected(unexpected<G>&&); constexpr explicit expected(in_place_t) noexcept; template<class... Args>constexpr explicit expected(unexpect_t, Args&&...); template<class U, class... Args>constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...); // [[expected.void.dtor]](#void.dtor "22.8.7.3Destructor"), destructorconstexpr ~expected(); // [[expected.void.assign]](#void.assign "22.8.7.4Assignment"), assignmentconstexpr expected& operator=(const expected&); constexpr expected& operator=(expected&&) noexcept(*see below*); template<class G>constexpr expected& operator=(const unexpected<G>&); template<class G>constexpr expected& operator=(unexpected<G>&&); constexpr void emplace() noexcept; // [[expected.void.swap]](#void.swap "22.8.7.5Swap"), swapconstexpr void swap(expected&) noexcept(*see below*); friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y))); // [[expected.void.obs]](#void.obs "22.8.7.6Observers"), observersconstexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr void operator*() const noexcept; constexpr void value() const &; // freestanding-deletedconstexpr void value() &&; // freestanding-deletedconstexpr const E& error() const & noexcept; constexpr E& error() & noexcept; constexpr const E&& error() const && noexcept; constexpr E&& error() && noexcept; template<class G = E> constexpr E error_or(G&&) const &; template<class G = E> constexpr E error_or(G&&) &&; // [[expected.void.monadic]](#void.monadic "22.8.7.7Monadic 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 or_else(F&& f) &; template<class F> constexpr auto or_else(F&& f) &&; template<class F> constexpr auto or_else(F&& f) const &; template<class F> constexpr auto or_else(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 auto transform_error(F&& f) &; template<class F> constexpr auto transform_error(F&& f) &&; template<class F> constexpr auto transform_error(F&& f) const &; template<class F> constexpr auto transform_error(F&& f) const &&; // [[expected.void.eq]](#void.eq "22.8.7.8Equality operators"), equality operatorstemplate<class T2, class E2> requires is_void_v<T2>friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y); template<class E2>friend constexpr bool operator==(const expected&, const unexpected<E2>&);
private:bool *has_val*; // *exposition only*union { E *unex*; // *exposition only*};};
[1](#void.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9513)
Any object of type expected<T, E> either
represents a value of type T, or
contains a value of type E nested within ([[intro.object]](intro.object "6.8.2Object model")) it[.](#void.general-1.sentence-1)
Member *has_val* indicates whether the expected<T, E> object
represents a value of type T[.](#void.general-1.sentence-2)
[2](#void.general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9521)
A program that instantiates
the definition of the template expected<T, E> with
a type for the E parameter that
is not a valid template argument for unexpected is ill-formed[.](#void.general-2.sentence-1)
[3](#void.general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9527)
E shall meet the requirements of[*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") (Table [35](utility.arg.requirements#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements"))[.](#void.general-3.sentence-1)
#### [22.8.7.2](#void.cons) Constructors [[expected.void.cons]](expected.void.cons)
[🔗](#lib:expected%3cvoid%3e,constructor)
`constexpr expected() noexcept;
`
[1](#void.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9539)
*Postconditions*: has_value() is true[.](#void.cons-1.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor_)
`constexpr expected(const expected& rhs);
`
[2](#void.cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9550)
*Effects*: If rhs.has_value() is false,
direct-non-list-initializes *unex* with rhs.error()[.](#void.cons-2.sentence-1)
[3](#void.cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9555)
*Postconditions*: rhs.has_value() == this->has_value()[.](#void.cons-3.sentence-1)
[4](#void.cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9559)
*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-4.sentence-1)
[5](#void.cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9563)
*Remarks*: This constructor is defined as deleted
unless is_copy_constructible_v<E> is true[.](#void.cons-5.sentence-1)
[6](#void.cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9568)
This constructor is trivial
if is_trivially_copy_constructible_v<E> is true[.](#void.cons-6.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor__)
`constexpr expected(expected&& rhs) noexcept(is_nothrow_move_constructible_v<E>);
`
[7](#void.cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9579)
*Constraints*: is_move_constructible_v<E> is true[.](#void.cons-7.sentence-1)
[8](#void.cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9583)
*Effects*: If rhs.has_value() is false,
direct-non-list-initializes *unex* with std::move(rhs.error())[.](#void.cons-8.sentence-1)
[9](#void.cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9588)
*Postconditions*: rhs.has_value() is unchanged;rhs.has_value() == this->has_value() is true[.](#void.cons-9.sentence-1)
[10](#void.cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9593)
*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-10.sentence-1)
[11](#void.cons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9597)
*Remarks*: This constructor is trivial
if is_trivially_move_constructible_v<E> is true[.](#void.cons-11.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor___)
`template<class U, class G>
constexpr explicit(!is_convertible_v<const G&, E>) expected(const expected<U, G>& rhs);
template<class U, class G>
constexpr explicit(!is_convertible_v<G, E>) expected(expected<U, G>&& rhs);
`
[12](#void.cons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9612)
Let GF be const G& for the first overload andG for the second overload[.](#void.cons-12.sentence-1)
[13](#void.cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9616)
*Constraints*:
- [(13.1)](#void.cons-13.1)
is_void_v<U> is true; and
- [(13.2)](#void.cons-13.2)
is_constructible_v<E, GF> is true; and
- [(13.3)](#void.cons-13.3)
is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
- [(13.4)](#void.cons-13.4)
is_constructible_v<unexpected<E>, expected<U, G>> is false; and
- [(13.5)](#void.cons-13.5)
is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
- [(13.6)](#void.cons-13.6)
is_constructible_v<unexpected<E>, const expected<U, G>> is false[.](#void.cons-13.sentence-1)
[14](#void.cons-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9637)
*Effects*: If rhs.has_value() is false,
direct-non-list-initializes *unex* with std::forward<GF>(rhs.error())[.](#void.cons-14.sentence-1)
[15](#void.cons-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9643)
*Postconditions*: rhs.has_value() is unchanged;rhs.has_value() == this->has_value() is true[.](#void.cons-15.sentence-1)
[16](#void.cons-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9648)
*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-16.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor____)
`template<class G>
constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);
template<class G>
constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);
`
[17](#void.cons-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9662)
Let GF be const G& for the first overload andG for the second overload[.](#void.cons-17.sentence-1)
[18](#void.cons-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9666)
*Constraints*: is_constructible_v<E, GF> is true[.](#void.cons-18.sentence-1)
[19](#void.cons-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9670)
*Effects*: Direct-non-list-initializes *unex* with std::forward<GF>(e.error())[.](#void.cons-19.sentence-1)
[20](#void.cons-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9675)
*Postconditions*: has_value() is false[.](#void.cons-20.sentence-1)
[21](#void.cons-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9679)
*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-21.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor_____)
`constexpr explicit expected(in_place_t) noexcept;
`
[22](#void.cons-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9690)
*Postconditions*: has_value() is true[.](#void.cons-22.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor______)
`template<class... Args>
constexpr explicit expected(unexpect_t, Args&&... args);
`
[23](#void.cons-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9702)
*Constraints*: is_constructible_v<E, Args...> is true[.](#void.cons-23.sentence-1)
[24](#void.cons-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9706)
*Effects*: Direct-non-list-initializes *unex* with std::forward<Args>(args)...[.](#void.cons-24.sentence-1)
[25](#void.cons-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9711)
*Postconditions*: has_value() is false[.](#void.cons-25.sentence-1)
[26](#void.cons-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9715)
*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-26.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor_______)
`template<class U, class... Args>
constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
`
[27](#void.cons-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9727)
*Constraints*: is_constructible_v<E, initializer_list<U>&, Args...> is true[.](#void.cons-27.sentence-1)
[28](#void.cons-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9731)
*Effects*: Direct-non-list-initializes *unex* with il, std::forward<Args>(args)...[.](#void.cons-28.sentence-1)
[29](#void.cons-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9736)
*Postconditions*: has_value() is false[.](#void.cons-29.sentence-1)
[30](#void.cons-30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9740)
*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-30.sentence-1)
#### [22.8.7.3](#void.dtor) Destructor [[expected.void.dtor]](expected.void.dtor)
[🔗](#lib:expected%3cvoid%3e,destructor)
`constexpr ~expected();
`
[1](#void.dtor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9753)
*Effects*: If has_value() is false, destroys *unex*[.](#void.dtor-1.sentence-1)
[2](#void.dtor-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9757)
*Remarks*: If is_trivially_destructible_v<E> is true,
then this destructor is a trivial destructor[.](#void.dtor-2.sentence-1)
#### [22.8.7.4](#void.assign) Assignment [[expected.void.assign]](expected.void.assign)
[🔗](#lib:operator=,expected%3cvoid%3e)
`constexpr expected& operator=(const expected& rhs);
`
[1](#void.assign-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9771)
*Effects*:
- [(1.1)](#void.assign-1.1)
If this->has_value() && rhs.has_value() is true, no effects[.](#void.assign-1.1.sentence-1)
- [(1.2)](#void.assign-1.2)
Otherwise, if this->has_value() is true,
equivalent to: construct_at(addressof(*unex*), rhs.*unex*); *has_val* = false;
- [(1.3)](#void.assign-1.3)
Otherwise, if rhs.has_value() is true,
destroys *unex* and sets *has_val* to true[.](#void.assign-1.3.sentence-1)
- [(1.4)](#void.assign-1.4)
Otherwise, equivalent to *unex* = rhs.error()[.](#void.assign-1.4.sentence-1)
[2](#void.assign-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9786)
*Returns*: *this[.](#void.assign-2.sentence-1)
[3](#void.assign-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9790)
*Remarks*: This operator is defined as deleted unlessis_copy_assignable_v<E> is true andis_copy_constructible_v<E> is true[.](#void.assign-3.sentence-1)
[🔗](#lib:operator=,expected%3cvoid%3e_)
`constexpr expected& operator=(expected&& rhs) noexcept(see below);
`
[4](#void.assign-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9803)
*Constraints*: is_move_constructible_v<E> is true andis_move_assignable_v<E> is true[.](#void.assign-4.sentence-1)
[5](#void.assign-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9808)
*Effects*:
- [(5.1)](#void.assign-5.1)
If this->has_value() && rhs.has_value() is true, no effects[.](#void.assign-5.1.sentence-1)
- [(5.2)](#void.assign-5.2)
Otherwise, if this->has_value() is true, equivalent to:construct_at(addressof(*unex*), std::move(rhs.*unex*));*has_val* = false;
- [(5.3)](#void.assign-5.3)
Otherwise, if rhs.has_value() is true,
destroys *unex* and sets *has_val* to true[.](#void.assign-5.3.sentence-1)
- [(5.4)](#void.assign-5.4)
Otherwise, equivalent to *unex* = std::move(rhs.error())[.](#void.assign-5.4.sentence-1)
[6](#void.assign-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9826)
*Returns*: *this[.](#void.assign-6.sentence-1)
[7](#void.assign-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9830)
*Remarks*: The exception specification is equivalent tois_nothrow_move_constructible_v<E> && is_nothrow_move_assignable_v<E>[.](#void.assign-7.sentence-1)
[🔗](#lib:operator=,expected%3cvoid%3e__)
`template<class G>
constexpr expected& operator=(const unexpected<G>& e);
template<class G>
constexpr expected& operator=(unexpected<G>&& e);
`
[8](#void.assign-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9845)
Let GF be const G& for the first overload andG for the second overload[.](#void.assign-8.sentence-1)
[9](#void.assign-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9849)
*Constraints*: is_constructible_v<E, GF> is true andis_assignable_v<E&, GF> is true[.](#void.assign-9.sentence-1)
[10](#void.assign-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9854)
*Effects*:
- [(10.1)](#void.assign-10.1)
If has_value() is true, equivalent to:construct_at(addressof(*unex*), std::forward<GF>(e.error()));*has_val* = false;
- [(10.2)](#void.assign-10.2)
Otherwise, equivalent to:*unex* = std::forward<GF>(e.error());
[11](#void.assign-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9868)
*Returns*: *this[.](#void.assign-11.sentence-1)
[🔗](#lib:emplace,expected%3cvoid%3e)
`constexpr void emplace() noexcept;
`
[12](#void.assign-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9879)
*Effects*: If has_value() is false,
destroys *unex* and sets *has_val* to true[.](#void.assign-12.sentence-1)
#### [22.8.7.5](#void.swap) Swap [[expected.void.swap]](expected.void.swap)
[🔗](#lib:swap,expected%3cvoid%3e)
`constexpr void swap(expected& rhs) noexcept(see below);
`
[1](#void.swap-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9893)
*Constraints*: is_swappable_v<E> is true andis_move_constructible_v<E> is true[.](#void.swap-1.sentence-1)
[2](#void.swap-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9898)
*Effects*: See Table [73](#tab:expected.void.swap "Table 73: swap(expected&amp;) effects")[.](#void.swap-2.sentence-1)
Table [73](#tab:expected.void.swap) — swap(expected&) effects [[tab:expected.void.swap]](./tab:expected.void.swap)
| [🔗](#tab:expected.void.swap-row-1) | **this->has_value()** | **!this->has_value()** |
| --- | --- | --- |
| [🔗](#tab:expected.void.swap-row-2)<br>**rhs.has_value()** | no effects | calls rhs.swap(*this) |
| [🔗](#tab:expected.void.swap-row-3)<br>**!rhs.has_value()** | *see below* | equivalent to: using std::swap; swap(*unex*, rhs.*unex*); |
For the case where rhs.has_value() is false andthis->has_value() is true, equivalent to:construct_at(addressof(*unex*), std::move(rhs.*unex*));
destroy_at(addressof(rhs.*unex*));*has_val* = false;
rhs.*has_val* = true;
[3](#void.swap-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9923)
*Throws*: Any exception thrown by the expressions in the *Effects*[.](#void.swap-3.sentence-1)
[4](#void.swap-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9927)
*Remarks*: The exception specification is equivalent tois_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>[.](#void.swap-4.sentence-1)
[🔗](#lib:swap,expected%3cvoid%3e_)
`friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
`
[5](#void.swap-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9939)
*Effects*: Equivalent to x.swap(y)[.](#void.swap-5.sentence-1)
#### [22.8.7.6](#void.obs) Observers [[expected.void.obs]](expected.void.obs)
[🔗](#lib:operator_bool,expected%3cvoid%3e)
`constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
`
[1](#void.obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9954)
*Returns*: *has_val*[.](#void.obs-1.sentence-1)
[🔗](#lib:operator*,expected%3cvoid%3e)
`constexpr void operator*() const noexcept;
`
[2](#void.obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9965)
*Hardened preconditions*: has_value() is true[.](#void.obs-2.sentence-1)
[🔗](#lib:value,expected%3cvoid%3e)
`constexpr void value() const &;
`
[3](#void.obs-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9976)
*Mandates*: is_copy_constructible_v<E> is true[.](#void.obs-3.sentence-1)
[4](#void.obs-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9980)
*Throws*: bad_expected_access(error()) if has_value() is false[.](#void.obs-4.sentence-1)
[🔗](#lib:value,expected%3cvoid%3e_)
`constexpr void value() &&;
`
[5](#void.obs-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9991)
*Mandates*: is_copy_constructible_v<E> is true andis_move_constructible_v<E> is true[.](#void.obs-5.sentence-1)
[6](#void.obs-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9996)
*Throws*: bad_expected_access(std::move(error())) if has_value() is false[.](#void.obs-6.sentence-1)
[🔗](#lib:error,expected%3cvoid%3e)
`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`
[7](#void.obs-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10009)
*Hardened preconditions*: has_value() is false[.](#void.obs-7.sentence-1)
[8](#void.obs-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10013)
*Returns*: *unex*[.](#void.obs-8.sentence-1)
[🔗](#lib:error,expected%3cvoid%3e_)
`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`
[9](#void.obs-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10025)
*Hardened preconditions*: has_value() is false[.](#void.obs-9.sentence-1)
[10](#void.obs-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10029)
*Returns*: std::move(*unex*)[.](#void.obs-10.sentence-1)
[🔗](#lib:error_or,expected%3cvoid%3e)
`template<class G = E> constexpr E error_or(G&& e) const &;
`
[11](#void.obs-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10040)
*Mandates*: is_copy_constructible_v<E> is true andis_convertible_v<G, E> is true[.](#void.obs-11.sentence-1)
[12](#void.obs-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10045)
*Returns*: std::forward<G>(e) if has_value() is true,error() otherwise[.](#void.obs-12.sentence-1)
[🔗](#lib:error_or,expected%3cvoid%3e_)
`template<class G = E> constexpr E error_or(G&& e) &&;
`
[13](#void.obs-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10057)
*Mandates*: is_move_constructible_v<E> is true andis_convertible_v<G, E> is true[.](#void.obs-13.sentence-1)
[14](#void.obs-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10062)
*Returns*: std::forward<G>(e) if has_value() is true,std::move(error()) otherwise[.](#void.obs-14.sentence-1)
#### [22.8.7.7](#void.monadic) Monadic operations [[expected.void.monadic]](expected.void.monadic)
[🔗](#lib:and_then,expected%3cvoid%3e)
`template<class F> constexpr auto and_then(F&& f) &;
template<class F> constexpr auto and_then(F&& f) const &;
`
[1](#void.monadic-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10077)
Let U be remove_cvref_t<invoke_result_t<F>>[.](#void.monadic-1.sentence-1)
[2](#void.monadic-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10080)
*Constraints*: is_constructible_v<E, decltype(error())>> is true[.](#void.monadic-2.sentence-1)
[3](#void.monadic-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10084)
*Mandates*: U is a specialization of expected andis_same_v<U::error_type, E> is true[.](#void.monadic-3.sentence-1)
[4](#void.monadic-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10089)
*Effects*: Equivalent to:if (has_value())return invoke(std::forward<F>(f));elsereturn U(unexpect, error());
[🔗](#lib:and_then,expected%3cvoid%3e_)
`template<class F> constexpr auto and_then(F&& f) &&;
template<class F> constexpr auto and_then(F&& f) const &&;
`
[5](#void.monadic-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10107)
Let U be remove_cvref_t<invoke_result_t<F>>[.](#void.monadic-5.sentence-1)
[6](#void.monadic-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10110)
*Constraints*: is_constructible_v<E, decltype(std::move(error()))> is true[.](#void.monadic-6.sentence-1)
[7](#void.monadic-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10114)
*Mandates*: U is a specialization of expected andis_same_v<U::error_type, E> is true[.](#void.monadic-7.sentence-1)
[8](#void.monadic-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10119)
*Effects*: Equivalent to:if (has_value())return invoke(std::forward<F>(f));elsereturn U(unexpect, std::move(error()));
[🔗](#lib:or_else,expected%3cvoid%3e)
`template<class F> constexpr auto or_else(F&& f) &;
template<class F> constexpr auto or_else(F&& f) const &;
`
[9](#void.monadic-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10137)
Let G be remove_cvref_t<invoke_result_t<F, decltype(error())>>[.](#void.monadic-9.sentence-1)
[10](#void.monadic-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10140)
*Mandates*: G is a specialization of expected andis_same_v<G::value_type, T> is true[.](#void.monadic-10.sentence-1)
[11](#void.monadic-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10145)
*Effects*: Equivalent to:if (has_value())return G();elsereturn invoke(std::forward<F>(f), error());
[🔗](#lib:or_else,expected%3cvoid%3e_)
`template<class F> constexpr auto or_else(F&& f) &&;
template<class F> constexpr auto or_else(F&& f) const &&;
`
[12](#void.monadic-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10163)
Let G beremove_cvref_t<invoke_result_t<F, decltype(std::move(error()))>>[.](#void.monadic-12.sentence-1)
[13](#void.monadic-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10167)
*Mandates*: G is a specialization of expected andis_same_v<G::value_type, T> is true[.](#void.monadic-13.sentence-1)
[14](#void.monadic-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10172)
*Effects*: Equivalent to:if (has_value())return G();elsereturn invoke(std::forward<F>(f), std::move(error()));
[🔗](#lib:transform,expected%3cvoid%3e)
`template<class F> constexpr auto transform(F&& f) &;
template<class F> constexpr auto transform(F&& f) const &;
`
[15](#void.monadic-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10190)
Let U be remove_cv_t<invoke_result_t<F>>[.](#void.monadic-15.sentence-1)
[16](#void.monadic-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10193)
*Constraints*: is_constructible_v<E, decltype(error())> is true[.](#void.monadic-16.sentence-1)
[17](#void.monadic-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10197)
*Mandates*: U is a valid value type for expected[.](#void.monadic-17.sentence-1)
If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f))); is well-formed[.](#void.monadic-17.sentence-2)
[18](#void.monadic-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10206)
*Effects*:
- [(18.1)](#void.monadic-18.1)
If has_value() is false, returnsexpected<U, E>(unexpect, error())[.](#void.monadic-18.1.sentence-1)
- [(18.2)](#void.monadic-18.2)
Otherwise, if is_void_v<U> is false, returns anexpected<U, E> object whose *has_val* member is true and*val* member is direct-non-list-initialized withinvoke(std::forward<F>(f))[.](#void.monadic-18.2.sentence-1)
- [(18.3)](#void.monadic-18.3)
Otherwise, evaluates invoke(std::forward<F>(f)) and then returnsexpected<U, E>()[.](#void.monadic-18.3.sentence-1)
[🔗](#lib:transform,expected%3cvoid%3e_)
`template<class F> constexpr auto transform(F&& f) &&;
template<class F> constexpr auto transform(F&& f) const &&;
`
[19](#void.monadic-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10230)
Let U be remove_cv_t<invoke_result_t<F>>[.](#void.monadic-19.sentence-1)
[20](#void.monadic-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10233)
*Constraints*: is_constructible_v<E, decltype(std::move(error()))> is true[.](#void.monadic-20.sentence-1)
[21](#void.monadic-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10237)
*Mandates*: U is a valid value type for expected[.](#void.monadic-21.sentence-1)
If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f))); is well-formed[.](#void.monadic-21.sentence-2)
[22](#void.monadic-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10246)
*Effects*:
- [(22.1)](#void.monadic-22.1)
If has_value() is false, returnsexpected<U, E>(unexpect, std::move(error()))[.](#void.monadic-22.1.sentence-1)
- [(22.2)](#void.monadic-22.2)
Otherwise, if is_void_v<U> is false, returns anexpected<U, E> object whose *has_val* member is true and*val* member is direct-non-list-initialized withinvoke(std::forward<F>(f))[.](#void.monadic-22.2.sentence-1)
- [(22.3)](#void.monadic-22.3)
Otherwise, evaluates invoke(std::forward<F>(f)) and then returnsexpected<U, E>()[.](#void.monadic-22.3.sentence-1)
[🔗](#lib:transform_error,expected%3cvoid%3e)
`template<class F> constexpr auto transform_error(F&& f) &;
template<class F> constexpr auto transform_error(F&& f) const &;
`
[23](#void.monadic-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10270)
Let G be remove_cv_t<invoke_result_t<F, decltype(error())>>[.](#void.monadic-23.sentence-1)
[24](#void.monadic-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10273)
*Mandates*: G is a valid template argument
for unexpected ([[expected.un.general]](#un.general "22.8.3.1General")) and the declarationG g(invoke(std::forward<F>(f), error())); is well-formed[.](#void.monadic-24.sentence-1)
[25](#void.monadic-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10282)
*Returns*: If has_value() is true, expected<T, G>(); otherwise, anexpected<T, G> object whose *has_val* member is false and *unex* member is direct-non-list-initialized withinvoke(std::forward<F>(f), error())[.](#void.monadic-25.sentence-1)
[🔗](#lib:transform_error,expected%3cvoid%3e_)
`template<class F> constexpr auto transform_error(F&& f) &&;
template<class F> constexpr auto transform_error(F&& f) const &&;
`
[26](#void.monadic-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10297)
Let G beremove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>[.](#void.monadic-26.sentence-1)
[27](#void.monadic-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10301)
*Mandates*: G is a valid template argument
for unexpected ([[expected.un.general]](#un.general "22.8.3.1General")) and the declarationG g(invoke(std::forward<F>(f), std::move(error()))); is well-formed[.](#void.monadic-27.sentence-1)
[28](#void.monadic-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10310)
*Returns*: If has_value() is true, expected<T, G>(); otherwise, anexpected<T, G> object whose *has_val* member is false and *unex* member is direct-non-list-initialized withinvoke(std::forward<F>(f), std::move(error()))[.](#void.monadic-28.sentence-1)
#### [22.8.7.8](#void.eq) Equality operators [[expected.void.eq]](expected.void.eq)
[🔗](#lib:operator==,expected%3cvoid%3e)
`template<class T2, class E2> requires is_void_v<T2>
friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
`
[1](#void.eq-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10327)
*Constraints*: The expression x.error() == y.error() is well-formed and
its result is convertible to bool[.](#void.eq-1.sentence-1)
[2](#void.eq-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10332)
*Returns*: If x.has_value() does not equal y.has_value(), false;
otherwise x.has_value() || static_cast<bool>(x.error() == y.error())[.](#void.eq-2.sentence-1)
[🔗](#lib:operator==,expected%3cvoid%3e_)
`template<class E2>
friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
`
[3](#void.eq-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10345)
*Constraints*: The expression x.error() == e.error() is well-formed and
its result is convertible to bool[.](#void.eq-3.sentence-1)
[4](#void.eq-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10350)
*Returns*: !x.has_value() && static_cast<bool>(x.error() == e.error())[.](#void.eq-4.sentence-1)