From Jason Turner

[expected.expected]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpr_hly5j3/{from.md → to.md} +968 -0
tmp/tmpr_hly5j3/{from.md → to.md} RENAMED
@@ -0,0 +1,968 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Class template `expected` <a id="expected.expected">[[expected.expected]]</a>
2
+
3
+ #### General <a id="expected.object.general">[[expected.object.general]]</a>
4
+
5
+ ``` cpp
6
+ namespace std {
7
+ template<class T, class E>
8
+ class expected {
9
+ public:
10
+ using value_type = T;
11
+ using error_type = E;
12
+ using unexpected_type = unexpected<E>;
13
+
14
+ template<class U>
15
+ using rebind = expected<U, error_type>;
16
+
17
+ // [expected.object.cons], constructors
18
+ constexpr expected();
19
+ constexpr expected(const expected&);
20
+ constexpr expected(expected&&) noexcept(see below);
21
+ template<class U, class G>
22
+ constexpr explicit(see below) expected(const expected<U, G>&);
23
+ template<class U, class G>
24
+ constexpr explicit(see below) expected(expected<U, G>&&);
25
+
26
+ template<class U = T>
27
+ constexpr explicit(see below) expected(U&& v);
28
+
29
+ template<class G>
30
+ constexpr explicit(see below) expected(const unexpected<G>&);
31
+ template<class G>
32
+ constexpr explicit(see below) expected(unexpected<G>&&);
33
+
34
+ template<class... Args>
35
+ constexpr explicit expected(in_place_t, Args&&...);
36
+ template<class U, class... Args>
37
+ constexpr explicit expected(in_place_t, initializer_list<U>, Args&&...);
38
+ template<class... Args>
39
+ constexpr explicit expected(unexpect_t, Args&&...);
40
+ template<class U, class... Args>
41
+ constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...);
42
+
43
+ // [expected.object.dtor], destructor
44
+ constexpr ~expected();
45
+
46
+ // [expected.object.assign], assignment
47
+ constexpr expected& operator=(const expected&);
48
+ constexpr expected& operator=(expected&&) noexcept(see below);
49
+ template<class U = T> constexpr expected& operator=(U&&);
50
+ template<class G>
51
+ constexpr expected& operator=(const unexpected<G>&);
52
+ template<class G>
53
+ constexpr expected& operator=(unexpected<G>&&);
54
+
55
+ template<class... Args>
56
+ constexpr T& emplace(Args&&...) noexcept;
57
+ template<class U, class... Args>
58
+ constexpr T& emplace(initializer_list<U>, Args&&...) noexcept;
59
+
60
+ // [expected.object.swap], swap
61
+ constexpr void swap(expected&) noexcept(see below);
62
+ friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
63
+
64
+ // [expected.object.obs], observers
65
+ constexpr const T* operator->() const noexcept;
66
+ constexpr T* operator->() noexcept;
67
+ constexpr const T& operator*() const & noexcept;
68
+ constexpr T& operator*() & noexcept;
69
+ constexpr const T&& operator*() const && noexcept;
70
+ constexpr T&& operator*() && noexcept;
71
+ constexpr explicit operator bool() const noexcept;
72
+ constexpr bool has_value() const noexcept;
73
+ constexpr const T& value() const &;
74
+ constexpr T& value() &;
75
+ constexpr const T&& value() const &&;
76
+ constexpr T&& value() &&;
77
+ constexpr const E& error() const & noexcept;
78
+ constexpr E& error() & noexcept;
79
+ constexpr const E&& error() const && noexcept;
80
+ constexpr E&& error() && noexcept;
81
+ template<class U> constexpr T value_or(U&&) const &;
82
+ template<class U> constexpr T value_or(U&&) &&;
83
+ template<class G = E> constexpr E error_or(G&&) const &;
84
+ template<class G = E> constexpr E error_or(G&&) &&;
85
+
86
+ // [expected.object.monadic], monadic operations
87
+ template<class F> constexpr auto and_then(F&& f) &;
88
+ template<class F> constexpr auto and_then(F&& f) &&;
89
+ template<class F> constexpr auto and_then(F&& f) const &;
90
+ template<class F> constexpr auto and_then(F&& f) const &&;
91
+ template<class F> constexpr auto or_else(F&& f) &;
92
+ template<class F> constexpr auto or_else(F&& f) &&;
93
+ template<class F> constexpr auto or_else(F&& f) const &;
94
+ template<class F> constexpr auto or_else(F&& f) const &&;
95
+ template<class F> constexpr auto transform(F&& f) &;
96
+ template<class F> constexpr auto transform(F&& f) &&;
97
+ template<class F> constexpr auto transform(F&& f) const &;
98
+ template<class F> constexpr auto transform(F&& f) const &&;
99
+ template<class F> constexpr auto transform_error(F&& f) &;
100
+ template<class F> constexpr auto transform_error(F&& f) &&;
101
+ template<class F> constexpr auto transform_error(F&& f) const &;
102
+ template<class F> constexpr auto transform_error(F&& f) const &&;
103
+
104
+ // [expected.object.eq], equality operators
105
+ template<class T2, class E2> requires (!is_void_v<T2>)
106
+ friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
107
+ template<class T2>
108
+ friend constexpr bool operator==(const expected&, const T2&);
109
+ template<class E2>
110
+ friend constexpr bool operator==(const expected&, const unexpected<E2>&);
111
+
112
+ private:
113
+ bool has_val; // exposition only
114
+ union {
115
+ T val; // exposition only
116
+ E unex; // exposition only
117
+ };
118
+ };
119
+ }
120
+ ```
121
+
122
+ Any object of type `expected<T, E>` either contains a value of type `T`
123
+ or a value of type `E` within its own storage. Implementations are not
124
+ permitted to use additional storage, such as dynamic memory, to allocate
125
+ the object of type `T` or the object of type `E`. Member *`has_val`*
126
+ indicates whether the `expected<T, E>` object contains an object of type
127
+ `T`.
128
+
129
+ A type `T` is a *valid value type for `expected`*, if `remove_cv_t<T>`
130
+ is `void` or a complete non-array object type that is not `in_place_t`,
131
+ `unexpect_t`, or a specialization of `unexpected`. A program which
132
+ instantiates class template `expected<T, E>` with an argument `T` that
133
+ is not a valid value type for `expected` is ill-formed. A program that
134
+ instantiates the definition of the template `expected<T, E>` with a type
135
+ for the `E` parameter that is not a valid template argument for
136
+ `unexpected` is ill-formed.
137
+
138
+ When `T` is not cv `void`, it shall meet the *Cpp17Destructible*
139
+ requirements ([[cpp17.destructible]]). `E` shall meet the
140
+ *Cpp17Destructible* requirements.
141
+
142
+ #### Constructors <a id="expected.object.cons">[[expected.object.cons]]</a>
143
+
144
+ The exposition-only variable template *`converts-from-any-cvref`*
145
+ defined in [[optional.ctor]] is used by some constructors for
146
+ `expected`.
147
+
148
+ ``` cpp
149
+ constexpr expected();
150
+ ```
151
+
152
+ *Constraints:* `is_default_constructible_v<T>` is `true`.
153
+
154
+ *Effects:* Value-initializes *val*.
155
+
156
+ *Ensures:* `has_value()` is `true`.
157
+
158
+ *Throws:* Any exception thrown by the initialization of *val*.
159
+
160
+ ``` cpp
161
+ constexpr expected(const expected& rhs);
162
+ ```
163
+
164
+ *Effects:* If `rhs.has_value()` is `true`, direct-non-list-initializes
165
+ *val* with `*rhs`. Otherwise, direct-non-list-initializes *unex* with
166
+ `rhs.error()`.
167
+
168
+ *Ensures:* `rhs.has_value() == this->has_value()`.
169
+
170
+ *Throws:* Any exception thrown by the initialization of *val* or *unex*.
171
+
172
+ *Remarks:* This constructor is defined as deleted unless
173
+
174
+ - `is_copy_constructible_v<T>` is `true` and
175
+ - `is_copy_constructible_v<E>` is `true`.
176
+
177
+ This constructor is trivial if
178
+
179
+ - `is_trivially_copy_constructible_v<T>` is `true` and
180
+ - `is_trivially_copy_constructible_v<E>` is `true`.
181
+
182
+ ``` cpp
183
+ constexpr expected(expected&& rhs) noexcept(see below);
184
+ ```
185
+
186
+ *Constraints:*
187
+
188
+ - `is_move_constructible_v<T>` is `true` and
189
+ - `is_move_constructible_v<E>` is `true`.
190
+
191
+ *Effects:* If `rhs.has_value()` is `true`, direct-non-list-initializes
192
+ *val* with `std::move(*rhs)`. Otherwise, direct-non-list-initializes
193
+ *unex* with `std::move(rhs.error())`.
194
+
195
+ *Ensures:* `rhs.has_value()` is unchanged;
196
+ `rhs.has_value() == this->has_value()` is `true`.
197
+
198
+ *Throws:* Any exception thrown by the initialization of *val* or *unex*.
199
+
200
+ *Remarks:* The exception specification is equivalent to
201
+ `is_nothrow_move_constructible_v<T> && is_nothrow_move_constructible_v<E>`.
202
+
203
+ This constructor is trivial if
204
+
205
+ - `is_trivially_move_constructible_v<T>` is `true` and
206
+ - `is_trivially_move_constructible_v<E>` is `true`.
207
+
208
+ ``` cpp
209
+ template<class U, class G>
210
+ constexpr explicit(see below) expected(const expected<U, G>& rhs);
211
+ template<class U, class G>
212
+ constexpr explicit(see below) expected(expected<U, G>&& rhs);
213
+ ```
214
+
215
+ Let:
216
+
217
+ - `UF` be `const U&` for the first overload and `U` for the second
218
+ overload.
219
+ - `GF` be `const G&` for the first overload and `G` for the second
220
+ overload.
221
+
222
+ *Constraints:*
223
+
224
+ - `is_constructible_v<T, UF>` is `true`; and
225
+ - `is_constructible_v<E, GF>` is `true`; and
226
+ - if `T` is not cv `bool`,
227
+ *`converts-from-any-cvref`*`<T, expected<U, G>>` is `false`; and
228
+ - `is_constructible_v<unexpected<E>, expected<U, G>&>` is `false`; and
229
+ - `is_constructible_v<unexpected<E>, expected<U, G>>` is `false`; and
230
+ - `is_constructible_v<unexpected<E>, const expected<U, G>&>` is `false`;
231
+ and
232
+ - `is_constructible_v<unexpected<E>, const expected<U, G>>` is `false`.
233
+
234
+ *Effects:* If `rhs.has_value()`, direct-non-list-initializes *val* with
235
+ `std::forward<UF>(*rhs)`. Otherwise, direct-non-list-initializes *unex*
236
+ with `std::forward<GF>(rhs.error())`.
237
+
238
+ *Ensures:* `rhs.has_value()` is unchanged;
239
+ `rhs.has_value() == this->has_value()` is `true`.
240
+
241
+ *Throws:* Any exception thrown by the initialization of *val* or *unex*.
242
+
243
+ *Remarks:* The expression inside `explicit` is equivalent to
244
+ `!is_convertible_v<UF, T> || !is_convertible_v<GF, E>`.
245
+
246
+ ``` cpp
247
+ template<class U = T>
248
+ constexpr explicit(!is_convertible_v<U, T>) expected(U&& v);
249
+ ```
250
+
251
+ *Constraints:*
252
+
253
+ - `is_same_v<remove_cvref_t<U>, in_place_t>` is `false`; and
254
+ - `is_same_v<expected, remove_cvref_t<U>>` is `false`; and
255
+ - `remove_cvref_t<U>` is not a specialization of `unexpected`; and
256
+ - `is_constructible_v<T, U>` is `true`; and
257
+ - if `T` is cv `bool`, `remove_cvref_t<U>` is not a specialization of
258
+ `expected`.
259
+
260
+ *Effects:* Direct-non-list-initializes *val* with `std::forward<U>(v)`.
261
+
262
+ *Ensures:* `has_value()` is `true`.
263
+
264
+ *Throws:* Any exception thrown by the initialization of *val*.
265
+
266
+ ``` cpp
267
+ template<class G>
268
+ constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);
269
+ template<class G>
270
+ constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);
271
+ ```
272
+
273
+ Let `GF` be `const G&` for the first overload and `G` for the second
274
+ overload.
275
+
276
+ *Constraints:* `is_constructible_v<E, GF>` is `true`.
277
+
278
+ *Effects:* Direct-non-list-initializes *unex* with
279
+ `std::forward<GF>(e.error())`.
280
+
281
+ *Ensures:* `has_value()` is `false`.
282
+
283
+ *Throws:* Any exception thrown by the initialization of *unex*.
284
+
285
+ ``` cpp
286
+ template<class... Args>
287
+ constexpr explicit expected(in_place_t, Args&&... args);
288
+ ```
289
+
290
+ *Constraints:* `is_constructible_v<T, Args...>` is `true`.
291
+
292
+ *Effects:* Direct-non-list-initializes *val* with
293
+ `std::forward<Args>(args)...`.
294
+
295
+ *Ensures:* `has_value()` is `true`.
296
+
297
+ *Throws:* Any exception thrown by the initialization of *val*.
298
+
299
+ ``` cpp
300
+ template<class U, class... Args>
301
+ constexpr explicit expected(in_place_t, initializer_list<U> il, Args&&... args);
302
+ ```
303
+
304
+ *Constraints:* `is_constructible_v<T, initializer_list<U>&, Args...>` is
305
+ `true`.
306
+
307
+ *Effects:* Direct-non-list-initializes *val* with
308
+ `il, std::forward<Args>(args)...`.
309
+
310
+ *Ensures:* `has_value()` is `true`.
311
+
312
+ *Throws:* Any exception thrown by the initialization of *val*.
313
+
314
+ ``` cpp
315
+ template<class... Args>
316
+ constexpr explicit expected(unexpect_t, Args&&... args);
317
+ ```
318
+
319
+ *Constraints:* `is_constructible_v<E, Args...>` is `true`.
320
+
321
+ *Effects:* Direct-non-list-initializes *unex* with
322
+ `std::forward<Args>(args)...`.
323
+
324
+ *Ensures:* `has_value()` is `false`.
325
+
326
+ *Throws:* Any exception thrown by the initialization of *unex*.
327
+
328
+ ``` cpp
329
+ template<class U, class... Args>
330
+ constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
331
+ ```
332
+
333
+ *Constraints:* `is_constructible_v<E, initializer_list<U>&, Args...>` is
334
+ `true`.
335
+
336
+ *Effects:* Direct-non-list-initializes *unex* with
337
+ `il, std::forward<Args>(args)...`.
338
+
339
+ *Ensures:* `has_value()` is `false`.
340
+
341
+ *Throws:* Any exception thrown by the initialization of *unex*.
342
+
343
+ #### Destructor <a id="expected.object.dtor">[[expected.object.dtor]]</a>
344
+
345
+ ``` cpp
346
+ constexpr ~expected();
347
+ ```
348
+
349
+ *Effects:* If `has_value()` is `true`, destroys *val*, otherwise
350
+ destroys *unex*.
351
+
352
+ *Remarks:* If `is_trivially_destructible_v<T>` is `true`, and
353
+ `is_trivially_destructible_v<E>` is `true`, then this destructor is a
354
+ trivial destructor.
355
+
356
+ #### Assignment <a id="expected.object.assign">[[expected.object.assign]]</a>
357
+
358
+ This subclause makes use of the following exposition-only function:
359
+
360
+ ``` cpp
361
+ template<class T, class U, class... Args>
362
+ constexpr void reinit-expected(T& newval, U& oldval, Args&&... args) { // exposition only
363
+ if constexpr (is_nothrow_constructible_v<T, Args...>) {
364
+ destroy_at(addressof(oldval));
365
+ construct_at(addressof(newval), std::forward<Args>(args)...);
366
+ } else if constexpr (is_nothrow_move_constructible_v<T>) {
367
+ T tmp(std::forward<Args>(args)...);
368
+ destroy_at(addressof(oldval));
369
+ construct_at(addressof(newval), std::move(tmp));
370
+ } else {
371
+ U tmp(std::move(oldval));
372
+ destroy_at(addressof(oldval));
373
+ try {
374
+ construct_at(addressof(newval), std::forward<Args>(args)...);
375
+ } catch (...) {
376
+ construct_at(addressof(oldval), std::move(tmp));
377
+ throw;
378
+ }
379
+ }
380
+ }
381
+ ```
382
+
383
+ ``` cpp
384
+ constexpr expected& operator=(const expected& rhs);
385
+ ```
386
+
387
+ *Effects:*
388
+
389
+ - If `this->has_value() && rhs.has_value()` is `true`, equivalent to
390
+ *`val`*` = *rhs`.
391
+ - Otherwise, if `this->has_value()` is `true`, equivalent to:
392
+ ``` cpp
393
+ reinit-expected(unex, val, rhs.error())
394
+ ```
395
+ - Otherwise, if `rhs.has_value()` is `true`, equivalent to:
396
+ ``` cpp
397
+ reinit-expected(val, unex, *rhs)
398
+ ```
399
+ - Otherwise, equivalent to *`unex`*` = rhs.error()`.
400
+
401
+ Then, if no exception was thrown, equivalent to:
402
+ *`has_val`*` = rhs.has_value(); return *this;`
403
+
404
+ *Returns:* `*this`.
405
+
406
+ *Remarks:* This operator is defined as deleted unless:
407
+
408
+ - `is_copy_assignable_v<T>` is `true` and
409
+ - `is_copy_constructible_v<T>` is `true` and
410
+ - `is_copy_assignable_v<E>` is `true` and
411
+ - `is_copy_constructible_v<E>` is `true` and
412
+ - `is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>`
413
+ is `true`.
414
+
415
+ ``` cpp
416
+ constexpr expected& operator=(expected&& rhs) noexcept(see below);
417
+ ```
418
+
419
+ *Constraints:*
420
+
421
+ - `is_move_constructible_v<T>` is `true` and
422
+ - `is_move_assignable_v<T>` is `true` and
423
+ - `is_move_constructible_v<E>` is `true` and
424
+ - `is_move_assignable_v<E>` is `true` and
425
+ - `is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>`
426
+ is `true`.
427
+
428
+ *Effects:*
429
+
430
+ - If `this->has_value() && rhs.has_value()` is `true`, equivalent to
431
+ *`val`*` = std::move(*rhs)`.
432
+ - Otherwise, if `this->has_value()` is `true`, equivalent to:
433
+ ``` cpp
434
+ reinit-expected(unex, val, std::move(rhs.error()))
435
+ ```
436
+ - Otherwise, if `rhs.has_value()` is `true`, equivalent to:
437
+ ``` cpp
438
+ reinit-expected(val, unex, std::move(*rhs))
439
+ ```
440
+ - Otherwise, equivalent to *`unex`*` = std::move(rhs.error())`.
441
+
442
+ Then, if no exception was thrown, equivalent to:
443
+ `has_val = rhs.has_value(); return *this;`
444
+
445
+ *Returns:* `*this`.
446
+
447
+ *Remarks:* The exception specification is equivalent to:
448
+
449
+ ``` cpp
450
+ is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> &&
451
+ is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>
452
+ ```
453
+
454
+ ``` cpp
455
+ template<class U = T>
456
+ constexpr expected& operator=(U&& v);
457
+ ```
458
+
459
+ *Constraints:*
460
+
461
+ - `is_same_v<expected, remove_cvref_t<U>>` is `false`; and
462
+ - `remove_cvref_t<U>` is not a specialization of `unexpected`; and
463
+ - `is_constructible_v<T, U>` is `true`; and
464
+ - `is_assignable_v<T&, U>` is `true`; and
465
+ - `is_nothrow_constructible_v<T, U> || is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>`
466
+ is `true`.
467
+
468
+ *Effects:*
469
+
470
+ - If `has_value()` is `true`, equivalent to:
471
+ *`val`*` = std::forward<U>(v);`
472
+ - Otherwise, equivalent to:
473
+ ``` cpp
474
+ reinit-expected(val, unex, std::forward<U>(v));
475
+ has_val = true;
476
+ ```
477
+
478
+ *Returns:* `*this`.
479
+
480
+ ``` cpp
481
+ template<class G>
482
+ constexpr expected& operator=(const unexpected<G>& e);
483
+ template<class G>
484
+ constexpr expected& operator=(unexpected<G>&& e);
485
+ ```
486
+
487
+ Let `GF` be `const G&` for the first overload and `G` for the second
488
+ overload.
489
+
490
+ *Constraints:*
491
+
492
+ - `is_constructible_v<E, GF>` is `true`; and
493
+ - `is_assignable_v<E&, GF>` is `true`; and
494
+ - `is_nothrow_constructible_v<E, GF> || is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>`
495
+ is `true`.
496
+
497
+ *Effects:*
498
+
499
+ - If `has_value()` is `true`, equivalent to:
500
+ ``` cpp
501
+ reinit-expected(unex, val, std::forward<GF>(e.error()));
502
+ has_val = false;
503
+ ```
504
+ - Otherwise, equivalent to: *`unex`*` = std::forward<GF>(e.error());`
505
+
506
+ *Returns:* `*this`.
507
+
508
+ ``` cpp
509
+ template<class... Args>
510
+ constexpr T& emplace(Args&&... args) noexcept;
511
+ ```
512
+
513
+ *Constraints:* `is_nothrow_constructible_v<T, Args...>` is `true`.
514
+
515
+ *Effects:* Equivalent to:
516
+
517
+ ``` cpp
518
+ if (has_value()) {
519
+ destroy_at(addressof(val));
520
+ } else {
521
+ destroy_at(addressof(unex));
522
+ has_val = true;
523
+ }
524
+ return *construct_at(addressof(val), std::forward<Args>(args)...);
525
+ ```
526
+
527
+ ``` cpp
528
+ template<class U, class... Args>
529
+ constexpr T& emplace(initializer_list<U> il, Args&&... args) noexcept;
530
+ ```
531
+
532
+ *Constraints:*
533
+ `is_nothrow_constructible_v<T, initializer_list<U>&, Args...>` is
534
+ `true`.
535
+
536
+ *Effects:* Equivalent to:
537
+
538
+ ``` cpp
539
+ if (has_value()) {
540
+ destroy_at(addressof(val));
541
+ } else {
542
+ destroy_at(addressof(unex));
543
+ has_val = true;
544
+ }
545
+ return *construct_at(addressof(val), il, std::forward<Args>(args)...);
546
+ ```
547
+
548
+ #### Swap <a id="expected.object.swap">[[expected.object.swap]]</a>
549
+
550
+ ``` cpp
551
+ constexpr void swap(expected& rhs) noexcept(see below);
552
+ ```
553
+
554
+ *Constraints:*
555
+
556
+ - `is_swappable_v<T>` is `true` and
557
+ - `is_swappable_v<E>` is `true` and
558
+ - `is_move_constructible_v<T> && is_move_constructible_v<E>` is `true`,
559
+ and
560
+ - `is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>`
561
+ is `true`.
562
+
563
+ *Effects:* See [[expected.object.swap]].
564
+
565
+ **Table: `swap(expected&)` effects** <a id="expected.object.swap">[expected.object.swap]</a>
566
+
567
+ | \topline | `this->has_value()` | `!this->has_value()` |
568
+ | -------- | ------------------- | -------------------- |
569
+
570
+
571
+ For the case where `rhs.value()` is `false` and `this->has_value()` is
572
+ `true`, equivalent to:
573
+
574
+ ``` cpp
575
+ if constexpr (is_nothrow_move_constructible_v<E>) {
576
+ E tmp(std::move(rhs.unex));
577
+ destroy_at(addressof(rhs.unex));
578
+ try {
579
+ construct_at(addressof(rhs.val), std::move(val));
580
+ destroy_at(addressof(val));
581
+ construct_at(addressof(unex), std::move(tmp));
582
+ } catch(...) {
583
+ construct_at(addressof(rhs.unex), std::move(tmp));
584
+ throw;
585
+ }
586
+ } else {
587
+ T tmp(std::move(val));
588
+ destroy_at(addressof(val));
589
+ try {
590
+ construct_at(addressof(unex), std::move(rhs.unex));
591
+ destroy_at(addressof(rhs.unex));
592
+ construct_at(addressof(rhs.val), std::move(tmp));
593
+ } catch (...) {
594
+ construct_at(addressof(val), std::move(tmp));
595
+ throw;
596
+ }
597
+ }
598
+ has_val = false;
599
+ rhs.has_val = true;
600
+ ```
601
+
602
+ *Throws:* Any exception thrown by the expressions in the *Effects*.
603
+
604
+ *Remarks:* The exception specification is equivalent to:
605
+
606
+ ``` cpp
607
+ is_nothrow_move_constructible_v<T> && is_nothrow_swappable_v<T> &&
608
+ is_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>
609
+ ```
610
+
611
+ ``` cpp
612
+ friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
613
+ ```
614
+
615
+ *Effects:* Equivalent to `x.swap(y)`.
616
+
617
+ #### Observers <a id="expected.object.obs">[[expected.object.obs]]</a>
618
+
619
+ ``` cpp
620
+ constexpr const T* operator->() const noexcept;
621
+ constexpr T* operator->() noexcept;
622
+ ```
623
+
624
+ *Preconditions:* `has_value()` is `true`.
625
+
626
+ *Returns:* `addressof(`*`val`*`)`.
627
+
628
+ ``` cpp
629
+ constexpr const T& operator*() const & noexcept;
630
+ constexpr T& operator*() & noexcept;
631
+ ```
632
+
633
+ *Preconditions:* `has_value()` is `true`.
634
+
635
+ *Returns:* *val*.
636
+
637
+ ``` cpp
638
+ constexpr T&& operator*() && noexcept;
639
+ constexpr const T&& operator*() const && noexcept;
640
+ ```
641
+
642
+ *Preconditions:* `has_value()` is `true`.
643
+
644
+ *Returns:* `std::move(`*`val`*`)`.
645
+
646
+ ``` cpp
647
+ constexpr explicit operator bool() const noexcept;
648
+ constexpr bool has_value() const noexcept;
649
+ ```
650
+
651
+ *Returns:* *has_val*.
652
+
653
+ ``` cpp
654
+ constexpr const T& value() const &;
655
+ constexpr T& value() &;
656
+ ```
657
+
658
+ *Mandates:* `is_copy_constructible_v<E>` is `true`.
659
+
660
+ *Returns:* *val*, if `has_value()` is `true`.
661
+
662
+ *Throws:* `bad_expected_access(as_const(error()))` if `has_value()` is
663
+ `false`.
664
+
665
+ ``` cpp
666
+ constexpr T&& value() &&;
667
+ constexpr const T&& value() const &&;
668
+ ```
669
+
670
+ *Mandates:* `is_copy_constructible_v<E>` is `true` and
671
+ `is_constructible_v<E, decltype(std::move(error()))>` is `true`.
672
+
673
+ *Returns:* `std::move(`*`val`*`)`, if `has_value()` is `true`.
674
+
675
+ *Throws:* `bad_expected_access(std::move(error()))` if `has_value()` is
676
+ `false`.
677
+
678
+ ``` cpp
679
+ constexpr const E& error() const & noexcept;
680
+ constexpr E& error() & noexcept;
681
+ ```
682
+
683
+ *Preconditions:* `has_value()` is `false`.
684
+
685
+ *Returns:* *unex*.
686
+
687
+ ``` cpp
688
+ constexpr E&& error() && noexcept;
689
+ constexpr const E&& error() const && noexcept;
690
+ ```
691
+
692
+ *Preconditions:* `has_value()` is `false`.
693
+
694
+ *Returns:* `std::move(`*`unex`*`)`.
695
+
696
+ ``` cpp
697
+ template<class U> constexpr T value_or(U&& v) const &;
698
+ ```
699
+
700
+ *Mandates:* `is_copy_constructible_v<T>` is `true` and
701
+ `is_convertible_v<U, T>` is `true`.
702
+
703
+ *Returns:* `has_value() ? **this : static_cast<T>(std::forward<U>(v))`.
704
+
705
+ ``` cpp
706
+ template<class U> constexpr T value_or(U&& v) &&;
707
+ ```
708
+
709
+ *Mandates:* `is_move_constructible_v<T>` is `true` and
710
+ `is_convertible_v<U, T>` is `true`.
711
+
712
+ *Returns:*
713
+ `has_value() ? std::move(**this) : static_cast<T>(std::forward<U>(v))`.
714
+
715
+ ``` cpp
716
+ template<class G = E> constexpr E error_or(G&& e) const &;
717
+ ```
718
+
719
+ *Mandates:* `is_copy_constructible_v<E>` is `true` and
720
+ `is_convertible_v<G, E>` is `true`.
721
+
722
+ *Returns:* `std::forward<G>(e)` if `has_value()` is `true`, `error()`
723
+ otherwise.
724
+
725
+ ``` cpp
726
+ template<class G = E> constexpr E error_or(G&& e) &&;
727
+ ```
728
+
729
+ *Mandates:* `is_move_constructible_v<E>` is `true` and
730
+ `is_convertible_v<G, E>` is `true`.
731
+
732
+ *Returns:* `std::forward<G>(e)` if `has_value()` is `true`,
733
+ `std::move(error())` otherwise.
734
+
735
+ #### Monadic operations <a id="expected.object.monadic">[[expected.object.monadic]]</a>
736
+
737
+ ``` cpp
738
+ template<class F> constexpr auto and_then(F&& f) &;
739
+ template<class F> constexpr auto and_then(F&& f) const &;
740
+ ```
741
+
742
+ Let `U` be `remove_cvref_t<invoke_result_t<F, decltype(value())>>`.
743
+
744
+ *Constraints:* `is_constructible_v<E, decltype(error())>` is `true`.
745
+
746
+ *Mandates:* `U` is a specialization of `expected` and
747
+ `is_same_v<U::error_type, E>` is `true`.
748
+
749
+ *Effects:* Equivalent to:
750
+
751
+ ``` cpp
752
+ if (has_value())
753
+ return invoke(std::forward<F>(f), value());
754
+ else
755
+ return U(unexpect, error());
756
+ ```
757
+
758
+ ``` cpp
759
+ template<class F> constexpr auto and_then(F&& f) &&;
760
+ template<class F> constexpr auto and_then(F&& f) const &&;
761
+ ```
762
+
763
+ Let `U` be
764
+ `remove_cvref_t<invoke_result_t<F, decltype(std::move(value()))>>`.
765
+
766
+ *Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
767
+ `true`.
768
+
769
+ *Mandates:* `U` is a specialization of `expected` and
770
+ `is_same_v<U::error_type, E>` is `true`.
771
+
772
+ *Effects:* Equivalent to:
773
+
774
+ ``` cpp
775
+ if (has_value())
776
+ return invoke(std::forward<F>(f), std::move(value()));
777
+ else
778
+ return U(unexpect, std::move(error()));
779
+ ```
780
+
781
+ ``` cpp
782
+ template<class F> constexpr auto or_else(F&& f) &;
783
+ template<class F> constexpr auto or_else(F&& f) const &;
784
+ ```
785
+
786
+ Let `G` be `remove_cvref_t<invoke_result_t<F, decltype(error())>>`.
787
+
788
+ *Constraints:* `is_constructible_v<T, decltype(value())>` is `true`.
789
+
790
+ *Mandates:* `G` is a specialization of `expected` and
791
+ `is_same_v<G::value_type, T>` is `true`.
792
+
793
+ *Effects:* Equivalent to:
794
+
795
+ ``` cpp
796
+ if (has_value())
797
+ return G(in_place, value());
798
+ else
799
+ return invoke(std::forward<F>(f), error());
800
+ ```
801
+
802
+ ``` cpp
803
+ template<class F> constexpr auto or_else(F&& f) &&;
804
+ template<class F> constexpr auto or_else(F&& f) const &&;
805
+ ```
806
+
807
+ Let `G` be
808
+ `remove_cvref_t<invoke_result_t<F, decltype(std::move(error()))>>`.
809
+
810
+ *Constraints:* `is_constructible_v<T, decltype(std::move(value()))>` is
811
+ `true`.
812
+
813
+ *Mandates:* `G` is a specialization of `expected` and
814
+ `is_same_v<G::value_type, T>` is `true`.
815
+
816
+ *Effects:* Equivalent to:
817
+
818
+ ``` cpp
819
+ if (has_value())
820
+ return G(in_place, std::move(value()));
821
+ else
822
+ return invoke(std::forward<F>(f), std::move(error()));
823
+ ```
824
+
825
+ ``` cpp
826
+ template<class F> constexpr auto transform(F&& f) &;
827
+ template<class F> constexpr auto transform(F&& f) const &;
828
+ ```
829
+
830
+ Let `U` be `remove_cv_t<invoke_result_t<F, decltype(value())>>`.
831
+
832
+ *Constraints:* `is_constructible_v<E, decltype(error())>` is `true`.
833
+
834
+ *Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
835
+ is `false`, the declaration
836
+
837
+ ``` cpp
838
+ U u(invoke(std::forward<F>(f), value()));
839
+ ```
840
+
841
+ is well-formed.
842
+
843
+ *Effects:*
844
+
845
+ - If `has_value()` is `false`, returns
846
+ `expected<U, E>(unexpect, error())`.
847
+ - Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
848
+ object whose *has_val* member is `true` and *val* member is
849
+ direct-non-list-initialized with
850
+ `invoke(std::forward<F>(f), value())`.
851
+ - Otherwise, evaluates `invoke(std::forward<F>(f), value())` and then
852
+ returns `expected<U, E>()`.
853
+
854
+ ``` cpp
855
+ template<class F> constexpr auto transform(F&& f) &&;
856
+ template<class F> constexpr auto transform(F&& f) const &&;
857
+ ```
858
+
859
+ Let `U` be
860
+ `remove_cv_t<invoke_result_t<F, decltype(std::move(value()))>>`.
861
+
862
+ *Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
863
+ `true`.
864
+
865
+ *Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
866
+ is `false`, the declaration
867
+
868
+ ``` cpp
869
+ U u(invoke(std::forward<F>(f), std::move(value())));
870
+ ```
871
+
872
+ is well-formed for some invented variable `u`.
873
+
874
+ *Effects:*
875
+
876
+ - If `has_value()` is `false`, returns
877
+ `expected<U, E>(unexpect, std::move(error()))`.
878
+ - Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
879
+ object whose *has_val* member is `true` and *val* member is
880
+ direct-non-list-initialized with
881
+ `invoke(std::forward<F>(f), std::move(value()))`.
882
+ - Otherwise, evaluates `invoke(std::forward<F>(f), std::move(value()))`
883
+ and then returns `expected<U, E>()`.
884
+
885
+ ``` cpp
886
+ template<class F> constexpr auto transform_error(F&& f) &;
887
+ template<class F> constexpr auto transform_error(F&& f) const &;
888
+ ```
889
+
890
+ Let `G` be `remove_cv_t<invoke_result_t<F, decltype(error())>>`.
891
+
892
+ *Constraints:* `is_constructible_v<T, decltype(value())>` is `true`.
893
+
894
+ *Mandates:* `G` is a valid template argument for `unexpected`
895
+ [[expected.un.general]] and the declaration
896
+
897
+ ``` cpp
898
+ G g(invoke(std::forward<F>(f), error()));
899
+ ```
900
+
901
+ is well-formed.
902
+
903
+ *Returns:* If `has_value()` is `true`,
904
+ `expected<T, G>(in_place, value())`; otherwise, an `expected<T, G>`
905
+ object whose *has_val* member is `false` and *unex* member is
906
+ direct-non-list-initialized with `invoke(std::forward<F>(f), error())`.
907
+
908
+ ``` cpp
909
+ template<class F> constexpr auto transform_error(F&& f) &&;
910
+ template<class F> constexpr auto transform_error(F&& f) const &&;
911
+ ```
912
+
913
+ Let `G` be
914
+ `remove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>`.
915
+
916
+ *Constraints:* `is_constructible_v<T, decltype(std::move(value()))>` is
917
+ `true`.
918
+
919
+ *Mandates:* `G` is a valid template argument for `unexpected`
920
+ [[expected.un.general]] and the declaration
921
+
922
+ ``` cpp
923
+ G g(invoke(std::forward<F>(f), std::move(error())));
924
+ ```
925
+
926
+ is well-formed.
927
+
928
+ *Returns:* If `has_value()` is `true`,
929
+ `expected<T, G>(in_place, std::move(value()))`; otherwise, an
930
+ `expected<T, G>` object whose *has_val* member is `false` and *unex*
931
+ member is direct-non-list-initialized with
932
+ `invoke(std::forward<F>(f), std::move(error()))`.
933
+
934
+ #### Equality operators <a id="expected.object.eq">[[expected.object.eq]]</a>
935
+
936
+ ``` cpp
937
+ template<class T2, class E2> requires (!is_void_v<T2>)
938
+ friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
939
+ ```
940
+
941
+ *Mandates:* The expressions `*x == *y` and `x.error() == y.error()` are
942
+ well-formed and their results are convertible to `bool`.
943
+
944
+ *Returns:* If `x.has_value()` does not equal `y.has_value()`, `false`;
945
+ otherwise if `x.has_value()` is `true`, `*x == *y`; otherwise
946
+ `x.error() == y.error()`.
947
+
948
+ ``` cpp
949
+ template<class T2> friend constexpr bool operator==(const expected& x, const T2& v);
950
+ ```
951
+
952
+ *Mandates:* The expression `*x == v` is well-formed and its result is
953
+ convertible to `bool`.
954
+
955
+ [*Note 1*: `T` need not be *Cpp17EqualityComparable*. — *end note*]
956
+
957
+ *Returns:* `x.has_value() && static_cast<bool>(*x == v)`.
958
+
959
+ ``` cpp
960
+ template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
961
+ ```
962
+
963
+ *Mandates:* The expression `x.error() == e.error()` is well-formed and
964
+ its result is convertible to `bool`.
965
+
966
+ *Returns:*
967
+ `!x.has_value() && static_cast<bool>(x.error() == e.error())`.
968
+