From Jason Turner

[expected]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpn_ct8hd0/{from.md → to.md} +1855 -0
tmp/tmpn_ct8hd0/{from.md → to.md} RENAMED
@@ -0,0 +1,1855 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Expected objects <a id="expected">[[expected]]</a>
2
+
3
+ ### In general <a id="expected.general">[[expected.general]]</a>
4
+
5
+ Subclause [[expected]] describes the class template `expected` that
6
+ represents expected objects. An `expected<T, E>` object holds an object
7
+ of type `T` or an object of type `unexpected<E>` and manages the
8
+ lifetime of the contained objects.
9
+
10
+ ### Header `<expected>` synopsis <a id="expected.syn">[[expected.syn]]</a>
11
+
12
+ ``` cpp
13
+ namespace std {
14
+ // [expected.unexpected], class template unexpected
15
+ template<class E> class unexpected;
16
+
17
+ // [expected.bad], class template bad_expected_access
18
+ template<class E> class bad_expected_access;
19
+
20
+ // [expected.bad.void], specialization for void
21
+ template<> class bad_expected_access<void>;
22
+
23
+ // in-place construction of unexpected values
24
+ struct unexpect_t {
25
+ explicit unexpect_t() = default;
26
+ };
27
+ inline constexpr unexpect_t unexpect{};
28
+
29
+ // [expected.expected], class template expected
30
+ template<class T, class E> class expected;
31
+
32
+ // [expected.void], partial specialization of expected for void types
33
+ template<class T, class E> requires is_void_v<T> class expected<T, E>;
34
+ }
35
+ ```
36
+
37
+ ### Class template `unexpected` <a id="expected.unexpected">[[expected.unexpected]]</a>
38
+
39
+ #### General <a id="expected.un.general">[[expected.un.general]]</a>
40
+
41
+ Subclause [[expected.unexpected]] describes the class template
42
+ `unexpected` that represents unexpected objects stored in `expected`
43
+ objects.
44
+
45
+ ``` cpp
46
+ namespace std {
47
+ template<class E>
48
+ class unexpected {
49
+ public:
50
+ // [expected.un.cons], constructors
51
+ constexpr unexpected(const unexpected&) = default;
52
+ constexpr unexpected(unexpected&&) = default;
53
+ template<class Err = E>
54
+ constexpr explicit unexpected(Err&&);
55
+ template<class... Args>
56
+ constexpr explicit unexpected(in_place_t, Args&&...);
57
+ template<class U, class... Args>
58
+ constexpr explicit unexpected(in_place_t, initializer_list<U>, Args&&...);
59
+
60
+ constexpr unexpected& operator=(const unexpected&) = default;
61
+ constexpr unexpected& operator=(unexpected&&) = default;
62
+
63
+ constexpr const E& error() const & noexcept;
64
+ constexpr E& error() & noexcept;
65
+ constexpr const E&& error() const && noexcept;
66
+ constexpr E&& error() && noexcept;
67
+
68
+ constexpr void swap(unexpected& other) noexcept(see below);
69
+
70
+ template<class E2>
71
+ friend constexpr bool operator==(const unexpected&, const unexpected<E2>&);
72
+
73
+ friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y)));
74
+
75
+ private:
76
+ E unex; // exposition only
77
+ };
78
+
79
+ template<class E> unexpected(E) -> unexpected<E>;
80
+ }
81
+ ```
82
+
83
+ A program that instantiates the definition of `unexpected` for a
84
+ non-object type, an array type, a specialization of `unexpected`, or a
85
+ cv-qualified type is ill-formed.
86
+
87
+ #### Constructors <a id="expected.un.cons">[[expected.un.cons]]</a>
88
+
89
+ ``` cpp
90
+ template<class Err = E>
91
+ constexpr explicit unexpected(Err&& e);
92
+ ```
93
+
94
+ *Constraints:*
95
+
96
+ - `is_same_v<remove_cvref_t<Err>, unexpected>` is `false`; and
97
+ - `is_same_v<remove_cvref_t<Err>, in_place_t>` is `false`; and
98
+ - `is_constructible_v<E, Err>` is `true`.
99
+
100
+ *Effects:* Direct-non-list-initializes *unex* with
101
+ `std::forward<Err>(e)`.
102
+
103
+ *Throws:* Any exception thrown by the initialization of *unex*.
104
+
105
+ ``` cpp
106
+ template<class... Args>
107
+ constexpr explicit unexpected(in_place_t, Args&&... args);
108
+ ```
109
+
110
+ *Constraints:* `is_constructible_v<E, Args...>` is `true`.
111
+
112
+ *Effects:* Direct-non-list-initializes *unex* with
113
+ `std::forward<Args>(args)...`.
114
+
115
+ *Throws:* Any exception thrown by the initialization of *unex*.
116
+
117
+ ``` cpp
118
+ template<class U, class... Args>
119
+ constexpr explicit unexpected(in_place_t, initializer_list<U> il, Args&&... args);
120
+ ```
121
+
122
+ *Constraints:* `is_constructible_v<E, initializer_list<U>&, Args...>` is
123
+ `true`.
124
+
125
+ *Effects:* Direct-non-list-initializes *unex* with
126
+ `il, std::forward<Args>(args)...`.
127
+
128
+ *Throws:* Any exception thrown by the initialization of *unex*.
129
+
130
+ #### Observers <a id="expected.un.obs">[[expected.un.obs]]</a>
131
+
132
+ ``` cpp
133
+ constexpr const E& error() const & noexcept;
134
+ constexpr E& error() & noexcept;
135
+ ```
136
+
137
+ *Returns:* *unex*.
138
+
139
+ ``` cpp
140
+ constexpr E&& error() && noexcept;
141
+ constexpr const E&& error() const && noexcept;
142
+ ```
143
+
144
+ *Returns:* `std::move(`*`unex`*`)`.
145
+
146
+ #### Swap <a id="expected.un.swap">[[expected.un.swap]]</a>
147
+
148
+ ``` cpp
149
+ constexpr void swap(unexpected& other) noexcept(is_nothrow_swappable_v<E>);
150
+ ```
151
+
152
+ *Mandates:* `is_swappable_v<E>` is `true`.
153
+
154
+ *Effects:* Equivalent to:
155
+ `using std::swap; swap(`*`unex`*`, other.`*`unex`*`);`
156
+
157
+ ``` cpp
158
+ friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y)));
159
+ ```
160
+
161
+ *Constraints:* `is_swappable_v<E>` is `true`.
162
+
163
+ *Effects:* Equivalent to `x.swap(y)`.
164
+
165
+ #### Equality operator <a id="expected.un.eq">[[expected.un.eq]]</a>
166
+
167
+ ``` cpp
168
+ template<class E2>
169
+ friend constexpr bool operator==(const unexpected& x, const unexpected<E2>& y);
170
+ ```
171
+
172
+ *Mandates:* The expression `x.error() == y.error()` is well-formed and
173
+ its result is convertible to `bool`.
174
+
175
+ *Returns:* `x.error() == y.error()`.
176
+
177
+ ### Class template `bad_expected_access` <a id="expected.bad">[[expected.bad]]</a>
178
+
179
+ ``` cpp
180
+ namespace std {
181
+ template<class E>
182
+ class bad_expected_access : public bad_expected_access<void> {
183
+ public:
184
+ explicit bad_expected_access(E);
185
+ const char* what() const noexcept override;
186
+ E& error() & noexcept;
187
+ const E& error() const & noexcept;
188
+ E&& error() && noexcept;
189
+ const E&& error() const && noexcept;
190
+
191
+ private:
192
+ E unex; // exposition only
193
+ };
194
+ }
195
+ ```
196
+
197
+ The class template `bad_expected_access` defines the type of objects
198
+ thrown as exceptions to report the situation where an attempt is made to
199
+ access the value of an `expected<T, E>` object for which `has_value()`
200
+ is `false`.
201
+
202
+ ``` cpp
203
+ explicit bad_expected_access(E e);
204
+ ```
205
+
206
+ *Effects:* Initializes *unex* with `std::move(e)`.
207
+
208
+ ``` cpp
209
+ const E& error() const & noexcept;
210
+ E& error() & noexcept;
211
+ ```
212
+
213
+ *Returns:* *unex*.
214
+
215
+ ``` cpp
216
+ E&& error() && noexcept;
217
+ const E&& error() const && noexcept;
218
+ ```
219
+
220
+ *Returns:* `std::move(`*`unex`*`)`.
221
+
222
+ ``` cpp
223
+ const char* what() const noexcept override;
224
+ ```
225
+
226
+ *Returns:* An implementation-defined NTBS.
227
+
228
+ ### Class template specialization `bad_expected_access<void>` <a id="expected.bad.void">[[expected.bad.void]]</a>
229
+
230
+ ``` cpp
231
+ namespace std {
232
+ template<>
233
+ class bad_expected_access<void> : public exception {
234
+ protected:
235
+ bad_expected_access() noexcept;
236
+ bad_expected_access(const bad_expected_access&);
237
+ bad_expected_access(bad_expected_access&&);
238
+ bad_expected_access& operator=(const bad_expected_access&);
239
+ bad_expected_access& operator=(bad_expected_access&&);
240
+ ~bad_expected_access();
241
+
242
+ public:
243
+ const char* what() const noexcept override;
244
+ };
245
+ }
246
+ ```
247
+
248
+ ``` cpp
249
+ const char* what() const noexcept override;
250
+ ```
251
+
252
+ *Returns:* An implementation-defined NTBS.
253
+
254
+ ### Class template `expected` <a id="expected.expected">[[expected.expected]]</a>
255
+
256
+ #### General <a id="expected.object.general">[[expected.object.general]]</a>
257
+
258
+ ``` cpp
259
+ namespace std {
260
+ template<class T, class E>
261
+ class expected {
262
+ public:
263
+ using value_type = T;
264
+ using error_type = E;
265
+ using unexpected_type = unexpected<E>;
266
+
267
+ template<class U>
268
+ using rebind = expected<U, error_type>;
269
+
270
+ // [expected.object.cons], constructors
271
+ constexpr expected();
272
+ constexpr expected(const expected&);
273
+ constexpr expected(expected&&) noexcept(see below);
274
+ template<class U, class G>
275
+ constexpr explicit(see below) expected(const expected<U, G>&);
276
+ template<class U, class G>
277
+ constexpr explicit(see below) expected(expected<U, G>&&);
278
+
279
+ template<class U = T>
280
+ constexpr explicit(see below) expected(U&& v);
281
+
282
+ template<class G>
283
+ constexpr explicit(see below) expected(const unexpected<G>&);
284
+ template<class G>
285
+ constexpr explicit(see below) expected(unexpected<G>&&);
286
+
287
+ template<class... Args>
288
+ constexpr explicit expected(in_place_t, Args&&...);
289
+ template<class U, class... Args>
290
+ constexpr explicit expected(in_place_t, initializer_list<U>, Args&&...);
291
+ template<class... Args>
292
+ constexpr explicit expected(unexpect_t, Args&&...);
293
+ template<class U, class... Args>
294
+ constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...);
295
+
296
+ // [expected.object.dtor], destructor
297
+ constexpr ~expected();
298
+
299
+ // [expected.object.assign], assignment
300
+ constexpr expected& operator=(const expected&);
301
+ constexpr expected& operator=(expected&&) noexcept(see below);
302
+ template<class U = T> constexpr expected& operator=(U&&);
303
+ template<class G>
304
+ constexpr expected& operator=(const unexpected<G>&);
305
+ template<class G>
306
+ constexpr expected& operator=(unexpected<G>&&);
307
+
308
+ template<class... Args>
309
+ constexpr T& emplace(Args&&...) noexcept;
310
+ template<class U, class... Args>
311
+ constexpr T& emplace(initializer_list<U>, Args&&...) noexcept;
312
+
313
+ // [expected.object.swap], swap
314
+ constexpr void swap(expected&) noexcept(see below);
315
+ friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
316
+
317
+ // [expected.object.obs], observers
318
+ constexpr const T* operator->() const noexcept;
319
+ constexpr T* operator->() noexcept;
320
+ constexpr const T& operator*() const & noexcept;
321
+ constexpr T& operator*() & noexcept;
322
+ constexpr const T&& operator*() const && noexcept;
323
+ constexpr T&& operator*() && noexcept;
324
+ constexpr explicit operator bool() const noexcept;
325
+ constexpr bool has_value() const noexcept;
326
+ constexpr const T& value() const &;
327
+ constexpr T& value() &;
328
+ constexpr const T&& value() const &&;
329
+ constexpr T&& value() &&;
330
+ constexpr const E& error() const & noexcept;
331
+ constexpr E& error() & noexcept;
332
+ constexpr const E&& error() const && noexcept;
333
+ constexpr E&& error() && noexcept;
334
+ template<class U> constexpr T value_or(U&&) const &;
335
+ template<class U> constexpr T value_or(U&&) &&;
336
+ template<class G = E> constexpr E error_or(G&&) const &;
337
+ template<class G = E> constexpr E error_or(G&&) &&;
338
+
339
+ // [expected.object.monadic], monadic operations
340
+ template<class F> constexpr auto and_then(F&& f) &;
341
+ template<class F> constexpr auto and_then(F&& f) &&;
342
+ template<class F> constexpr auto and_then(F&& f) const &;
343
+ template<class F> constexpr auto and_then(F&& f) const &&;
344
+ template<class F> constexpr auto or_else(F&& f) &;
345
+ template<class F> constexpr auto or_else(F&& f) &&;
346
+ template<class F> constexpr auto or_else(F&& f) const &;
347
+ template<class F> constexpr auto or_else(F&& f) const &&;
348
+ template<class F> constexpr auto transform(F&& f) &;
349
+ template<class F> constexpr auto transform(F&& f) &&;
350
+ template<class F> constexpr auto transform(F&& f) const &;
351
+ template<class F> constexpr auto transform(F&& f) const &&;
352
+ template<class F> constexpr auto transform_error(F&& f) &;
353
+ template<class F> constexpr auto transform_error(F&& f) &&;
354
+ template<class F> constexpr auto transform_error(F&& f) const &;
355
+ template<class F> constexpr auto transform_error(F&& f) const &&;
356
+
357
+ // [expected.object.eq], equality operators
358
+ template<class T2, class E2> requires (!is_void_v<T2>)
359
+ friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
360
+ template<class T2>
361
+ friend constexpr bool operator==(const expected&, const T2&);
362
+ template<class E2>
363
+ friend constexpr bool operator==(const expected&, const unexpected<E2>&);
364
+
365
+ private:
366
+ bool has_val; // exposition only
367
+ union {
368
+ T val; // exposition only
369
+ E unex; // exposition only
370
+ };
371
+ };
372
+ }
373
+ ```
374
+
375
+ Any object of type `expected<T, E>` either contains a value of type `T`
376
+ or a value of type `E` within its own storage. Implementations are not
377
+ permitted to use additional storage, such as dynamic memory, to allocate
378
+ the object of type `T` or the object of type `E`. Member *`has_val`*
379
+ indicates whether the `expected<T, E>` object contains an object of type
380
+ `T`.
381
+
382
+ A type `T` is a *valid value type for `expected`*, if `remove_cv_t<T>`
383
+ is `void` or a complete non-array object type that is not `in_place_t`,
384
+ `unexpect_t`, or a specialization of `unexpected`. A program which
385
+ instantiates class template `expected<T, E>` with an argument `T` that
386
+ is not a valid value type for `expected` is ill-formed. A program that
387
+ instantiates the definition of the template `expected<T, E>` with a type
388
+ for the `E` parameter that is not a valid template argument for
389
+ `unexpected` is ill-formed.
390
+
391
+ When `T` is not cv `void`, it shall meet the *Cpp17Destructible*
392
+ requirements ([[cpp17.destructible]]). `E` shall meet the
393
+ *Cpp17Destructible* requirements.
394
+
395
+ #### Constructors <a id="expected.object.cons">[[expected.object.cons]]</a>
396
+
397
+ The exposition-only variable template *`converts-from-any-cvref`*
398
+ defined in [[optional.ctor]] is used by some constructors for
399
+ `expected`.
400
+
401
+ ``` cpp
402
+ constexpr expected();
403
+ ```
404
+
405
+ *Constraints:* `is_default_constructible_v<T>` is `true`.
406
+
407
+ *Effects:* Value-initializes *val*.
408
+
409
+ *Ensures:* `has_value()` is `true`.
410
+
411
+ *Throws:* Any exception thrown by the initialization of *val*.
412
+
413
+ ``` cpp
414
+ constexpr expected(const expected& rhs);
415
+ ```
416
+
417
+ *Effects:* If `rhs.has_value()` is `true`, direct-non-list-initializes
418
+ *val* with `*rhs`. Otherwise, direct-non-list-initializes *unex* with
419
+ `rhs.error()`.
420
+
421
+ *Ensures:* `rhs.has_value() == this->has_value()`.
422
+
423
+ *Throws:* Any exception thrown by the initialization of *val* or *unex*.
424
+
425
+ *Remarks:* This constructor is defined as deleted unless
426
+
427
+ - `is_copy_constructible_v<T>` is `true` and
428
+ - `is_copy_constructible_v<E>` is `true`.
429
+
430
+ This constructor is trivial if
431
+
432
+ - `is_trivially_copy_constructible_v<T>` is `true` and
433
+ - `is_trivially_copy_constructible_v<E>` is `true`.
434
+
435
+ ``` cpp
436
+ constexpr expected(expected&& rhs) noexcept(see below);
437
+ ```
438
+
439
+ *Constraints:*
440
+
441
+ - `is_move_constructible_v<T>` is `true` and
442
+ - `is_move_constructible_v<E>` is `true`.
443
+
444
+ *Effects:* If `rhs.has_value()` is `true`, direct-non-list-initializes
445
+ *val* with `std::move(*rhs)`. Otherwise, direct-non-list-initializes
446
+ *unex* with `std::move(rhs.error())`.
447
+
448
+ *Ensures:* `rhs.has_value()` is unchanged;
449
+ `rhs.has_value() == this->has_value()` is `true`.
450
+
451
+ *Throws:* Any exception thrown by the initialization of *val* or *unex*.
452
+
453
+ *Remarks:* The exception specification is equivalent to
454
+ `is_nothrow_move_constructible_v<T> && is_nothrow_move_constructible_v<E>`.
455
+
456
+ This constructor is trivial if
457
+
458
+ - `is_trivially_move_constructible_v<T>` is `true` and
459
+ - `is_trivially_move_constructible_v<E>` is `true`.
460
+
461
+ ``` cpp
462
+ template<class U, class G>
463
+ constexpr explicit(see below) expected(const expected<U, G>& rhs);
464
+ template<class U, class G>
465
+ constexpr explicit(see below) expected(expected<U, G>&& rhs);
466
+ ```
467
+
468
+ Let:
469
+
470
+ - `UF` be `const U&` for the first overload and `U` for the second
471
+ overload.
472
+ - `GF` be `const G&` for the first overload and `G` for the second
473
+ overload.
474
+
475
+ *Constraints:*
476
+
477
+ - `is_constructible_v<T, UF>` is `true`; and
478
+ - `is_constructible_v<E, GF>` is `true`; and
479
+ - if `T` is not cv `bool`,
480
+ *`converts-from-any-cvref`*`<T, expected<U, G>>` is `false`; and
481
+ - `is_constructible_v<unexpected<E>, expected<U, G>&>` is `false`; and
482
+ - `is_constructible_v<unexpected<E>, expected<U, G>>` is `false`; and
483
+ - `is_constructible_v<unexpected<E>, const expected<U, G>&>` is `false`;
484
+ and
485
+ - `is_constructible_v<unexpected<E>, const expected<U, G>>` is `false`.
486
+
487
+ *Effects:* If `rhs.has_value()`, direct-non-list-initializes *val* with
488
+ `std::forward<UF>(*rhs)`. Otherwise, direct-non-list-initializes *unex*
489
+ with `std::forward<GF>(rhs.error())`.
490
+
491
+ *Ensures:* `rhs.has_value()` is unchanged;
492
+ `rhs.has_value() == this->has_value()` is `true`.
493
+
494
+ *Throws:* Any exception thrown by the initialization of *val* or *unex*.
495
+
496
+ *Remarks:* The expression inside `explicit` is equivalent to
497
+ `!is_convertible_v<UF, T> || !is_convertible_v<GF, E>`.
498
+
499
+ ``` cpp
500
+ template<class U = T>
501
+ constexpr explicit(!is_convertible_v<U, T>) expected(U&& v);
502
+ ```
503
+
504
+ *Constraints:*
505
+
506
+ - `is_same_v<remove_cvref_t<U>, in_place_t>` is `false`; and
507
+ - `is_same_v<expected, remove_cvref_t<U>>` is `false`; and
508
+ - `remove_cvref_t<U>` is not a specialization of `unexpected`; and
509
+ - `is_constructible_v<T, U>` is `true`; and
510
+ - if `T` is cv `bool`, `remove_cvref_t<U>` is not a specialization of
511
+ `expected`.
512
+
513
+ *Effects:* Direct-non-list-initializes *val* with `std::forward<U>(v)`.
514
+
515
+ *Ensures:* `has_value()` is `true`.
516
+
517
+ *Throws:* Any exception thrown by the initialization of *val*.
518
+
519
+ ``` cpp
520
+ template<class G>
521
+ constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);
522
+ template<class G>
523
+ constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);
524
+ ```
525
+
526
+ Let `GF` be `const G&` for the first overload and `G` for the second
527
+ overload.
528
+
529
+ *Constraints:* `is_constructible_v<E, GF>` is `true`.
530
+
531
+ *Effects:* Direct-non-list-initializes *unex* with
532
+ `std::forward<GF>(e.error())`.
533
+
534
+ *Ensures:* `has_value()` is `false`.
535
+
536
+ *Throws:* Any exception thrown by the initialization of *unex*.
537
+
538
+ ``` cpp
539
+ template<class... Args>
540
+ constexpr explicit expected(in_place_t, Args&&... args);
541
+ ```
542
+
543
+ *Constraints:* `is_constructible_v<T, Args...>` is `true`.
544
+
545
+ *Effects:* Direct-non-list-initializes *val* with
546
+ `std::forward<Args>(args)...`.
547
+
548
+ *Ensures:* `has_value()` is `true`.
549
+
550
+ *Throws:* Any exception thrown by the initialization of *val*.
551
+
552
+ ``` cpp
553
+ template<class U, class... Args>
554
+ constexpr explicit expected(in_place_t, initializer_list<U> il, Args&&... args);
555
+ ```
556
+
557
+ *Constraints:* `is_constructible_v<T, initializer_list<U>&, Args...>` is
558
+ `true`.
559
+
560
+ *Effects:* Direct-non-list-initializes *val* with
561
+ `il, std::forward<Args>(args)...`.
562
+
563
+ *Ensures:* `has_value()` is `true`.
564
+
565
+ *Throws:* Any exception thrown by the initialization of *val*.
566
+
567
+ ``` cpp
568
+ template<class... Args>
569
+ constexpr explicit expected(unexpect_t, Args&&... args);
570
+ ```
571
+
572
+ *Constraints:* `is_constructible_v<E, Args...>` is `true`.
573
+
574
+ *Effects:* Direct-non-list-initializes *unex* with
575
+ `std::forward<Args>(args)...`.
576
+
577
+ *Ensures:* `has_value()` is `false`.
578
+
579
+ *Throws:* Any exception thrown by the initialization of *unex*.
580
+
581
+ ``` cpp
582
+ template<class U, class... Args>
583
+ constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
584
+ ```
585
+
586
+ *Constraints:* `is_constructible_v<E, initializer_list<U>&, Args...>` is
587
+ `true`.
588
+
589
+ *Effects:* Direct-non-list-initializes *unex* with
590
+ `il, std::forward<Args>(args)...`.
591
+
592
+ *Ensures:* `has_value()` is `false`.
593
+
594
+ *Throws:* Any exception thrown by the initialization of *unex*.
595
+
596
+ #### Destructor <a id="expected.object.dtor">[[expected.object.dtor]]</a>
597
+
598
+ ``` cpp
599
+ constexpr ~expected();
600
+ ```
601
+
602
+ *Effects:* If `has_value()` is `true`, destroys *val*, otherwise
603
+ destroys *unex*.
604
+
605
+ *Remarks:* If `is_trivially_destructible_v<T>` is `true`, and
606
+ `is_trivially_destructible_v<E>` is `true`, then this destructor is a
607
+ trivial destructor.
608
+
609
+ #### Assignment <a id="expected.object.assign">[[expected.object.assign]]</a>
610
+
611
+ This subclause makes use of the following exposition-only function:
612
+
613
+ ``` cpp
614
+ template<class T, class U, class... Args>
615
+ constexpr void reinit-expected(T& newval, U& oldval, Args&&... args) { // exposition only
616
+ if constexpr (is_nothrow_constructible_v<T, Args...>) {
617
+ destroy_at(addressof(oldval));
618
+ construct_at(addressof(newval), std::forward<Args>(args)...);
619
+ } else if constexpr (is_nothrow_move_constructible_v<T>) {
620
+ T tmp(std::forward<Args>(args)...);
621
+ destroy_at(addressof(oldval));
622
+ construct_at(addressof(newval), std::move(tmp));
623
+ } else {
624
+ U tmp(std::move(oldval));
625
+ destroy_at(addressof(oldval));
626
+ try {
627
+ construct_at(addressof(newval), std::forward<Args>(args)...);
628
+ } catch (...) {
629
+ construct_at(addressof(oldval), std::move(tmp));
630
+ throw;
631
+ }
632
+ }
633
+ }
634
+ ```
635
+
636
+ ``` cpp
637
+ constexpr expected& operator=(const expected& rhs);
638
+ ```
639
+
640
+ *Effects:*
641
+
642
+ - If `this->has_value() && rhs.has_value()` is `true`, equivalent to
643
+ *`val`*` = *rhs`.
644
+ - Otherwise, if `this->has_value()` is `true`, equivalent to:
645
+ ``` cpp
646
+ reinit-expected(unex, val, rhs.error())
647
+ ```
648
+ - Otherwise, if `rhs.has_value()` is `true`, equivalent to:
649
+ ``` cpp
650
+ reinit-expected(val, unex, *rhs)
651
+ ```
652
+ - Otherwise, equivalent to *`unex`*` = rhs.error()`.
653
+
654
+ Then, if no exception was thrown, equivalent to:
655
+ *`has_val`*` = rhs.has_value(); return *this;`
656
+
657
+ *Returns:* `*this`.
658
+
659
+ *Remarks:* This operator is defined as deleted unless:
660
+
661
+ - `is_copy_assignable_v<T>` is `true` and
662
+ - `is_copy_constructible_v<T>` is `true` and
663
+ - `is_copy_assignable_v<E>` is `true` and
664
+ - `is_copy_constructible_v<E>` is `true` and
665
+ - `is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>`
666
+ is `true`.
667
+
668
+ ``` cpp
669
+ constexpr expected& operator=(expected&& rhs) noexcept(see below);
670
+ ```
671
+
672
+ *Constraints:*
673
+
674
+ - `is_move_constructible_v<T>` is `true` and
675
+ - `is_move_assignable_v<T>` is `true` and
676
+ - `is_move_constructible_v<E>` is `true` and
677
+ - `is_move_assignable_v<E>` is `true` and
678
+ - `is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>`
679
+ is `true`.
680
+
681
+ *Effects:*
682
+
683
+ - If `this->has_value() && rhs.has_value()` is `true`, equivalent to
684
+ *`val`*` = std::move(*rhs)`.
685
+ - Otherwise, if `this->has_value()` is `true`, equivalent to:
686
+ ``` cpp
687
+ reinit-expected(unex, val, std::move(rhs.error()))
688
+ ```
689
+ - Otherwise, if `rhs.has_value()` is `true`, equivalent to:
690
+ ``` cpp
691
+ reinit-expected(val, unex, std::move(*rhs))
692
+ ```
693
+ - Otherwise, equivalent to *`unex`*` = std::move(rhs.error())`.
694
+
695
+ Then, if no exception was thrown, equivalent to:
696
+ `has_val = rhs.has_value(); return *this;`
697
+
698
+ *Returns:* `*this`.
699
+
700
+ *Remarks:* The exception specification is equivalent to:
701
+
702
+ ``` cpp
703
+ is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> &&
704
+ is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>
705
+ ```
706
+
707
+ ``` cpp
708
+ template<class U = T>
709
+ constexpr expected& operator=(U&& v);
710
+ ```
711
+
712
+ *Constraints:*
713
+
714
+ - `is_same_v<expected, remove_cvref_t<U>>` is `false`; and
715
+ - `remove_cvref_t<U>` is not a specialization of `unexpected`; and
716
+ - `is_constructible_v<T, U>` is `true`; and
717
+ - `is_assignable_v<T&, U>` is `true`; and
718
+ - `is_nothrow_constructible_v<T, U> || is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>`
719
+ is `true`.
720
+
721
+ *Effects:*
722
+
723
+ - If `has_value()` is `true`, equivalent to:
724
+ *`val`*` = std::forward<U>(v);`
725
+ - Otherwise, equivalent to:
726
+ ``` cpp
727
+ reinit-expected(val, unex, std::forward<U>(v));
728
+ has_val = true;
729
+ ```
730
+
731
+ *Returns:* `*this`.
732
+
733
+ ``` cpp
734
+ template<class G>
735
+ constexpr expected& operator=(const unexpected<G>& e);
736
+ template<class G>
737
+ constexpr expected& operator=(unexpected<G>&& e);
738
+ ```
739
+
740
+ Let `GF` be `const G&` for the first overload and `G` for the second
741
+ overload.
742
+
743
+ *Constraints:*
744
+
745
+ - `is_constructible_v<E, GF>` is `true`; and
746
+ - `is_assignable_v<E&, GF>` is `true`; and
747
+ - `is_nothrow_constructible_v<E, GF> || is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>`
748
+ is `true`.
749
+
750
+ *Effects:*
751
+
752
+ - If `has_value()` is `true`, equivalent to:
753
+ ``` cpp
754
+ reinit-expected(unex, val, std::forward<GF>(e.error()));
755
+ has_val = false;
756
+ ```
757
+ - Otherwise, equivalent to: *`unex`*` = std::forward<GF>(e.error());`
758
+
759
+ *Returns:* `*this`.
760
+
761
+ ``` cpp
762
+ template<class... Args>
763
+ constexpr T& emplace(Args&&... args) noexcept;
764
+ ```
765
+
766
+ *Constraints:* `is_nothrow_constructible_v<T, Args...>` is `true`.
767
+
768
+ *Effects:* Equivalent to:
769
+
770
+ ``` cpp
771
+ if (has_value()) {
772
+ destroy_at(addressof(val));
773
+ } else {
774
+ destroy_at(addressof(unex));
775
+ has_val = true;
776
+ }
777
+ return *construct_at(addressof(val), std::forward<Args>(args)...);
778
+ ```
779
+
780
+ ``` cpp
781
+ template<class U, class... Args>
782
+ constexpr T& emplace(initializer_list<U> il, Args&&... args) noexcept;
783
+ ```
784
+
785
+ *Constraints:*
786
+ `is_nothrow_constructible_v<T, initializer_list<U>&, Args...>` is
787
+ `true`.
788
+
789
+ *Effects:* Equivalent to:
790
+
791
+ ``` cpp
792
+ if (has_value()) {
793
+ destroy_at(addressof(val));
794
+ } else {
795
+ destroy_at(addressof(unex));
796
+ has_val = true;
797
+ }
798
+ return *construct_at(addressof(val), il, std::forward<Args>(args)...);
799
+ ```
800
+
801
+ #### Swap <a id="expected.object.swap">[[expected.object.swap]]</a>
802
+
803
+ ``` cpp
804
+ constexpr void swap(expected& rhs) noexcept(see below);
805
+ ```
806
+
807
+ *Constraints:*
808
+
809
+ - `is_swappable_v<T>` is `true` and
810
+ - `is_swappable_v<E>` is `true` and
811
+ - `is_move_constructible_v<T> && is_move_constructible_v<E>` is `true`,
812
+ and
813
+ - `is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>`
814
+ is `true`.
815
+
816
+ *Effects:* See [[expected.object.swap]].
817
+
818
+ **Table: `swap(expected&)` effects** <a id="expected.object.swap">[expected.object.swap]</a>
819
+
820
+ | \topline | `this->has_value()` | `!this->has_value()` |
821
+ | -------- | ------------------- | -------------------- |
822
+
823
+
824
+ For the case where `rhs.value()` is `false` and `this->has_value()` is
825
+ `true`, equivalent to:
826
+
827
+ ``` cpp
828
+ if constexpr (is_nothrow_move_constructible_v<E>) {
829
+ E tmp(std::move(rhs.unex));
830
+ destroy_at(addressof(rhs.unex));
831
+ try {
832
+ construct_at(addressof(rhs.val), std::move(val));
833
+ destroy_at(addressof(val));
834
+ construct_at(addressof(unex), std::move(tmp));
835
+ } catch(...) {
836
+ construct_at(addressof(rhs.unex), std::move(tmp));
837
+ throw;
838
+ }
839
+ } else {
840
+ T tmp(std::move(val));
841
+ destroy_at(addressof(val));
842
+ try {
843
+ construct_at(addressof(unex), std::move(rhs.unex));
844
+ destroy_at(addressof(rhs.unex));
845
+ construct_at(addressof(rhs.val), std::move(tmp));
846
+ } catch (...) {
847
+ construct_at(addressof(val), std::move(tmp));
848
+ throw;
849
+ }
850
+ }
851
+ has_val = false;
852
+ rhs.has_val = true;
853
+ ```
854
+
855
+ *Throws:* Any exception thrown by the expressions in the *Effects*.
856
+
857
+ *Remarks:* The exception specification is equivalent to:
858
+
859
+ ``` cpp
860
+ is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T> &&
861
+ is_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>
862
+ ```
863
+
864
+ ``` cpp
865
+ friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
866
+ ```
867
+
868
+ *Effects:* Equivalent to `x.swap(y)`.
869
+
870
+ #### Observers <a id="expected.object.obs">[[expected.object.obs]]</a>
871
+
872
+ ``` cpp
873
+ constexpr const T* operator->() const noexcept;
874
+ constexpr T* operator->() noexcept;
875
+ ```
876
+
877
+ *Preconditions:* `has_value()` is `true`.
878
+
879
+ *Returns:* `addressof(`*`val`*`)`.
880
+
881
+ ``` cpp
882
+ constexpr const T& operator*() const & noexcept;
883
+ constexpr T& operator*() & noexcept;
884
+ ```
885
+
886
+ *Preconditions:* `has_value()` is `true`.
887
+
888
+ *Returns:* *val*.
889
+
890
+ ``` cpp
891
+ constexpr T&& operator*() && noexcept;
892
+ constexpr const T&& operator*() const && noexcept;
893
+ ```
894
+
895
+ *Preconditions:* `has_value()` is `true`.
896
+
897
+ *Returns:* `std::move(`*`val`*`)`.
898
+
899
+ ``` cpp
900
+ constexpr explicit operator bool() const noexcept;
901
+ constexpr bool has_value() const noexcept;
902
+ ```
903
+
904
+ *Returns:* *has_val*.
905
+
906
+ ``` cpp
907
+ constexpr const T& value() const &;
908
+ constexpr T& value() &;
909
+ ```
910
+
911
+ *Mandates:* `is_copy_constructible_v<E>` is `true`.
912
+
913
+ *Returns:* *val*, if `has_value()` is `true`.
914
+
915
+ *Throws:* `bad_expected_access(as_const(error()))` if `has_value()` is
916
+ `false`.
917
+
918
+ ``` cpp
919
+ constexpr T&& value() &&;
920
+ constexpr const T&& value() const &&;
921
+ ```
922
+
923
+ *Mandates:* `is_copy_constructible_v<E>` is `true` and
924
+ `is_constructible_v<E, decltype(std::move(error()))>` is `true`.
925
+
926
+ *Returns:* `std::move(`*`val`*`)`, if `has_value()` is `true`.
927
+
928
+ *Throws:* `bad_expected_access(std::move(error()))` if `has_value()` is
929
+ `false`.
930
+
931
+ ``` cpp
932
+ constexpr const E& error() const & noexcept;
933
+ constexpr E& error() & noexcept;
934
+ ```
935
+
936
+ *Preconditions:* `has_value()` is `false`.
937
+
938
+ *Returns:* *unex*.
939
+
940
+ ``` cpp
941
+ constexpr E&& error() && noexcept;
942
+ constexpr const E&& error() const && noexcept;
943
+ ```
944
+
945
+ *Preconditions:* `has_value()` is `false`.
946
+
947
+ *Returns:* `std::move(`*`unex`*`)`.
948
+
949
+ ``` cpp
950
+ template<class U> constexpr T value_or(U&& v) const &;
951
+ ```
952
+
953
+ *Mandates:* `is_copy_constructible_v<T>` is `true` and
954
+ `is_convertible_v<U, T>` is `true`.
955
+
956
+ *Returns:* `has_value() ? **this : static_cast<T>(std::forward<U>(v))`.
957
+
958
+ ``` cpp
959
+ template<class U> constexpr T value_or(U&& v) &&;
960
+ ```
961
+
962
+ *Mandates:* `is_move_constructible_v<T>` is `true` and
963
+ `is_convertible_v<U, T>` is `true`.
964
+
965
+ *Returns:*
966
+ `has_value() ? std::move(**this) : static_cast<T>(std::forward<U>(v))`.
967
+
968
+ ``` cpp
969
+ template<class G = E> constexpr E error_or(G&& e) const &;
970
+ ```
971
+
972
+ *Mandates:* `is_copy_constructible_v<E>` is `true` and
973
+ `is_convertible_v<G, E>` is `true`.
974
+
975
+ *Returns:* `std::forward<G>(e)` if `has_value()` is `true`, `error()`
976
+ otherwise.
977
+
978
+ ``` cpp
979
+ template<class G = E> constexpr E error_or(G&& e) &&;
980
+ ```
981
+
982
+ *Mandates:* `is_move_constructible_v<E>` is `true` and
983
+ `is_convertible_v<G, E>` is `true`.
984
+
985
+ *Returns:* `std::forward<G>(e)` if `has_value()` is `true`,
986
+ `std::move(error())` otherwise.
987
+
988
+ #### Monadic operations <a id="expected.object.monadic">[[expected.object.monadic]]</a>
989
+
990
+ ``` cpp
991
+ template<class F> constexpr auto and_then(F&& f) &;
992
+ template<class F> constexpr auto and_then(F&& f) const &;
993
+ ```
994
+
995
+ Let `U` be `remove_cvref_t<invoke_result_t<F, decltype(value())>>`.
996
+
997
+ *Constraints:* `is_constructible_v<E, decltype(error())>` is `true`.
998
+
999
+ *Mandates:* `U` is a specialization of `expected` and
1000
+ `is_same_v<U::error_type, E>` is `true`.
1001
+
1002
+ *Effects:* Equivalent to:
1003
+
1004
+ ``` cpp
1005
+ if (has_value())
1006
+ return invoke(std::forward<F>(f), value());
1007
+ else
1008
+ return U(unexpect, error());
1009
+ ```
1010
+
1011
+ ``` cpp
1012
+ template<class F> constexpr auto and_then(F&& f) &&;
1013
+ template<class F> constexpr auto and_then(F&& f) const &&;
1014
+ ```
1015
+
1016
+ Let `U` be
1017
+ `remove_cvref_t<invoke_result_t<F, decltype(std::move(value()))>>`.
1018
+
1019
+ *Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
1020
+ `true`.
1021
+
1022
+ *Mandates:* `U` is a specialization of `expected` and
1023
+ `is_same_v<U::error_type, E>` is `true`.
1024
+
1025
+ *Effects:* Equivalent to:
1026
+
1027
+ ``` cpp
1028
+ if (has_value())
1029
+ return invoke(std::forward<F>(f), std::move(value()));
1030
+ else
1031
+ return U(unexpect, std::move(error()));
1032
+ ```
1033
+
1034
+ ``` cpp
1035
+ template<class F> constexpr auto or_else(F&& f) &;
1036
+ template<class F> constexpr auto or_else(F&& f) const &;
1037
+ ```
1038
+
1039
+ Let `G` be `remove_cvref_t<invoke_result_t<F, decltype(error())>>`.
1040
+
1041
+ *Constraints:* `is_constructible_v<T, decltype(value())>` is `true`.
1042
+
1043
+ *Mandates:* `G` is a specialization of `expected` and
1044
+ `is_same_v<G::value_type, T>` is `true`.
1045
+
1046
+ *Effects:* Equivalent to:
1047
+
1048
+ ``` cpp
1049
+ if (has_value())
1050
+ return G(in_place, value());
1051
+ else
1052
+ return invoke(std::forward<F>(f), error());
1053
+ ```
1054
+
1055
+ ``` cpp
1056
+ template<class F> constexpr auto or_else(F&& f) &&;
1057
+ template<class F> constexpr auto or_else(F&& f) const &&;
1058
+ ```
1059
+
1060
+ Let `G` be
1061
+ `remove_cvref_t<invoke_result_t<F, decltype(std::move(error()))>>`.
1062
+
1063
+ *Constraints:* `is_constructible_v<T, decltype(std::move(value()))>` is
1064
+ `true`.
1065
+
1066
+ *Mandates:* `G` is a specialization of `expected` and
1067
+ `is_same_v<G::value_type, T>` is `true`.
1068
+
1069
+ *Effects:* Equivalent to:
1070
+
1071
+ ``` cpp
1072
+ if (has_value())
1073
+ return G(in_place, std::move(value()));
1074
+ else
1075
+ return invoke(std::forward<F>(f), std::move(error()));
1076
+ ```
1077
+
1078
+ ``` cpp
1079
+ template<class F> constexpr auto transform(F&& f) &;
1080
+ template<class F> constexpr auto transform(F&& f) const &;
1081
+ ```
1082
+
1083
+ Let `U` be `remove_cv_t<invoke_result_t<F, decltype(value())>>`.
1084
+
1085
+ *Constraints:* `is_constructible_v<E, decltype(error())>` is `true`.
1086
+
1087
+ *Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
1088
+ is `false`, the declaration
1089
+
1090
+ ``` cpp
1091
+ U u(invoke(std::forward<F>(f), value()));
1092
+ ```
1093
+
1094
+ is well-formed.
1095
+
1096
+ *Effects:*
1097
+
1098
+ - If `has_value()` is `false`, returns
1099
+ `expected<U, E>(unexpect, error())`.
1100
+ - Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
1101
+ object whose *has_val* member is `true` and *val* member is
1102
+ direct-non-list-initialized with
1103
+ `invoke(std::forward<F>(f), value())`.
1104
+ - Otherwise, evaluates `invoke(std::forward<F>(f), value())` and then
1105
+ returns `expected<U, E>()`.
1106
+
1107
+ ``` cpp
1108
+ template<class F> constexpr auto transform(F&& f) &&;
1109
+ template<class F> constexpr auto transform(F&& f) const &&;
1110
+ ```
1111
+
1112
+ Let `U` be
1113
+ `remove_cv_t<invoke_result_t<F, decltype(std::move(value()))>>`.
1114
+
1115
+ *Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
1116
+ `true`.
1117
+
1118
+ *Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
1119
+ is `false`, the declaration
1120
+
1121
+ ``` cpp
1122
+ U u(invoke(std::forward<F>(f), std::move(value())));
1123
+ ```
1124
+
1125
+ is well-formed for some invented variable `u`.
1126
+
1127
+ *Effects:*
1128
+
1129
+ - If `has_value()` is `false`, returns
1130
+ `expected<U, E>(unexpect, std::move(error()))`.
1131
+ - Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
1132
+ object whose *has_val* member is `true` and *val* member is
1133
+ direct-non-list-initialized with
1134
+ `invoke(std::forward<F>(f), std::move(value()))`.
1135
+ - Otherwise, evaluates `invoke(std::forward<F>(f), std::move(value()))`
1136
+ and then returns `expected<U, E>()`.
1137
+
1138
+ ``` cpp
1139
+ template<class F> constexpr auto transform_error(F&& f) &;
1140
+ template<class F> constexpr auto transform_error(F&& f) const &;
1141
+ ```
1142
+
1143
+ Let `G` be `remove_cv_t<invoke_result_t<F, decltype(error())>>`.
1144
+
1145
+ *Constraints:* `is_constructible_v<T, decltype(value())>` is `true`.
1146
+
1147
+ *Mandates:* `G` is a valid template argument for `unexpected`
1148
+ [[expected.un.general]] and the declaration
1149
+
1150
+ ``` cpp
1151
+ G g(invoke(std::forward<F>(f), error()));
1152
+ ```
1153
+
1154
+ is well-formed.
1155
+
1156
+ *Returns:* If `has_value()` is `true`,
1157
+ `expected<T, G>(in_place, value())`; otherwise, an `expected<T, G>`
1158
+ object whose *has_val* member is `false` and *unex* member is
1159
+ direct-non-list-initialized with `invoke(std::forward<F>(f), error())`.
1160
+
1161
+ ``` cpp
1162
+ template<class F> constexpr auto transform_error(F&& f) &&;
1163
+ template<class F> constexpr auto transform_error(F&& f) const &&;
1164
+ ```
1165
+
1166
+ Let `G` be
1167
+ `remove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>`.
1168
+
1169
+ *Constraints:* `is_constructible_v<T, decltype(std::move(value()))>` is
1170
+ `true`.
1171
+
1172
+ *Mandates:* `G` is a valid template argument for `unexpected`
1173
+ [[expected.un.general]] and the declaration
1174
+
1175
+ ``` cpp
1176
+ G g(invoke(std::forward<F>(f), std::move(error())));
1177
+ ```
1178
+
1179
+ is well-formed.
1180
+
1181
+ *Returns:* If `has_value()` is `true`,
1182
+ `expected<T, G>(in_place, std::move(value()))`; otherwise, an
1183
+ `expected<T, G>` object whose *has_val* member is `false` and *unex*
1184
+ member is direct-non-list-initialized with
1185
+ `invoke(std::forward<F>(f), std::move(error()))`.
1186
+
1187
+ #### Equality operators <a id="expected.object.eq">[[expected.object.eq]]</a>
1188
+
1189
+ ``` cpp
1190
+ template<class T2, class E2> requires (!is_void_v<T2>)
1191
+ friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
1192
+ ```
1193
+
1194
+ *Mandates:* The expressions `*x == *y` and `x.error() == y.error()` are
1195
+ well-formed and their results are convertible to `bool`.
1196
+
1197
+ *Returns:* If `x.has_value()` does not equal `y.has_value()`, `false`;
1198
+ otherwise if `x.has_value()` is `true`, `*x == *y`; otherwise
1199
+ `x.error() == y.error()`.
1200
+
1201
+ ``` cpp
1202
+ template<class T2> friend constexpr bool operator==(const expected& x, const T2& v);
1203
+ ```
1204
+
1205
+ *Mandates:* The expression `*x == v` is well-formed and its result is
1206
+ convertible to `bool`.
1207
+
1208
+ [*Note 1*: `T` need not be *Cpp17EqualityComparable*. — *end note*]
1209
+
1210
+ *Returns:* `x.has_value() && static_cast<bool>(*x == v)`.
1211
+
1212
+ ``` cpp
1213
+ template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
1214
+ ```
1215
+
1216
+ *Mandates:* The expression `x.error() == e.error()` is well-formed and
1217
+ its result is convertible to `bool`.
1218
+
1219
+ *Returns:*
1220
+ `!x.has_value() && static_cast<bool>(x.error() == e.error())`.
1221
+
1222
+ ### Partial specialization of `expected` for `void` types <a id="expected.void">[[expected.void]]</a>
1223
+
1224
+ #### General <a id="expected.void.general">[[expected.void.general]]</a>
1225
+
1226
+ ``` cpp
1227
+ template<class T, class E> requires is_void_v<T>
1228
+ class expected<T, E> {
1229
+ public:
1230
+ using value_type = T;
1231
+ using error_type = E;
1232
+ using unexpected_type = unexpected<E>;
1233
+
1234
+ template<class U>
1235
+ using rebind = expected<U, error_type>;
1236
+
1237
+ // [expected.void.cons], constructors
1238
+ constexpr expected() noexcept;
1239
+ constexpr expected(const expected&);
1240
+ constexpr expected(expected&&) noexcept(see below);
1241
+ template<class U, class G>
1242
+ constexpr explicit(see below) expected(const expected<U, G>&);
1243
+ template<class U, class G>
1244
+ constexpr explicit(see below) expected(expected<U, G>&&);
1245
+
1246
+ template<class G>
1247
+ constexpr explicit(see below) expected(const unexpected<G>&);
1248
+ template<class G>
1249
+ constexpr explicit(see below) expected(unexpected<G>&&);
1250
+
1251
+ constexpr explicit expected(in_place_t) noexcept;
1252
+ template<class... Args>
1253
+ constexpr explicit expected(unexpect_t, Args&&...);
1254
+ template<class U, class... Args>
1255
+ constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...);
1256
+
1257
+
1258
+ // [expected.void.dtor], destructor
1259
+ constexpr ~expected();
1260
+
1261
+ // [expected.void.assign], assignment
1262
+ constexpr expected& operator=(const expected&);
1263
+ constexpr expected& operator=(expected&&) noexcept(see below);
1264
+ template<class G>
1265
+ constexpr expected& operator=(const unexpected<G>&);
1266
+ template<class G>
1267
+ constexpr expected& operator=(unexpected<G>&&);
1268
+ constexpr void emplace() noexcept;
1269
+
1270
+ // [expected.void.swap], swap
1271
+ constexpr void swap(expected&) noexcept(see below);
1272
+ friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
1273
+
1274
+ // [expected.void.obs], observers
1275
+ constexpr explicit operator bool() const noexcept;
1276
+ constexpr bool has_value() const noexcept;
1277
+ constexpr void operator*() const noexcept;
1278
+ constexpr void value() const &;
1279
+ constexpr void value() &&;
1280
+ constexpr const E& error() const & noexcept;
1281
+ constexpr E& error() & noexcept;
1282
+ constexpr const E&& error() const && noexcept;
1283
+ constexpr E&& error() && noexcept;
1284
+ template<class G = E> constexpr E error_or(G&&) const &;
1285
+ template<class G = E> constexpr E error_or(G&&) &&;
1286
+
1287
+ // [expected.void.monadic], monadic operations
1288
+ template<class F> constexpr auto and_then(F&& f) &;
1289
+ template<class F> constexpr auto and_then(F&& f) &&;
1290
+ template<class F> constexpr auto and_then(F&& f) const &;
1291
+ template<class F> constexpr auto and_then(F&& f) const &&;
1292
+ template<class F> constexpr auto or_else(F&& f) &;
1293
+ template<class F> constexpr auto or_else(F&& f) &&;
1294
+ template<class F> constexpr auto or_else(F&& f) const &;
1295
+ template<class F> constexpr auto or_else(F&& f) const &&;
1296
+ template<class F> constexpr auto transform(F&& f) &;
1297
+ template<class F> constexpr auto transform(F&& f) &&;
1298
+ template<class F> constexpr auto transform(F&& f) const &;
1299
+ template<class F> constexpr auto transform(F&& f) const &&;
1300
+ template<class F> constexpr auto transform_error(F&& f) &;
1301
+ template<class F> constexpr auto transform_error(F&& f) &&;
1302
+ template<class F> constexpr auto transform_error(F&& f) const &;
1303
+ template<class F> constexpr auto transform_error(F&& f) const &&;
1304
+
1305
+ // [expected.void.eq], equality operators
1306
+ template<class T2, class E2> requires is_void_v<T2>
1307
+ friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
1308
+ template<class E2>
1309
+ friend constexpr bool operator==(const expected&, const unexpected<E2>&);
1310
+
1311
+ private:
1312
+ bool has_val; // exposition only
1313
+ union {
1314
+ E unex; // exposition only
1315
+ };
1316
+ };
1317
+ ```
1318
+
1319
+ Any object of type `expected<T, E>` either represents a value of type
1320
+ `T`, or contains a value of type `E` within its own storage.
1321
+ Implementations are not permitted to use additional storage, such as
1322
+ dynamic memory, to allocate the object of type `E`. Member *`has_val`*
1323
+ indicates whether the `expected<T, E>` object represents a value of type
1324
+ `T`.
1325
+
1326
+ A program that instantiates the definition of the template
1327
+ `expected<T, E>` with a type for the `E` parameter that is not a valid
1328
+ template argument for `unexpected` is ill-formed.
1329
+
1330
+ `E` shall meet the requirements of *Cpp17Destructible* (
1331
+ [[cpp17.destructible]]).
1332
+
1333
+ #### Constructors <a id="expected.void.cons">[[expected.void.cons]]</a>
1334
+
1335
+ ``` cpp
1336
+ constexpr expected() noexcept;
1337
+ ```
1338
+
1339
+ *Ensures:* `has_value()` is `true`.
1340
+
1341
+ ``` cpp
1342
+ constexpr expected(const expected& rhs);
1343
+ ```
1344
+
1345
+ *Effects:* If `rhs.has_value()` is `false`, direct-non-list-initializes
1346
+ *unex* with `rhs.error()`.
1347
+
1348
+ *Ensures:* `rhs.has_value() == this->has_value()`.
1349
+
1350
+ *Throws:* Any exception thrown by the initialization of *unex*.
1351
+
1352
+ *Remarks:* This constructor is defined as deleted unless
1353
+ `is_copy_constructible_v<E>` is `true`.
1354
+
1355
+ This constructor is trivial if `is_trivially_copy_constructible_v<E>` is
1356
+ `true`.
1357
+
1358
+ ``` cpp
1359
+ constexpr expected(expected&& rhs) noexcept(is_nothrow_move_constructible_v<E>);
1360
+ ```
1361
+
1362
+ *Constraints:* `is_move_constructible_v<E>` is `true`.
1363
+
1364
+ *Effects:* If `rhs.has_value()` is `false`, direct-non-list-initializes
1365
+ *unex* with `std::move(rhs.error())`.
1366
+
1367
+ *Ensures:* `rhs.has_value()` is unchanged;
1368
+ `rhs.has_value() == this->has_value()` is `true`.
1369
+
1370
+ *Throws:* Any exception thrown by the initialization of *unex*.
1371
+
1372
+ *Remarks:* This constructor is trivial if
1373
+ `is_trivially_move_constructible_v<E>` is `true`.
1374
+
1375
+ ``` cpp
1376
+ template<class U, class G>
1377
+ constexpr explicit(!is_convertible_v<const G&, E>) expected(const expected<U, G>& rhs);
1378
+ template<class U, class G>
1379
+ constexpr explicit(!is_convertible_v<G, E>) expected(expected<U, G>&& rhs);
1380
+ ```
1381
+
1382
+ Let `GF` be `const G&` for the first overload and `G` for the second
1383
+ overload.
1384
+
1385
+ *Constraints:*
1386
+
1387
+ - `is_void_v<U>` is `true`; and
1388
+ - `is_constructible_v<E, GF>` is `true`; and
1389
+ - `is_constructible_v<unexpected<E>, expected<U, G>&>` is `false`; and
1390
+ - `is_constructible_v<unexpected<E>, expected<U, G>>` is `false`; and
1391
+ - `is_constructible_v<unexpected<E>, const expected<U, G>&>` is `false`;
1392
+ and
1393
+ - `is_constructible_v<unexpected<E>, const expected<U, G>>` is `false`.
1394
+
1395
+ *Effects:* If `rhs.has_value()` is `false`, direct-non-list-initializes
1396
+ *unex* with `std::forward<GF>(rhs.error())`.
1397
+
1398
+ *Ensures:* `rhs.has_value()` is unchanged;
1399
+ `rhs.has_value() == this->has_value()` is `true`.
1400
+
1401
+ *Throws:* Any exception thrown by the initialization of *unex*.
1402
+
1403
+ ``` cpp
1404
+ template<class G>
1405
+ constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);
1406
+ template<class G>
1407
+ constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);
1408
+ ```
1409
+
1410
+ Let `GF` be `const G&` for the first overload and `G` for the second
1411
+ overload.
1412
+
1413
+ *Constraints:* `is_constructible_v<E, GF>` is `true`.
1414
+
1415
+ *Effects:* Direct-non-list-initializes *unex* with
1416
+ `std::forward<GF>(e.error())`.
1417
+
1418
+ *Ensures:* `has_value()` is `false`.
1419
+
1420
+ *Throws:* Any exception thrown by the initialization of *unex*.
1421
+
1422
+ ``` cpp
1423
+ constexpr explicit expected(in_place_t) noexcept;
1424
+ ```
1425
+
1426
+ *Ensures:* `has_value()` is `true`.
1427
+
1428
+ ``` cpp
1429
+ template<class... Args>
1430
+ constexpr explicit expected(unexpect_t, Args&&... args);
1431
+ ```
1432
+
1433
+ *Constraints:* `is_constructible_v<E, Args...>` is `true`.
1434
+
1435
+ *Effects:* Direct-non-list-initializes *unex* with
1436
+ `std::forward<Args>(args)...`.
1437
+
1438
+ *Ensures:* `has_value()` is `false`.
1439
+
1440
+ *Throws:* Any exception thrown by the initialization of *unex*.
1441
+
1442
+ ``` cpp
1443
+ template<class U, class... Args>
1444
+ constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
1445
+ ```
1446
+
1447
+ *Constraints:* `is_constructible_v<E, initializer_list<U>&, Args...>` is
1448
+ `true`.
1449
+
1450
+ *Effects:* Direct-non-list-initializes *unex* with
1451
+ `il, std::forward<Args>(args)...`.
1452
+
1453
+ *Ensures:* `has_value()` is `false`.
1454
+
1455
+ *Throws:* Any exception thrown by the initialization of *unex*.
1456
+
1457
+ #### Destructor <a id="expected.void.dtor">[[expected.void.dtor]]</a>
1458
+
1459
+ ``` cpp
1460
+ constexpr ~expected();
1461
+ ```
1462
+
1463
+ *Effects:* If `has_value()` is `false`, destroys *unex*.
1464
+
1465
+ *Remarks:* If `is_trivially_destructible_v<E>` is `true`, then this
1466
+ destructor is a trivial destructor.
1467
+
1468
+ #### Assignment <a id="expected.void.assign">[[expected.void.assign]]</a>
1469
+
1470
+ ``` cpp
1471
+ constexpr expected& operator=(const expected& rhs);
1472
+ ```
1473
+
1474
+ *Effects:*
1475
+
1476
+ - If `this->has_value() && rhs.has_value()` is `true`, no effects.
1477
+ - Otherwise, if `this->has_value()` is `true`, equivalent to:
1478
+ `construct_at(addressof(`*`unex`*`), rhs.`*`unex`*`); `*`has_val`*` = false;`
1479
+ - Otherwise, if `rhs.has_value()` is `true`, destroys *unex* and sets
1480
+ *has_val* to `true`.
1481
+ - Otherwise, equivalent to *`unex`*` = rhs.error()`.
1482
+
1483
+ *Returns:* `*this`.
1484
+
1485
+ *Remarks:* This operator is defined as deleted unless
1486
+ `is_copy_assignable_v<E>` is `true` and `is_copy_constructible_v<E>` is
1487
+ `true`.
1488
+
1489
+ ``` cpp
1490
+ constexpr expected& operator=(expected&& rhs) noexcept(see below);
1491
+ ```
1492
+
1493
+ *Effects:*
1494
+
1495
+ - If `this->has_value() && rhs.has_value()` is `true`, no effects.
1496
+ - Otherwise, if `this->has_value()` is `true`, equivalent to:
1497
+ ``` cpp
1498
+ construct_at(addressof(unex), std::move(rhs.unex));
1499
+ has_val = false;
1500
+ ```
1501
+ - Otherwise, if `rhs.has_value()` is `true`, destroys *unex* and sets
1502
+ *has_val* to `true`.
1503
+ - Otherwise, equivalent to *`unex`*` = std::move(rhs.error())`.
1504
+
1505
+ *Returns:* `*this`.
1506
+
1507
+ *Remarks:* The exception specification is equivalent to
1508
+ `is_nothrow_move_constructible_v<E> && is_nothrow_move_assignable_v<E>`.
1509
+
1510
+ This operator is defined as deleted unless `is_move_constructible_v<E>`
1511
+ is `true` and `is_move_assignable_v<E>` is `true`.
1512
+
1513
+ ``` cpp
1514
+ template<class G>
1515
+ constexpr expected& operator=(const unexpected<G>& e);
1516
+ template<class G>
1517
+ constexpr expected& operator=(unexpected<G>&& e);
1518
+ ```
1519
+
1520
+ Let `GF` be `const G&` for the first overload and `G` for the second
1521
+ overload.
1522
+
1523
+ *Constraints:* `is_constructible_v<E, GF>` is `true` and
1524
+ `is_assignable_v<E&, GF>` is `true`.
1525
+
1526
+ *Effects:*
1527
+
1528
+ - If `has_value()` is `true`, equivalent to:
1529
+ ``` cpp
1530
+ construct_at(addressof(unex), std::forward<GF>(e.error()));
1531
+ has_val = false;
1532
+ ```
1533
+ - Otherwise, equivalent to: *`unex`*` = std::forward<GF>(e.error());`
1534
+
1535
+ *Returns:* `*this`.
1536
+
1537
+ ``` cpp
1538
+ constexpr void emplace() noexcept;
1539
+ ```
1540
+
1541
+ *Effects:* If `has_value()` is `false`, destroys *unex* and sets
1542
+ *has_val* to `true`.
1543
+
1544
+ #### Swap <a id="expected.void.swap">[[expected.void.swap]]</a>
1545
+
1546
+ ``` cpp
1547
+ constexpr void swap(expected& rhs) noexcept(see below);
1548
+ ```
1549
+
1550
+ *Constraints:* `is_swappable_v<E>` is `true` and
1551
+ `is_move_constructible_v<E>` is `true`.
1552
+
1553
+ *Effects:* See [[expected.void.swap]].
1554
+
1555
+ **Table: `swap(expected&)` effects** <a id="expected.void.swap">[expected.void.swap]</a>
1556
+
1557
+ | \topline | `this->has_value()` | `!this->has_value()` |
1558
+ | -------- | ------------------- | -------------------- |
1559
+
1560
+
1561
+ For the case where `rhs.value()` is `false` and `this->has_value()` is
1562
+ `true`, equivalent to:
1563
+
1564
+ ``` cpp
1565
+ construct_at(addressof(unex), std::move(rhs.unex));
1566
+ destroy_at(addressof(rhs.unex));
1567
+ has_val = false;
1568
+ rhs.has_val = true;
1569
+ ```
1570
+
1571
+ *Throws:* Any exception thrown by the expressions in the *Effects*.
1572
+
1573
+ *Remarks:* The exception specification is equivalent to
1574
+ `is_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>`.
1575
+
1576
+ ``` cpp
1577
+ friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
1578
+ ```
1579
+
1580
+ *Effects:* Equivalent to `x.swap(y)`.
1581
+
1582
+ #### Observers <a id="expected.void.obs">[[expected.void.obs]]</a>
1583
+
1584
+ ``` cpp
1585
+ constexpr explicit operator bool() const noexcept;
1586
+ constexpr bool has_value() const noexcept;
1587
+ ```
1588
+
1589
+ *Returns:* *has_val*.
1590
+
1591
+ ``` cpp
1592
+ constexpr void operator*() const noexcept;
1593
+ ```
1594
+
1595
+ *Preconditions:* `has_value()` is `true`.
1596
+
1597
+ ``` cpp
1598
+ constexpr void value() const &;
1599
+ ```
1600
+
1601
+ *Throws:* `bad_expected_access(error())` if `has_value()` is `false`.
1602
+
1603
+ ``` cpp
1604
+ constexpr void value() &&;
1605
+ ```
1606
+
1607
+ *Throws:* `bad_expected_access(std::move(error()))` if `has_value()` is
1608
+ `false`.
1609
+
1610
+ ``` cpp
1611
+ constexpr const E& error() const & noexcept;
1612
+ constexpr E& error() & noexcept;
1613
+ ```
1614
+
1615
+ *Preconditions:* `has_value()` is `false`.
1616
+
1617
+ *Returns:* *unex*.
1618
+
1619
+ ``` cpp
1620
+ constexpr E&& error() && noexcept;
1621
+ constexpr const E&& error() const && noexcept;
1622
+ ```
1623
+
1624
+ *Preconditions:* `has_value()` is `false`.
1625
+
1626
+ *Returns:* `std::move(`*`unex`*`)`.
1627
+
1628
+ ``` cpp
1629
+ template<class G = E> constexpr E error_or(G&& e) const &;
1630
+ ```
1631
+
1632
+ *Mandates:* `is_copy_constructible_v<E>` is `true` and
1633
+ `is_convertible_v<G, E>` is `true`.
1634
+
1635
+ *Returns:* `std::forward<G>(e)` if `has_value()` is `true`, `error()`
1636
+ otherwise.
1637
+
1638
+ ``` cpp
1639
+ template<class G = E> constexpr E error_or(G&& e) &&;
1640
+ ```
1641
+
1642
+ *Mandates:* `is_move_constructible_v<E>` is `true` and
1643
+ `is_convertible_v<G, E>` is `true`.
1644
+
1645
+ *Returns:* `std::forward<G>(e)` if `has_value()` is `true`,
1646
+ `std::move(error())` otherwise.
1647
+
1648
+ #### Monadic operations <a id="expected.void.monadic">[[expected.void.monadic]]</a>
1649
+
1650
+ ``` cpp
1651
+ template<class F> constexpr auto and_then(F&& f) &;
1652
+ template<class F> constexpr auto and_then(F&& f) const &;
1653
+ ```
1654
+
1655
+ Let `U` be `remove_cvref_t<invoke_result_t<F>>`.
1656
+
1657
+ *Constraints:* `is_constructible_v<E, decltype(error())>>` is `true`.
1658
+
1659
+ *Mandates:* `U` is a specialization of `expected` and
1660
+ `is_same_v<U::error_type, E>` is `true`.
1661
+
1662
+ *Effects:* Equivalent to:
1663
+
1664
+ ``` cpp
1665
+ if (has_value())
1666
+ return invoke(std::forward<F>(f));
1667
+ else
1668
+ return U(unexpect, error());
1669
+ ```
1670
+
1671
+ ``` cpp
1672
+ template<class F> constexpr auto and_then(F&& f) &&;
1673
+ template<class F> constexpr auto and_then(F&& f) const &&;
1674
+ ```
1675
+
1676
+ Let `U` be `remove_cvref_t<invoke_result_t<F>>`.
1677
+
1678
+ *Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
1679
+ `true`.
1680
+
1681
+ *Mandates:* `U` is a specialization of `expected` and
1682
+ `is_same_v<U::error_type, E>` is `true`.
1683
+
1684
+ *Effects:* Equivalent to:
1685
+
1686
+ ``` cpp
1687
+ if (has_value())
1688
+ return invoke(std::forward<F>(f));
1689
+ else
1690
+ return U(unexpect, std::move(error()));
1691
+ ```
1692
+
1693
+ ``` cpp
1694
+ template<class F> constexpr auto or_else(F&& f) &;
1695
+ template<class F> constexpr auto or_else(F&& f) const &;
1696
+ ```
1697
+
1698
+ Let `G` be `remove_cvref_t<invoke_result_t<F, decltype(error())>>`.
1699
+
1700
+ *Mandates:* `G` is a specialization of `expected` and
1701
+ `is_same_v<G::value_type, T>` is `true`.
1702
+
1703
+ *Effects:* Equivalent to:
1704
+
1705
+ ``` cpp
1706
+ if (has_value())
1707
+ return G();
1708
+ else
1709
+ return invoke(std::forward<F>(f), error());
1710
+ ```
1711
+
1712
+ ``` cpp
1713
+ template<class F> constexpr auto or_else(F&& f) &&;
1714
+ template<class F> constexpr auto or_else(F&& f) const &&;
1715
+ ```
1716
+
1717
+ Let `G` be
1718
+ `remove_cvref_t<invoke_result_t<F, decltype(std::move(error()))>>`.
1719
+
1720
+ *Mandates:* `G` is a specialization of `expected` and
1721
+ `is_same_v<G::value_type, T>` is `true`.
1722
+
1723
+ *Effects:* Equivalent to:
1724
+
1725
+ ``` cpp
1726
+ if (has_value())
1727
+ return G();
1728
+ else
1729
+ return invoke(std::forward<F>(f), std::move(error()));
1730
+ ```
1731
+
1732
+ ``` cpp
1733
+ template<class F> constexpr auto transform(F&& f) &;
1734
+ template<class F> constexpr auto transform(F&& f) const &;
1735
+ ```
1736
+
1737
+ Let `U` be `remove_cv_t<invoke_result_t<F>>`.
1738
+
1739
+ *Constraints:* `is_constructible_v<E, decltype(error())>` is `true`.
1740
+
1741
+ *Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
1742
+ is `false`, the declaration
1743
+
1744
+ ``` cpp
1745
+ U u(invoke(std::forward<F>(f)));
1746
+ ```
1747
+
1748
+ is well-formed.
1749
+
1750
+ *Effects:*
1751
+
1752
+ - If `has_value()` is `false`, returns
1753
+ `expected<U, E>(unexpect, error())`.
1754
+ - Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
1755
+ object whose *has_val* member is `true` and *val* member is
1756
+ direct-non-list-initialized with `invoke(std::forward<F>(f))`.
1757
+ - Otherwise, evaluates `invoke(std::forward<F>(f))` and then returns
1758
+ `expected<U, E>()`.
1759
+
1760
+ ``` cpp
1761
+ template<class F> constexpr auto transform(F&& f) &&;
1762
+ template<class F> constexpr auto transform(F&& f) const &&;
1763
+ ```
1764
+
1765
+ Let `U` be `remove_cv_t<invoke_result_t<F>>`.
1766
+
1767
+ *Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
1768
+ `true`.
1769
+
1770
+ *Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
1771
+ is `false`, the declaration
1772
+
1773
+ ``` cpp
1774
+ U u(invoke(std::forward<F>(f)));
1775
+ ```
1776
+
1777
+ is well-formed.
1778
+
1779
+ *Effects:*
1780
+
1781
+ - If `has_value()` is `false`, returns
1782
+ `expected<U, E>(unexpect, std::move(error()))`.
1783
+ - Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
1784
+ object whose *has_val* member is `true` and *val* member is
1785
+ direct-non-list-initialized with `invoke(std::forward<F>(f))`.
1786
+ - Otherwise, evaluates `invoke(std::forward<F>(f))` and then returns
1787
+ `expected<U, E>()`.
1788
+
1789
+ ``` cpp
1790
+ template<class F> constexpr auto transform_error(F&& f) &;
1791
+ template<class F> constexpr auto transform_error(F&& f) const &;
1792
+ ```
1793
+
1794
+ Let `G` be `remove_cv_t<invoke_result_t<F, decltype(error())>>`.
1795
+
1796
+ *Mandates:* `G` is a valid template argument for `unexpected`
1797
+ [[expected.un.general]] and the declaration
1798
+
1799
+ ``` cpp
1800
+ G g(invoke(std::forward<F>(f), error()));
1801
+ ```
1802
+
1803
+ is well-formed.
1804
+
1805
+ *Returns:* If `has_value()` is `true`, `expected<T, G>()`; otherwise, an
1806
+ `expected<T, G>` object whose *has_val* member is `false` and *unex*
1807
+ member is direct-non-list-initialized with
1808
+ `invoke(std::forward<F>(f), error())`.
1809
+
1810
+ ``` cpp
1811
+ template<class F> constexpr auto transform_error(F&& f) &&;
1812
+ template<class F> constexpr auto transform_error(F&& f) const &&;
1813
+ ```
1814
+
1815
+ Let `G` be
1816
+ `remove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>`.
1817
+
1818
+ *Mandates:* `G` is a valid template argument for `unexpected`
1819
+ [[expected.un.general]] and the declaration
1820
+
1821
+ ``` cpp
1822
+ G g(invoke(std::forward<F>(f), std::move(error())));
1823
+ ```
1824
+
1825
+ is well-formed.
1826
+
1827
+ *Returns:* If `has_value()` is `true`, `expected<T, G>()`; otherwise, an
1828
+ `expected<T, G>` object whose *has_val* member is `false` and *unex*
1829
+ member is direct-non-list-initialized with
1830
+ `invoke(std::forward<F>(f), std::move(error()))`.
1831
+
1832
+ #### Equality operators <a id="expected.void.eq">[[expected.void.eq]]</a>
1833
+
1834
+ ``` cpp
1835
+ template<class T2, class E2> requires is_void_v<T2>
1836
+ friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
1837
+ ```
1838
+
1839
+ *Mandates:* The expression `x.error() == y.error()` is well-formed and
1840
+ its result is convertible to `bool`.
1841
+
1842
+ *Returns:* If `x.has_value()` does not equal `y.has_value()`, `false`;
1843
+ otherwise `x.has_value() || static_cast<bool>(x.error() == y.error())`.
1844
+
1845
+ ``` cpp
1846
+ template<class E2>
1847
+ friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
1848
+ ```
1849
+
1850
+ *Mandates:* The expression `x.error() == e.error()` is well-formed and
1851
+ its result is convertible to `bool`.
1852
+
1853
+ *Returns:*
1854
+ `!x.has_value() && static_cast<bool>(x.error() == e.error())`.
1855
+