This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

67
cppdraft/expected/bad.md Normal file
View File

@@ -0,0 +1,67 @@
[expected.bad]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#bad)
### 22.8.4 Class template bad_expected_access [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](#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[.](#1.sentence-1)
[🔗](#lib:bad_expected_access,constructor)
`constexpr explicit bad_expected_access(E e);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7930)
*Effects*: Initializes *unex* with std::move(e)[.](#2.sentence-1)
[🔗](#lib:error,bad_expected_access)
`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7942)
*Returns*: *unex*[.](#3.sentence-1)
[🔗](#lib:error,bad_expected_access_)
`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7954)
*Returns*: std::move(*unex*)[.](#4.sentence-1)
[🔗](#lib:what,bad_expected_access)
`constexpr const char* what() const noexcept override;
`
[5](#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"))[.](#5.sentence-1)

View File

@@ -0,0 +1,22 @@
[expected.bad.void]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#bad.void)
### 22.8.5 Class template specialization bad_expected_access<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](#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"))[.](#1.sentence-1)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
[expected.general]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#general)
### 22.8.1 General [expected.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7656)
Subclause [[expected]](expected "22.8Expected objects") describes the class template expected that represents expected objects[.](#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[.](#1.sentence-2)

View File

@@ -0,0 +1,294 @@
[expected.object.assign]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#object.assign)
### 22.8.6 Class template expected [[expected.expected]](expected.expected#expected.object.assign)
#### 22.8.6.4 Assignment [expected.object.assign]
[1](#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](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8553)
*Effects*:
- [(2.1)](#2.1)
If this->has_value() && rhs.has_value() is true,
equivalent to *val* = *rhs[.](#2.1.sentence-1)
- [(2.2)](#2.2)
Otherwise, if this->has_value() is true, equivalent to:*reinit-expected*(*unex*, *val*, rhs.error())
- [(2.3)](#2.3)
Otherwise, if rhs.has_value() is true, equivalent to:*reinit-expected*(*val*, *unex*, *rhs)
- [(2.4)](#2.4)
Otherwise, equivalent to *unex* = rhs.error()[.](#2.4.sentence-1)
Then, if no exception was thrown,
equivalent to: *has_val* = rhs.has_value(); return *this;
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8575)
*Returns*: *this[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8579)
*Remarks*: This operator is defined as deleted unless:
- [(4.1)](#4.1)
is_copy_assignable_v<T> is true and
- [(4.2)](#4.2)
is_copy_constructible_v<T> is true and
- [(4.3)](#4.3)
is_copy_assignable_v<E> is true and
- [(4.4)](#4.4)
is_copy_constructible_v<E> is true and
- [(4.5)](#4.5)
is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true[.](#4.sentence-1)
[🔗](#lib:operator=,expected_)
`constexpr expected& operator=(expected&& rhs) noexcept(see below);
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8603)
*Constraints*:
- [(5.1)](#5.1)
is_move_constructible_v<T> is true and
- [(5.2)](#5.2)
is_move_assignable_v<T> is true and
- [(5.3)](#5.3)
is_move_constructible_v<E> is true and
- [(5.4)](#5.4)
is_move_assignable_v<E> is true and
- [(5.5)](#5.5)
is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8619)
*Effects*:
- [(6.1)](#6.1)
If this->has_value() && rhs.has_value() is true,
equivalent to *val* = std::move(*rhs)[.](#6.1.sentence-1)
- [(6.2)](#6.2)
Otherwise, if this->has_value() is true, equivalent to:*reinit-expected*(*unex*, *val*, std::move(rhs.error()))
- [(6.3)](#6.3)
Otherwise, if rhs.has_value() is true, equivalent to:*reinit-expected*(*val*, *unex*, std::move(*rhs))
- [(6.4)](#6.4)
Otherwise, equivalent to *unex* = std::move(rhs.error())[.](#6.4.sentence-1)
Then, if no exception was thrown,
equivalent to: has_val = rhs.has_value(); return *this;
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8641)
*Returns*: *this[.](#7.sentence-1)
[8](#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](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8661)
*Constraints*:
- [(9.1)](#9.1)
is_same_v<expected, remove_cvref_t<U>> is false; and
- [(9.2)](#9.2)
remove_cvref_t<U> is not a specialization of unexpected; and
- [(9.3)](#9.3)
is_constructible_v<T, U> is true; and
- [(9.4)](#9.4)
is_assignable_v<T&, U> is true; and
- [(9.5)](#9.5)
is_nothrow_constructible_v<T, U> || is_nothrow_move_constructible_v<T> ||
is_nothrow_move_constructible_v<E> is true[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8678)
*Effects*:
- [(10.1)](#10.1)
If has_value() is true,
equivalent to: *val* = std::forward<U>(v);
- [(10.2)](#10.2)
Otherwise, equivalent to:*reinit-expected*(*val*, *unex*, std::forward<U>(v));*has_val* = true;
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8692)
*Returns*: *this[.](#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](#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[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8710)
*Constraints*:
- [(13.1)](#13.1)
is_constructible_v<E, GF> is true; and
- [(13.2)](#13.2)
is_assignable_v<E&, GF> is true; and
- [(13.3)](#13.3)
is_nothrow_constructible_v<E, GF> || is_nothrow_move_constructible_v<T> ||
is_nothrow_move_constructible_v<E> is true[.](#13.sentence-1)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8722)
*Effects*:
- [(14.1)](#14.1)
If has_value() is true, equivalent to:*reinit-expected*(*unex*, *val*, std::forward<GF>(e.error()));*has_val* = false;
- [(14.2)](#14.2)
Otherwise, equivalent to:*unex* = std::forward<GF>(e.error());
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8736)
*Returns*: *this[.](#15.sentence-1)
[🔗](#lib:emplace,expected)
`template<class... Args>
constexpr T& emplace(Args&&... args) noexcept;
`
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8748)
*Constraints*: is_nothrow_constructible_v<T, Args...> is true[.](#16.sentence-1)
[17](#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](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8773)
*Constraints*: is_nothrow_constructible_v<T, initializer_list<U>&, Args...> is true[.](#18.sentence-1)
[19](#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)...);

View File

@@ -0,0 +1,455 @@
[expected.object.cons]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#object.cons)
### 22.8.6 Class template expected [[expected.expected]](expected.expected#expected.object.cons)
#### 22.8.6.2 Constructors [expected.object.cons]
[1](#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[.](#1.sentence-1)
[🔗](#lib:expected,constructor)
`constexpr expected();
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8167)
*Constraints*: is_default_constructible_v<T> is true[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8171)
*Effects*: Value-initializes *val*[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8175)
*Postconditions*: has_value() is true[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8179)
*Throws*: Any exception thrown by the initialization of *val*[.](#5.sentence-1)
[🔗](#lib:expected,constructor_)
`constexpr expected(const expected& rhs);
`
[6](#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[.](#6.sentence-1)
Otherwise, direct-non-list-initializes *unex* with rhs.error()[.](#6.sentence-2)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8196)
*Postconditions*: rhs.has_value() == this->has_value()[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8200)
*Throws*: Any exception thrown by the initialization of *val* or *unex*[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8204)
*Remarks*: This constructor is defined as deleted unless
- [(9.1)](#9.1)
is_copy_constructible_v<T> is true and
- [(9.2)](#9.2)
is_copy_constructible_v<E> is true[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8214)
This constructor is trivial if
- [(10.1)](#10.1)
is_trivially_copy_constructible_v<T> is true and
- [(10.2)](#10.2)
is_trivially_copy_constructible_v<E> is true[.](#10.sentence-1)
[🔗](#lib:expected,constructor__)
`constexpr expected(expected&& rhs) noexcept(see below);
`
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8230)
*Constraints*:
- [(11.1)](#11.1)
is_move_constructible_v<T> is true and
- [(11.2)](#11.2)
is_move_constructible_v<E> is true[.](#11.sentence-1)
[12](#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)[.](#12.sentence-1)
Otherwise,
direct-non-list-initializes *unex* with std::move(rhs.error())[.](#12.sentence-2)
[13](#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[.](#13.sentence-1)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8251)
*Throws*: Any exception thrown by the initialization of *val* or *unex*[.](#14.sentence-1)
[15](#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>[.](#15.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8261)
This constructor is trivial if
- [(16.1)](#16.1)
is_trivially_move_constructible_v<T> is true and
- [(16.2)](#16.2)
is_trivially_move_constructible_v<E> is true[.](#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](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8280)
Let:
- [(17.1)](#17.1)
UF be const U& for the first overload andU for the second overload[.](#17.1.sentence-1)
- [(17.2)](#17.2)
GF be const G& for the first overload andG for the second overload[.](#17.2.sentence-1)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8291)
*Constraints*:
- [(18.1)](#18.1)
is_constructible_v<T, UF> is true; and
- [(18.2)](#18.2)
is_constructible_v<E, GF> is true; and
- [(18.3)](#18.3)
if T is not cv bool,*converts-from-any-cvref*<T, expected<U, G>> is false; and
- [(18.4)](#18.4)
is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
- [(18.5)](#18.5)
is_constructible_v<unexpected<E>, expected<U, G>> is false; and
- [(18.6)](#18.6)
is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
- [(18.7)](#18.7)
is_constructible_v<unexpected<E>, const expected<U, G>> is false[.](#18.sentence-1)
[19](#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)[.](#19.sentence-1)
Otherwise,
direct-non-list-initializes *unex* with std::forward<GF>(rhs.error())[.](#19.sentence-2)
[20](#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[.](#20.sentence-1)
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8323)
*Throws*: Any exception thrown by the initialization of *val* or *unex*[.](#21.sentence-1)
[22](#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>[.](#22.sentence-1)
[🔗](#lib:expected,constructor____)
`template<class U = remove_cv_t<T>>
constexpr explicit(!is_convertible_v<U, T>) expected(U&& v);
`
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8340)
*Constraints*:
- [(23.1)](#23.1)
is_same_v<remove_cvref_t<U>, in_place_t> is false; and
- [(23.2)](#23.2)
is_same_v<remove_cvref_t<U>, expected> is false; and
- [(23.3)](#23.3)
is_same_v<remove_cvref_t<U>, unexpect_t> is false; and
- [(23.4)](#23.4)
remove_cvref_t<U> is not a specialization of unexpected; and
- [(23.5)](#23.5)
is_constructible_v<T, U> is true; and
- [(23.6)](#23.6)
if T is cv bool,remove_cvref_t<U> is not a specialization of expected[.](#23.sentence-1)
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8358)
*Effects*: Direct-non-list-initializes *val* with std::forward<U>(v)[.](#24.sentence-1)
[25](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8362)
*Postconditions*: has_value() is true[.](#25.sentence-1)
[26](#26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8366)
*Throws*: Any exception thrown by the initialization of *val*[.](#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](#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[.](#27.sentence-1)
[28](#28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8384)
*Constraints*: is_constructible_v<E, GF> is true[.](#28.sentence-1)
[29](#29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8388)
*Effects*: Direct-non-list-initializes *unex* with std::forward<GF>(e.error())[.](#29.sentence-1)
[30](#30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8392)
*Postconditions*: has_value() is false[.](#30.sentence-1)
[31](#31)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8396)
*Throws*: Any exception thrown by the initialization of *unex*[.](#31.sentence-1)
[🔗](#lib:expected,constructor______)
`template<class... Args>
constexpr explicit expected(in_place_t, Args&&... args);
`
[32](#32)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8408)
*Constraints*: is_constructible_v<T, Args...> is true[.](#32.sentence-1)
[33](#33)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8412)
*Effects*: Direct-non-list-initializes *val* with std::forward<Args>(args)...[.](#33.sentence-1)
[34](#34)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8416)
*Postconditions*: has_value() is true[.](#34.sentence-1)
[35](#35)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8420)
*Throws*: Any exception thrown by the initialization of *val*[.](#35.sentence-1)
[🔗](#lib:expected,constructor_______)
`template<class U, class... Args>
constexpr explicit expected(in_place_t, initializer_list<U> il, Args&&... args);
`
[36](#36)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8432)
*Constraints*: is_constructible_v<T, initializer_list<U>&, Args...> is true[.](#36.sentence-1)
[37](#37)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8436)
*Effects*: Direct-non-list-initializes *val* withil, std::forward<Args>(args)...[.](#37.sentence-1)
[38](#38)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8441)
*Postconditions*: has_value() is true[.](#38.sentence-1)
[39](#39)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8445)
*Throws*: Any exception thrown by the initialization of *val*[.](#39.sentence-1)
[🔗](#lib:expected,constructor________)
`template<class... Args>
constexpr explicit expected(unexpect_t, Args&&... args);
`
[40](#40)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8457)
*Constraints*: is_constructible_v<E, Args...> is true[.](#40.sentence-1)
[41](#41)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8461)
*Effects*: Direct-non-list-initializes *unex* withstd::forward<Args>(args)...[.](#41.sentence-1)
[42](#42)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8466)
*Postconditions*: has_value() is false[.](#42.sentence-1)
[43](#43)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8470)
*Throws*: Any exception thrown by the initialization of *unex*[.](#43.sentence-1)
[🔗](#lib:expected,constructor_________)
`template<class U, class... Args>
constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
`
[44](#44)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8482)
*Constraints*: is_constructible_v<E, initializer_list<U>&, Args...> is true[.](#44.sentence-1)
[45](#45)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8486)
*Effects*: Direct-non-list-initializes *unex* withil, std::forward<Args>(args)...[.](#45.sentence-1)
[46](#46)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8491)
*Postconditions*: has_value() is false[.](#46.sentence-1)
[47](#47)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8495)
*Throws*: Any exception thrown by the initialization of *unex*[.](#47.sentence-1)

View File

@@ -0,0 +1,28 @@
[expected.object.dtor]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#object.dtor)
### 22.8.6 Class template expected [[expected.expected]](expected.expected#expected.object.dtor)
#### 22.8.6.3 Destructor [expected.object.dtor]
[🔗](#lib:expected,destructor)
`constexpr ~expected();
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8508)
*Effects*: If has_value() is true, destroys *val*,
otherwise destroys *unex*[.](#1.sentence-1)
[2](#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[.](#2.sentence-1)

View File

@@ -0,0 +1,73 @@
[expected.object.eq]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#object.eq)
### 22.8.6 Class template expected [[expected.expected]](expected.expected#expected.object.eq)
#### 22.8.6.8 Equality operators [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](#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[.](#1.sentence-1)
[2](#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()[.](#2.sentence-1)
[🔗](#lib:operator==,expected_)
`template<class T2> friend constexpr bool operator==(const expected& x, const T2& v);
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9386)
*Constraints*: T2 is not a specialization of expected[.](#3.sentence-1)
The expression *x == v is well-formed and
its result is convertible to bool[.](#3.sentence-2)
[*Note [1](#note-1)*:
T need not be [*Cpp17EqualityComparable*](utility.arg.requirements#:Cpp17EqualityComparable "16.4.4.2Template argument requirements[utility.arg.requirements]")[.](#3.sentence-3)
— *end note*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9395)
*Returns*: x.has_value() && static_cast<bool>(*x == v)[.](#4.sentence-1)
[🔗](#lib:operator==,expected__)
`template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
`
[5](#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[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9411)
*Returns*: !x.has_value() && static_cast<bool>(x.error() == e.error())[.](#6.sentence-1)

View File

@@ -0,0 +1,47 @@
[expected.object.general]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#object.general)
### 22.8.6 Class template expected [[expected.expected]](expected.expected#expected.object.general)
#### 22.8.6.1 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]](expected.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]](expected.object.dtor "22.8.6.3Destructor"), destructorconstexpr ~expected(); // [[expected.object.assign]](expected.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]](expected.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]](expected.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]](expected.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]](expected.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](#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[.](#1.sentence-1)
Member *has_val* indicates whether the expected<T, E> object
contains an object of type T[.](#1.sentence-2)
[2](#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[.](#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[.](#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[.](#2.sentence-3)
[3](#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"))[.](#3.sentence-1)
E shall meet
the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#3.sentence-2)

View File

@@ -0,0 +1,283 @@
[expected.object.monadic]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#object.monadic)
### 22.8.6 Class template expected [[expected.expected]](expected.expected#expected.object.monadic)
#### 22.8.6.7 Monadic operations [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](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9097)
Let U be remove_cvref_t<invoke_result_t<F, decltype((*val*))>>[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9100)
*Constraints*: is_constructible_v<E, decltype(error())> is true[.](#2.sentence-1)
[3](#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[.](#3.sentence-1)
[4](#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](#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*))>>[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9131)
*Constraints*: is_constructible_v<E, decltype(std::move(error()))> is true[.](#6.sentence-1)
[7](#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[.](#7.sentence-1)
[8](#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](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9158)
Let G be remove_cvref_t<invoke_result_t<F, decltype(error())>>[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9161)
*Constraints*: is_constructible_v<T, decltype((*val*))> is true[.](#10.sentence-1)
[11](#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[.](#11.sentence-1)
[12](#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](#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()))>>[.](#13.sentence-1)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9192)
*Constraints*: is_constructible_v<T, decltype(std::move(*val*))> is true[.](#14.sentence-1)
[15](#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[.](#15.sentence-1)
[16](#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](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9219)
Let U beremove_cv_t<invoke_result_t<F, decltype((*val*))>>[.](#17.sentence-1)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9223)
*Constraints*: is_constructible_v<E, decltype(error())> is true[.](#18.sentence-1)
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9227)
*Mandates*: U is a valid value type for expected[.](#19.sentence-1)
If is_void_v<U> is false,
the declarationU u(invoke(std::forward<F>(f), *val*)); is well-formed[.](#19.sentence-2)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9237)
*Effects*:
- [(20.1)](#20.1)
If has_value() is false, returnsexpected<U, E>(unexpect, error())[.](#20.1.sentence-1)
- [(20.2)](#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*)[.](#20.2.sentence-1)
- [(20.3)](#20.3)
Otherwise, evaluates invoke(std::forward<F>(f), *val*) and then
returns expected<U, E>()[.](#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](#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*))>>[.](#21.sentence-1)
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9265)
*Constraints*: is_constructible_v<E, decltype(std::move(error()))> is true[.](#22.sentence-1)
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9269)
*Mandates*: U is a valid value type for expected[.](#23.sentence-1)
If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f), std::move(*val*))); is well-formed[.](#23.sentence-2)
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9278)
*Effects*:
- [(24.1)](#24.1)
If has_value() is false, returnsexpected<U, E>(unexpect, std::move(error()))[.](#24.1.sentence-1)
- [(24.2)](#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*))[.](#24.2.sentence-1)
- [(24.3)](#24.3)
Otherwise, evaluates invoke(std::forward<F>(f), std::move(*val*)) and
then returns expected<U, E>()[.](#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](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9302)
Let G be remove_cv_t<invoke_result_t<F, decltype(error())>>[.](#25.sentence-1)
[26](#26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9305)
*Constraints*: is_constructible_v<T, decltype((*val*))> is true[.](#26.sentence-1)
[27](#27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9309)
*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[.](#27.sentence-1)
[28](#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())[.](#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](#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()))>>[.](#29.sentence-1)
[30](#30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9337)
*Constraints*: is_constructible_v<T, decltype(std::move(*val*))> is true[.](#30.sentence-1)
[31](#31)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9341)
*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[.](#31.sentence-1)
[32](#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()))[.](#32.sentence-1)

View File

@@ -0,0 +1,227 @@
[expected.object.obs]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#object.obs)
### 22.8.6 Class template expected [[expected.expected]](expected.expected#expected.object.obs)
#### 22.8.6.6 Observers [expected.object.obs]
[🔗](#lib:operator-%3e,expected)
`constexpr const T* operator->() const noexcept;
constexpr T* operator->() noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8894)
*Hardened preconditions*: has_value() is true[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8898)
*Returns*: addressof(*val*)[.](#2.sentence-1)
[🔗](#lib:operator*,expected)
`constexpr const T& operator*() const & noexcept;
constexpr T& operator*() & noexcept;
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8910)
*Hardened preconditions*: has_value() is true[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8914)
*Returns*: *val*[.](#4.sentence-1)
[🔗](#lib:operator*,expected_)
`constexpr T&& operator*() && noexcept;
constexpr const T&& operator*() const && noexcept;
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8926)
*Hardened preconditions*: has_value() is true[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8930)
*Returns*: std::move(*val*)[.](#6.sentence-1)
[🔗](#lib:operator_bool,expected)
`constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8943)
*Returns*: *has_val*[.](#7.sentence-1)
[🔗](#lib:value,expected)
`constexpr const T& value() const &;
constexpr T& value() &;
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8955)
*Mandates*: is_copy_constructible_v<E> is true[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8959)
*Returns*: *val*, if has_value() is true[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8963)
*Throws*: bad_expected_access(as_const(error())) if has_value() is false[.](#10.sentence-1)
[🔗](#lib:value,expected_)
`constexpr T&& value() &&;
constexpr const T&& value() const &&;
`
[11](#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[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8980)
*Returns*: std::move(*val*), if has_value() is true[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8984)
*Throws*: bad_expected_access(std::move(error())) if has_value() is false[.](#13.sentence-1)
[🔗](#lib:error,expected)
`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8997)
*Hardened preconditions*: has_value() is false[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9001)
*Returns*: *unex*[.](#15.sentence-1)
[🔗](#lib:error,expected_)
`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9013)
*Hardened preconditions*: has_value() is false[.](#16.sentence-1)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9017)
*Returns*: std::move(*unex*)[.](#17.sentence-1)
[🔗](#lib:value_or,expected)
`template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;
`
[18](#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[.](#18.sentence-1)
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9033)
*Returns*: has_value() ? **this : static_cast<T>(std::forward<U>(v))[.](#19.sentence-1)
[🔗](#lib:value_or,expected_)
`template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;
`
[20](#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[.](#20.sentence-1)
[21](#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))[.](#21.sentence-1)
[🔗](#lib:error_or,expected)
`template<class G = E> constexpr E error_or(G&& e) const &;
`
[22](#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[.](#22.sentence-1)
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9065)
*Returns*: std::forward<G>(e) if has_value() is true,error() otherwise[.](#23.sentence-1)
[🔗](#lib:error_or,expected_)
`template<class G = E> constexpr E error_or(G&& e) &&;
`
[24](#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[.](#24.sentence-1)
[25](#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[.](#25.sentence-1)

View File

@@ -0,0 +1,81 @@
[expected.object.swap]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#object.swap)
### 22.8.6 Class template expected [[expected.expected]](expected.expected#expected.object.swap)
#### 22.8.6.5 Swap [expected.object.swap]
[🔗](#lib:swap,expected)
`constexpr void swap(expected& rhs) noexcept(see below);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8800)
*Constraints*:
- [(1.1)](#1.1)
is_swappable_v<T> is true and
- [(1.2)](#1.2)
is_swappable_v<E> is true and
- [(1.3)](#1.3)
is_move_constructible_v<T> && is_move_constructible_v<E> is true, and
- [(1.4)](#1.4)
is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true[.](#1.sentence-1)
[2](#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")[.](#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](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8861)
*Throws*: Any exception thrown by the expressions in the *Effects*[.](#3.sentence-1)
[4](#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](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8880)
*Effects*: Equivalent to x.swap(y)[.](#5.sentence-1)

11
cppdraft/expected/syn.md Normal file
View File

@@ -0,0 +1,11 @@
[expected.syn]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#syn)
### 22.8.2 Header <expected> synopsis [expected.syn]
[🔗](#header:%3cexpected%3e)
// mostly freestandingnamespace std {// [[expected.unexpected]](expected.unexpected "22.8.3Class template unexpected"), class template unexpectedtemplate<class E> class unexpected; // [[expected.bad]](expected.bad "22.8.4Class template bad_­expected_­access"), class template bad_expected_accesstemplate<class E> class bad_expected_access; // [[expected.bad.void]](expected.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.expected "22.8.6Class template expected"), class template expectedtemplate<class T, class E> class expected; // partially freestanding// [[expected.void]](expected.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}

View File

@@ -0,0 +1,93 @@
[expected.un.cons]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#un.cons)
### 22.8.3 Class template unexpected [[expected.unexpected]](expected.unexpected#expected.un.cons)
#### 22.8.3.2 Constructors [expected.un.cons]
[🔗](#lib:unexpected,constructor)
`template<class Err = E>
constexpr explicit unexpected(Err&& e);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7758)
*Constraints*:
- [(1.1)](#1.1)
is_same_v<remove_cvref_t<Err>, unexpected> is false; and
- [(1.2)](#1.2)
is_same_v<remove_cvref_t<Err>, in_place_t> is false; and
- [(1.3)](#1.3)
is_constructible_v<E, Err> is true[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7769)
*Effects*: Direct-non-list-initializes *unex* with std::forward<Err>(e)[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7773)
*Throws*: Any exception thrown by the initialization of *unex*[.](#3.sentence-1)
[🔗](#lib:unexpected,constructor_)
`template<class... Args>
constexpr explicit unexpected(in_place_t, Args&&... args);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7785)
*Constraints*: is_constructible_v<E, Args...> is true[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7789)
*Effects*: Direct-non-list-initializes*unex* with std::forward<Args>(args)...[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7794)
*Throws*: Any exception thrown by the initialization of *unex*[.](#6.sentence-1)
[🔗](#lib:unexpected,constructor__)
`template<class U, class... Args>
constexpr explicit unexpected(in_place_t, initializer_list<U> il, Args&&... args);
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7806)
*Constraints*: is_constructible_v<E, initializer_list<U>&, Args...> is true[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7810)
*Effects*: Direct-non-list-initializes*unex* with il, std::forward<Args>(args)...[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7815)
*Throws*: Any exception thrown by the initialization of *unex*[.](#9.sentence-1)

View File

@@ -0,0 +1,28 @@
[expected.un.eq]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#un.eq)
### 22.8.3 Class template unexpected [[expected.unexpected]](expected.unexpected#expected.un.eq)
#### 22.8.3.5 Equality operator [expected.un.eq]
[🔗](#lib:operator==,unexpected)
`template<class E2>
friend constexpr bool operator==(const unexpected& x, const unexpected<E2>& y);
`
[1](#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[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7892)
*Returns*: x.error() == y.error()[.](#2.sentence-1)

View File

@@ -0,0 +1,30 @@
[expected.un.general]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#un.general)
### 22.8.3 Class template unexpected [[expected.unexpected]](expected.unexpected#expected.un.general)
#### 22.8.3.1 General [expected.un.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7698)
Subclause [[expected.unexpected]](expected.unexpected "22.8.3Class template unexpected") describes the class template unexpected that represents unexpected objects stored in expected objects[.](#1.sentence-1)
[🔗](#lib:unexpected)
namespace std {template<class E>class unexpected {public:// [[expected.un.cons]](expected.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](#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[.](#2.sentence-1)

View File

@@ -0,0 +1,33 @@
[expected.un.obs]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#un.obs)
### 22.8.3 Class template unexpected [[expected.unexpected]](expected.unexpected#expected.un.obs)
#### 22.8.3.3 Observers [expected.un.obs]
[🔗](#lib:error,unexpected)
`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7829)
*Returns*: *unex*[.](#1.sentence-1)
[🔗](#lib:error,unexpected_)
`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7841)
*Returns*: std::move(*unex*)[.](#2.sentence-1)

View File

@@ -0,0 +1,43 @@
[expected.un.swap]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#un.swap)
### 22.8.3 Class template unexpected [[expected.unexpected]](expected.unexpected#expected.un.swap)
#### 22.8.3.4 Swap [expected.un.swap]
[🔗](#lib:swap,unexpected)
`constexpr void swap(unexpected& other) noexcept(is_nothrow_swappable_v<E>);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7854)
*Mandates*: is_swappable_v<E> is true[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7858)
*Effects*: Equivalent to:using std::swap; swap(*unex*, other.*unex*);
[🔗](#itemdecl:2)
`friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y)));
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7869)
*Constraints*: is_swappable_v<E> is true[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7873)
*Effects*: Equivalent to x.swap(y)[.](#4.sentence-1)

View File

@@ -0,0 +1,199 @@
[expected.unexpected]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#unexpected)
### 22.8.3 Class template unexpected [expected.unexpected]
#### [22.8.3.1](#expected.un.general) General [[expected.un.general]](expected.un.general)
[1](#expected.un.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7698)
Subclause [expected.unexpected] describes the class template unexpected that represents unexpected objects stored in expected objects[.](#expected.un.general-1.sentence-1)
[🔗](#lib:unexpected)
namespace std {template<class E>class unexpected {public:// [[expected.un.cons]](#expected.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](#expected.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[.](#expected.un.general-2.sentence-1)
#### [22.8.3.2](#expected.un.cons) Constructors [[expected.un.cons]](expected.un.cons)
[🔗](#lib:unexpected,constructor)
`template<class Err = E>
constexpr explicit unexpected(Err&& e);
`
[1](#expected.un.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7758)
*Constraints*:
- [(1.1)](#expected.un.cons-1.1)
is_same_v<remove_cvref_t<Err>, unexpected> is false; and
- [(1.2)](#expected.un.cons-1.2)
is_same_v<remove_cvref_t<Err>, in_place_t> is false; and
- [(1.3)](#expected.un.cons-1.3)
is_constructible_v<E, Err> is true[.](#expected.un.cons-1.sentence-1)
[2](#expected.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)[.](#expected.un.cons-2.sentence-1)
[3](#expected.un.cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7773)
*Throws*: Any exception thrown by the initialization of *unex*[.](#expected.un.cons-3.sentence-1)
[🔗](#lib:unexpected,constructor_)
`template<class... Args>
constexpr explicit unexpected(in_place_t, Args&&... args);
`
[4](#expected.un.cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7785)
*Constraints*: is_constructible_v<E, Args...> is true[.](#expected.un.cons-4.sentence-1)
[5](#expected.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)...[.](#expected.un.cons-5.sentence-1)
[6](#expected.un.cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7794)
*Throws*: Any exception thrown by the initialization of *unex*[.](#expected.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](#expected.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[.](#expected.un.cons-7.sentence-1)
[8](#expected.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)...[.](#expected.un.cons-8.sentence-1)
[9](#expected.un.cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7815)
*Throws*: Any exception thrown by the initialization of *unex*[.](#expected.un.cons-9.sentence-1)
#### [22.8.3.3](#expected.un.obs) Observers [[expected.un.obs]](expected.un.obs)
[🔗](#lib:error,unexpected)
`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`
[1](#expected.un.obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7829)
*Returns*: *unex*[.](#expected.un.obs-1.sentence-1)
[🔗](#lib:error,unexpected_)
`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`
[2](#expected.un.obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7841)
*Returns*: std::move(*unex*)[.](#expected.un.obs-2.sentence-1)
#### [22.8.3.4](#expected.un.swap) Swap [[expected.un.swap]](expected.un.swap)
[🔗](#lib:swap,unexpected)
`constexpr void swap(unexpected& other) noexcept(is_nothrow_swappable_v<E>);
`
[1](#expected.un.swap-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7854)
*Mandates*: is_swappable_v<E> is true[.](#expected.un.swap-1.sentence-1)
[2](#expected.un.swap-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7858)
*Effects*: Equivalent to:using std::swap; swap(*unex*, other.*unex*);
[🔗](#expected.un.swap-itemdecl:2)
`friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y)));
`
[3](#expected.un.swap-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7869)
*Constraints*: is_swappable_v<E> is true[.](#expected.un.swap-3.sentence-1)
[4](#expected.un.swap-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7873)
*Effects*: Equivalent to x.swap(y)[.](#expected.un.swap-4.sentence-1)
#### [22.8.3.5](#expected.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](#expected.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[.](#expected.un.eq-1.sentence-1)
[2](#expected.un.eq-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7892)
*Returns*: x.error() == y.error()[.](#expected.un.eq-2.sentence-1)

931
cppdraft/expected/void.md Normal file
View File

@@ -0,0 +1,931 @@
[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)

View File

@@ -0,0 +1,148 @@
[expected.void.assign]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#void.assign)
### 22.8.7 Partial specialization of expected for void types [[expected.void]](expected.void#assign)
#### 22.8.7.4 Assignment [expected.void.assign]
[🔗](#lib:operator=,expected%3cvoid%3e)
`constexpr expected& operator=(const expected& rhs);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9771)
*Effects*:
- [(1.1)](#1.1)
If this->has_value() && rhs.has_value() is true, no effects[.](#1.1.sentence-1)
- [(1.2)](#1.2)
Otherwise, if this->has_value() is true,
equivalent to: construct_at(addressof(*unex*), rhs.*unex*); *has_val* = false;
- [(1.3)](#1.3)
Otherwise, if rhs.has_value() is true,
destroys *unex* and sets *has_val* to true[.](#1.3.sentence-1)
- [(1.4)](#1.4)
Otherwise, equivalent to *unex* = rhs.error()[.](#1.4.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9786)
*Returns*: *this[.](#2.sentence-1)
[3](#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[.](#3.sentence-1)
[🔗](#lib:operator=,expected%3cvoid%3e_)
`constexpr expected& operator=(expected&& rhs) noexcept(see below);
`
[4](#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[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9808)
*Effects*:
- [(5.1)](#5.1)
If this->has_value() && rhs.has_value() is true, no effects[.](#5.1.sentence-1)
- [(5.2)](#5.2)
Otherwise, if this->has_value() is true, equivalent to:construct_at(addressof(*unex*), std::move(rhs.*unex*));*has_val* = false;
- [(5.3)](#5.3)
Otherwise, if rhs.has_value() is true,
destroys *unex* and sets *has_val* to true[.](#5.3.sentence-1)
- [(5.4)](#5.4)
Otherwise, equivalent to *unex* = std::move(rhs.error())[.](#5.4.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9826)
*Returns*: *this[.](#6.sentence-1)
[7](#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>[.](#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](#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[.](#8.sentence-1)
[9](#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[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9854)
*Effects*:
- [(10.1)](#10.1)
If has_value() is true, equivalent to:construct_at(addressof(*unex*), std::forward<GF>(e.error()));*has_val* = false;
- [(10.2)](#10.2)
Otherwise, equivalent to:*unex* = std::forward<GF>(e.error());
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9868)
*Returns*: *this[.](#11.sentence-1)
[🔗](#lib:emplace,expected%3cvoid%3e)
`constexpr void emplace() noexcept;
`
[12](#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[.](#12.sentence-1)

View File

@@ -0,0 +1,267 @@
[expected.void.cons]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#void.cons)
### 22.8.7 Partial specialization of expected for void types [[expected.void]](expected.void#cons)
#### 22.8.7.2 Constructors [expected.void.cons]
[🔗](#lib:expected%3cvoid%3e,constructor)
`constexpr expected() noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9539)
*Postconditions*: has_value() is true[.](#1.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor_)
`constexpr expected(const expected& rhs);
`
[2](#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()[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9555)
*Postconditions*: rhs.has_value() == this->has_value()[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9559)
*Throws*: Any exception thrown by the initialization of *unex*[.](#4.sentence-1)
[5](#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[.](#5.sentence-1)
[6](#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[.](#6.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor__)
`constexpr expected(expected&& rhs) noexcept(is_nothrow_move_constructible_v<E>);
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9579)
*Constraints*: is_move_constructible_v<E> is true[.](#7.sentence-1)
[8](#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())[.](#8.sentence-1)
[9](#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[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9593)
*Throws*: Any exception thrown by the initialization of *unex*[.](#10.sentence-1)
[11](#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[.](#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](#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[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9616)
*Constraints*:
- [(13.1)](#13.1)
is_void_v<U> is true; and
- [(13.2)](#13.2)
is_constructible_v<E, GF> is true; and
- [(13.3)](#13.3)
is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
- [(13.4)](#13.4)
is_constructible_v<unexpected<E>, expected<U, G>> is false; and
- [(13.5)](#13.5)
is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
- [(13.6)](#13.6)
is_constructible_v<unexpected<E>, const expected<U, G>> is false[.](#13.sentence-1)
[14](#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())[.](#14.sentence-1)
[15](#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[.](#15.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9648)
*Throws*: Any exception thrown by the initialization of *unex*[.](#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](#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[.](#17.sentence-1)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9666)
*Constraints*: is_constructible_v<E, GF> is true[.](#18.sentence-1)
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9670)
*Effects*: Direct-non-list-initializes *unex* with std::forward<GF>(e.error())[.](#19.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9675)
*Postconditions*: has_value() is false[.](#20.sentence-1)
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9679)
*Throws*: Any exception thrown by the initialization of *unex*[.](#21.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor_____)
`constexpr explicit expected(in_place_t) noexcept;
`
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9690)
*Postconditions*: has_value() is true[.](#22.sentence-1)
[🔗](#lib:expected%3cvoid%3e,constructor______)
`template<class... Args>
constexpr explicit expected(unexpect_t, Args&&... args);
`
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9702)
*Constraints*: is_constructible_v<E, Args...> is true[.](#23.sentence-1)
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9706)
*Effects*: Direct-non-list-initializes *unex* with std::forward<Args>(args)...[.](#24.sentence-1)
[25](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9711)
*Postconditions*: has_value() is false[.](#25.sentence-1)
[26](#26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9715)
*Throws*: Any exception thrown by the initialization of *unex*[.](#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](#27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9727)
*Constraints*: is_constructible_v<E, initializer_list<U>&, Args...> is true[.](#27.sentence-1)
[28](#28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9731)
*Effects*: Direct-non-list-initializes *unex* with il, std::forward<Args>(args)...[.](#28.sentence-1)
[29](#29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9736)
*Postconditions*: has_value() is false[.](#29.sentence-1)
[30](#30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9740)
*Throws*: Any exception thrown by the initialization of *unex*[.](#30.sentence-1)

View File

@@ -0,0 +1,27 @@
[expected.void.dtor]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#void.dtor)
### 22.8.7 Partial specialization of expected for void types [[expected.void]](expected.void#dtor)
#### 22.8.7.3 Destructor [expected.void.dtor]
[🔗](#lib:expected%3cvoid%3e,destructor)
`constexpr ~expected();
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9753)
*Effects*: If has_value() is false, destroys *unex*[.](#1.sentence-1)
[2](#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[.](#2.sentence-1)

View File

@@ -0,0 +1,48 @@
[expected.void.eq]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#void.eq)
### 22.8.7 Partial specialization of expected for void types [[expected.void]](expected.void#eq)
#### 22.8.7.8 Equality operators [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](#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[.](#1.sentence-1)
[2](#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())[.](#2.sentence-1)
[🔗](#lib:operator==,expected%3cvoid%3e_)
`template<class E2>
friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
`
[3](#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[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10350)
*Returns*: !x.has_value() && static_cast<bool>(x.error() == e.error())[.](#4.sentence-1)

View File

@@ -0,0 +1,39 @@
[expected.void.general]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#void.general)
### 22.8.7 Partial specialization of expected for void types [[expected.void]](expected.void#general)
#### 22.8.7.1 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]](expected.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]](expected.void.dtor "22.8.7.3Destructor"), destructorconstexpr ~expected(); // [[expected.void.assign]](expected.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]](expected.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]](expected.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]](expected.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]](expected.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](#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[.](#1.sentence-1)
Member *has_val* indicates whether the expected<T, E> object
represents a value of type T[.](#1.sentence-2)
[2](#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[.](#2.sentence-1)
[3](#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"))[.](#3.sentence-1)

View File

@@ -0,0 +1,255 @@
[expected.void.monadic]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#void.monadic)
### 22.8.7 Partial specialization of expected for void types [[expected.void]](expected.void#monadic)
#### 22.8.7.7 Monadic operations [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](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10077)
Let U be remove_cvref_t<invoke_result_t<F>>[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10080)
*Constraints*: is_constructible_v<E, decltype(error())>> is true[.](#2.sentence-1)
[3](#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[.](#3.sentence-1)
[4](#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](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10107)
Let U be remove_cvref_t<invoke_result_t<F>>[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10110)
*Constraints*: is_constructible_v<E, decltype(std::move(error()))> is true[.](#6.sentence-1)
[7](#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[.](#7.sentence-1)
[8](#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](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10137)
Let G be remove_cvref_t<invoke_result_t<F, decltype(error())>>[.](#9.sentence-1)
[10](#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[.](#10.sentence-1)
[11](#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](#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()))>>[.](#12.sentence-1)
[13](#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[.](#13.sentence-1)
[14](#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](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10190)
Let U be remove_cv_t<invoke_result_t<F>>[.](#15.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10193)
*Constraints*: is_constructible_v<E, decltype(error())> is true[.](#16.sentence-1)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10197)
*Mandates*: U is a valid value type for expected[.](#17.sentence-1)
If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f))); is well-formed[.](#17.sentence-2)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10206)
*Effects*:
- [(18.1)](#18.1)
If has_value() is false, returnsexpected<U, E>(unexpect, error())[.](#18.1.sentence-1)
- [(18.2)](#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))[.](#18.2.sentence-1)
- [(18.3)](#18.3)
Otherwise, evaluates invoke(std::forward<F>(f)) and then returnsexpected<U, E>()[.](#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](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10230)
Let U be remove_cv_t<invoke_result_t<F>>[.](#19.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10233)
*Constraints*: is_constructible_v<E, decltype(std::move(error()))> is true[.](#20.sentence-1)
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10237)
*Mandates*: U is a valid value type for expected[.](#21.sentence-1)
If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f))); is well-formed[.](#21.sentence-2)
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10246)
*Effects*:
- [(22.1)](#22.1)
If has_value() is false, returnsexpected<U, E>(unexpect, std::move(error()))[.](#22.1.sentence-1)
- [(22.2)](#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))[.](#22.2.sentence-1)
- [(22.3)](#22.3)
Otherwise, evaluates invoke(std::forward<F>(f)) and then returnsexpected<U, E>()[.](#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](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10270)
Let G be remove_cv_t<invoke_result_t<F, decltype(error())>>[.](#23.sentence-1)
[24](#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[.](#24.sentence-1)
[25](#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())[.](#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](#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()))>>[.](#26.sentence-1)
[27](#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[.](#27.sentence-1)
[28](#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()))[.](#28.sentence-1)

View File

@@ -0,0 +1,136 @@
[expected.void.obs]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#void.obs)
### 22.8.7 Partial specialization of expected for void types [[expected.void]](expected.void#obs)
#### 22.8.7.6 Observers [expected.void.obs]
[🔗](#lib:operator_bool,expected%3cvoid%3e)
`constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9954)
*Returns*: *has_val*[.](#1.sentence-1)
[🔗](#lib:operator*,expected%3cvoid%3e)
`constexpr void operator*() const noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9965)
*Hardened preconditions*: has_value() is true[.](#2.sentence-1)
[🔗](#lib:value,expected%3cvoid%3e)
`constexpr void value() const &;
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9976)
*Mandates*: is_copy_constructible_v<E> is true[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9980)
*Throws*: bad_expected_access(error()) if has_value() is false[.](#4.sentence-1)
[🔗](#lib:value,expected%3cvoid%3e_)
`constexpr void value() &&;
`
[5](#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[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9996)
*Throws*: bad_expected_access(std::move(error())) if has_value() is false[.](#6.sentence-1)
[🔗](#lib:error,expected%3cvoid%3e)
`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10009)
*Hardened preconditions*: has_value() is false[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10013)
*Returns*: *unex*[.](#8.sentence-1)
[🔗](#lib:error,expected%3cvoid%3e_)
`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10025)
*Hardened preconditions*: has_value() is false[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10029)
*Returns*: std::move(*unex*)[.](#10.sentence-1)
[🔗](#lib:error_or,expected%3cvoid%3e)
`template<class G = E> constexpr E error_or(G&& e) const &;
`
[11](#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[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10045)
*Returns*: std::forward<G>(e) if has_value() is true,error() otherwise[.](#12.sentence-1)
[🔗](#lib:error_or,expected%3cvoid%3e_)
`template<class G = E> constexpr E error_or(G&& e) &&;
`
[13](#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[.](#13.sentence-1)
[14](#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[.](#14.sentence-1)

View File

@@ -0,0 +1,60 @@
[expected.void.swap]
# 22 General utilities library [[utilities]](./#utilities)
## 22.8 Expected objects [[expected]](expected#void.swap)
### 22.8.7 Partial specialization of expected for void types [[expected.void]](expected.void#swap)
#### 22.8.7.5 Swap [expected.void.swap]
[🔗](#lib:swap,expected%3cvoid%3e)
`constexpr void swap(expected& rhs) noexcept(see below);
`
[1](#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[.](#1.sentence-1)
[2](#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")[.](#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](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9923)
*Throws*: Any exception thrown by the expressions in the *Effects*[.](#3.sentence-1)
[4](#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>[.](#4.sentence-1)
[🔗](#lib:swap,expected%3cvoid%3e_)
`friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9939)
*Effects*: Equivalent to x.swap(y)[.](#5.sentence-1)