Files
2025-10-25 03:02:53 +03:00

932 lines
35 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

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

[expected.void]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#void)
### 22.8.7 Partial specialization of expected for void types [expected.void]
#### [22.8.7.1](#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]](#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]](#dtor "22.8.7.3Destructor"), destructorconstexpr ~expected(); // [[expected.void.assign]](#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]](#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]](#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]](#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]](#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](#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[.](#general-1.sentence-1)
Member *has_val* indicates whether the expected<T, E> object
represents a value of type T[.](#general-1.sentence-2)
[2](#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[.](#general-2.sentence-1)
[3](#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"))[.](#general-3.sentence-1)
#### [22.8.7.2](#cons) Constructors [[expected.void.cons]](expected.void.cons)
[🔗](#lib:expected%3cvoid%3e,constructor)
`constexpr expected() noexcept;
`
[1](#cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9539)
*Postconditions*: has_value() is true[.](#cons-1.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor_)
`constexpr expected(const expected& rhs);
`
[2](#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()[.](#cons-2.sentence-1)
[3](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9555)
*Postconditions*: rhs.has_value() == this->has_value()[.](#cons-3.sentence-1)
[4](#cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9559)
*Throws*: Any exception thrown by the initialization of *unex*[.](#cons-4.sentence-1)
[5](#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[.](#cons-5.sentence-1)
[6](#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[.](#cons-6.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor__)
`constexpr expected(expected&& rhs) noexcept(is_nothrow_move_constructible_v<E>);
`
[7](#cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9579)
*Constraints*: is_move_constructible_v<E> is true[.](#cons-7.sentence-1)
[8](#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())[.](#cons-8.sentence-1)
[9](#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[.](#cons-9.sentence-1)
[10](#cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9593)
*Throws*: Any exception thrown by the initialization of *unex*[.](#cons-10.sentence-1)
[11](#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[.](#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](#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[.](#cons-12.sentence-1)
[13](#cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9616)
*Constraints*:
- [(13.1)](#cons-13.1)
is_void_v<U> is true; and
- [(13.2)](#cons-13.2)
is_constructible_v<E, GF> is true; and
- [(13.3)](#cons-13.3)
is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
- [(13.4)](#cons-13.4)
is_constructible_v<unexpected<E>, expected<U, G>> is false; and
- [(13.5)](#cons-13.5)
is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
- [(13.6)](#cons-13.6)
is_constructible_v<unexpected<E>, const expected<U, G>> is false[.](#cons-13.sentence-1)
[14](#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())[.](#cons-14.sentence-1)
[15](#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[.](#cons-15.sentence-1)
[16](#cons-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9648)
*Throws*: Any exception thrown by the initialization of *unex*[.](#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](#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[.](#cons-17.sentence-1)
[18](#cons-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9666)
*Constraints*: is_constructible_v<E, GF> is true[.](#cons-18.sentence-1)
[19](#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())[.](#cons-19.sentence-1)
[20](#cons-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9675)
*Postconditions*: has_value() is false[.](#cons-20.sentence-1)
[21](#cons-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9679)
*Throws*: Any exception thrown by the initialization of *unex*[.](#cons-21.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor_____)
`constexpr explicit expected(in_place_t) noexcept;
`
[22](#cons-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9690)
*Postconditions*: has_value() is true[.](#cons-22.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor______)
`template<class... Args>
constexpr explicit expected(unexpect_t, Args&&... args);
`
[23](#cons-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9702)
*Constraints*: is_constructible_v<E, Args...> is true[.](#cons-23.sentence-1)
[24](#cons-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9706)
*Effects*: Direct-non-list-initializes *unex* with std::forward<Args>(args)...[.](#cons-24.sentence-1)
[25](#cons-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9711)
*Postconditions*: has_value() is false[.](#cons-25.sentence-1)
[26](#cons-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9715)
*Throws*: Any exception thrown by the initialization of *unex*[.](#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](#cons-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9727)
*Constraints*: is_constructible_v<E, initializer_list<U>&, Args...> is true[.](#cons-27.sentence-1)
[28](#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)...[.](#cons-28.sentence-1)
[29](#cons-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9736)
*Postconditions*: has_value() is false[.](#cons-29.sentence-1)
[30](#cons-30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9740)
*Throws*: Any exception thrown by the initialization of *unex*[.](#cons-30.sentence-1)
#### [22.8.7.3](#dtor) Destructor [[expected.void.dtor]](expected.void.dtor)
[🔗](#lib:expected%3cvoid%3e,destructor)
`constexpr ~expected();
`
[1](#dtor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9753)
*Effects*: If has_value() is false, destroys *unex*[.](#dtor-1.sentence-1)
[2](#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[.](#dtor-2.sentence-1)
#### [22.8.7.4](#assign) Assignment [[expected.void.assign]](expected.void.assign)
[🔗](#lib:operator=,expected%3cvoid%3e)
`constexpr expected& operator=(const expected& rhs);
`
[1](#assign-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9771)
*Effects*:
- [(1.1)](#assign-1.1)
If this->has_value() && rhs.has_value() is true, no effects[.](#assign-1.1.sentence-1)
- [(1.2)](#assign-1.2)
Otherwise, if this->has_value() is true,
equivalent to: construct_at(addressof(*unex*), rhs.*unex*); *has_val* = false;
- [(1.3)](#assign-1.3)
Otherwise, if rhs.has_value() is true,
destroys *unex* and sets *has_val* to true[.](#assign-1.3.sentence-1)
- [(1.4)](#assign-1.4)
Otherwise, equivalent to *unex* = rhs.error()[.](#assign-1.4.sentence-1)
[2](#assign-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9786)
*Returns*: *this[.](#assign-2.sentence-1)
[3](#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[.](#assign-3.sentence-1)
[🔗](#lib:operator=,expected%3cvoid%3e_)
`constexpr expected& operator=(expected&& rhs) noexcept(see below);
`
[4](#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[.](#assign-4.sentence-1)
[5](#assign-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9808)
*Effects*:
- [(5.1)](#assign-5.1)
If this->has_value() && rhs.has_value() is true, no effects[.](#assign-5.1.sentence-1)
- [(5.2)](#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)](#assign-5.3)
Otherwise, if rhs.has_value() is true,
destroys *unex* and sets *has_val* to true[.](#assign-5.3.sentence-1)
- [(5.4)](#assign-5.4)
Otherwise, equivalent to *unex* = std::move(rhs.error())[.](#assign-5.4.sentence-1)
[6](#assign-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9826)
*Returns*: *this[.](#assign-6.sentence-1)
[7](#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>[.](#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](#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[.](#assign-8.sentence-1)
[9](#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[.](#assign-9.sentence-1)
[10](#assign-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9854)
*Effects*:
- [(10.1)](#assign-10.1)
If has_value() is true, equivalent to:construct_at(addressof(*unex*), std::forward<GF>(e.error()));*has_val* = false;
- [(10.2)](#assign-10.2)
Otherwise, equivalent to:*unex* = std::forward<GF>(e.error());
[11](#assign-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9868)
*Returns*: *this[.](#assign-11.sentence-1)
[🔗](#lib:emplace,expected%3cvoid%3e)
`constexpr void emplace() noexcept;
`
[12](#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[.](#assign-12.sentence-1)
#### [22.8.7.5](#swap) Swap [[expected.void.swap]](expected.void.swap)
[🔗](#lib:swap,expected%3cvoid%3e)
`constexpr void swap(expected& rhs) noexcept(see below);
`
[1](#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[.](#swap-1.sentence-1)
[2](#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")[.](#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](#swap-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9923)
*Throws*: Any exception thrown by the expressions in the *Effects*[.](#swap-3.sentence-1)
[4](#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>[.](#swap-4.sentence-1)
[🔗](#lib:swap,expected%3cvoid%3e_)
`friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
`
[5](#swap-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9939)
*Effects*: Equivalent to x.swap(y)[.](#swap-5.sentence-1)
#### [22.8.7.6](#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](#obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9954)
*Returns*: *has_val*[.](#obs-1.sentence-1)
[🔗](#lib:operator*,expected%3cvoid%3e)
`constexpr void operator*() const noexcept;
`
[2](#obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9965)
*Hardened preconditions*: has_value() is true[.](#obs-2.sentence-1)
[🔗](#lib:value,expected%3cvoid%3e)
`constexpr void value() const &;
`
[3](#obs-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9976)
*Mandates*: is_copy_constructible_v<E> is true[.](#obs-3.sentence-1)
[4](#obs-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9980)
*Throws*: bad_expected_access(error()) if has_value() is false[.](#obs-4.sentence-1)
[🔗](#lib:value,expected%3cvoid%3e_)
`constexpr void value() &&;
`
[5](#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[.](#obs-5.sentence-1)
[6](#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[.](#obs-6.sentence-1)
[🔗](#lib:error,expected%3cvoid%3e)
`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`
[7](#obs-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10009)
*Hardened preconditions*: has_value() is false[.](#obs-7.sentence-1)
[8](#obs-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10013)
*Returns*: *unex*[.](#obs-8.sentence-1)
[🔗](#lib:error,expected%3cvoid%3e_)
`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`
[9](#obs-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10025)
*Hardened preconditions*: has_value() is false[.](#obs-9.sentence-1)
[10](#obs-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10029)
*Returns*: std::move(*unex*)[.](#obs-10.sentence-1)
[🔗](#lib:error_or,expected%3cvoid%3e)
`template<class G = E> constexpr E error_or(G&& e) const &;
`
[11](#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[.](#obs-11.sentence-1)
[12](#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[.](#obs-12.sentence-1)
[🔗](#lib:error_or,expected%3cvoid%3e_)
`template<class G = E> constexpr E error_or(G&& e) &&;
`
[13](#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[.](#obs-13.sentence-1)
[14](#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[.](#obs-14.sentence-1)
#### [22.8.7.7](#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](#monadic-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10077)
Let U be remove_cvref_t<invoke_result_t<F>>[.](#monadic-1.sentence-1)
[2](#monadic-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10080)
*Constraints*: is_constructible_v<E, decltype(error())>> is true[.](#monadic-2.sentence-1)
[3](#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[.](#monadic-3.sentence-1)
[4](#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](#monadic-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10107)
Let U be remove_cvref_t<invoke_result_t<F>>[.](#monadic-5.sentence-1)
[6](#monadic-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10110)
*Constraints*: is_constructible_v<E, decltype(std::move(error()))> is true[.](#monadic-6.sentence-1)
[7](#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[.](#monadic-7.sentence-1)
[8](#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](#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())>>[.](#monadic-9.sentence-1)
[10](#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[.](#monadic-10.sentence-1)
[11](#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](#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()))>>[.](#monadic-12.sentence-1)
[13](#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[.](#monadic-13.sentence-1)
[14](#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](#monadic-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10190)
Let U be remove_cv_t<invoke_result_t<F>>[.](#monadic-15.sentence-1)
[16](#monadic-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10193)
*Constraints*: is_constructible_v<E, decltype(error())> is true[.](#monadic-16.sentence-1)
[17](#monadic-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10197)
*Mandates*: U is a valid value type for expected[.](#monadic-17.sentence-1)
If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f))); is well-formed[.](#monadic-17.sentence-2)
[18](#monadic-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10206)
*Effects*:
- [(18.1)](#monadic-18.1)
If has_value() is false, returnsexpected<U, E>(unexpect, error())[.](#monadic-18.1.sentence-1)
- [(18.2)](#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))[.](#monadic-18.2.sentence-1)
- [(18.3)](#monadic-18.3)
Otherwise, evaluates invoke(std::forward<F>(f)) and then returnsexpected<U, E>()[.](#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](#monadic-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10230)
Let U be remove_cv_t<invoke_result_t<F>>[.](#monadic-19.sentence-1)
[20](#monadic-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10233)
*Constraints*: is_constructible_v<E, decltype(std::move(error()))> is true[.](#monadic-20.sentence-1)
[21](#monadic-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10237)
*Mandates*: U is a valid value type for expected[.](#monadic-21.sentence-1)
If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f))); is well-formed[.](#monadic-21.sentence-2)
[22](#monadic-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10246)
*Effects*:
- [(22.1)](#monadic-22.1)
If has_value() is false, returnsexpected<U, E>(unexpect, std::move(error()))[.](#monadic-22.1.sentence-1)
- [(22.2)](#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))[.](#monadic-22.2.sentence-1)
- [(22.3)](#monadic-22.3)
Otherwise, evaluates invoke(std::forward<F>(f)) and then returnsexpected<U, E>()[.](#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](#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())>>[.](#monadic-23.sentence-1)
[24](#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]](expected.un.general "22.8.3.1General")) and the declarationG g(invoke(std::forward<F>(f), error())); is well-formed[.](#monadic-24.sentence-1)
[25](#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())[.](#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](#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()))>>[.](#monadic-26.sentence-1)
[27](#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]](expected.un.general "22.8.3.1General")) and the declarationG g(invoke(std::forward<F>(f), std::move(error()))); is well-formed[.](#monadic-27.sentence-1)
[28](#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()))[.](#monadic-28.sentence-1)
#### [22.8.7.8](#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](#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[.](#eq-1.sentence-1)
[2](#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())[.](#eq-2.sentence-1)
[🔗](#lib:operator==,expected%3cvoid%3e_)
`template<class E2>
friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
`
[3](#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[.](#eq-3.sentence-1)
[4](#eq-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10350)
*Returns*: !x.has_value() && static_cast<bool>(x.error() == e.error())[.](#eq-4.sentence-1)