From Jason Turner

[expected]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmphmycijtw/{from.md → to.md} +118 -110
tmp/tmphmycijtw/{from.md → to.md} RENAMED
@@ -1,17 +1,18 @@
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
@@ -25,14 +26,14 @@ namespace std {
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
 
@@ -179,16 +180,16 @@ its result is convertible to `bool`.
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
  }
@@ -198,60 +199,62 @@ 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
 
@@ -274,11 +277,11 @@ namespace std {
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>
@@ -297,11 +300,11 @@ namespace std {
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
 
@@ -321,20 +324,20 @@ namespace std {
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) &;
@@ -371,15 +374,13 @@ namespace std {
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
@@ -495,18 +496,19 @@ with `std::forward<GF>(rhs.error())`.
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
 
@@ -606,11 +608,12 @@ destroys *unex*.
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...>) {
@@ -703,11 +706,11 @@ Then, if no exception was thrown, equivalent to:
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
 
@@ -819,12 +822,12 @@ constexpr void swap(expected& rhs) noexcept(see below);
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));
@@ -872,29 +875,29 @@ friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)
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;
@@ -931,34 +934,34 @@ constexpr const T&& value() const &&;
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
 
@@ -990,45 +993,45 @@ template<class G = E> constexpr E error_or(G&& e) &&;
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
@@ -1036,20 +1039,20 @@ 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
@@ -1058,39 +1061,39 @@ 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:*
@@ -1098,53 +1101,54 @@ is well-formed.
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
@@ -1152,11 +1156,11 @@ 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) &&;
@@ -1164,12 +1168,12 @@ 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
@@ -1177,11 +1181,11 @@ 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>
@@ -1189,34 +1193,35 @@ member is direct-non-list-initialized with
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>
@@ -1273,12 +1278,12 @@ public:
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 &;
@@ -1315,15 +1320,13 @@ private:
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
 
@@ -1488,10 +1491,13 @@ constexpr expected& operator=(const expected& rhs);
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
@@ -1505,13 +1511,10 @@ constexpr expected& operator=(expected&& rhs) noexcept(see below);
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);
@@ -1556,12 +1559,12 @@ constexpr void swap(expected& rhs) noexcept(see below);
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;
@@ -1590,40 +1593,45 @@ constexpr bool has_value() const noexcept;
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 &;
@@ -1655,11 +1663,11 @@ template<class F> constexpr auto and_then(F&& f) const &;
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())
@@ -1677,11 +1685,11 @@ 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())
@@ -1696,11 +1704,11 @@ 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())
@@ -1716,11 +1724,11 @@ template<class F> constexpr auto or_else(F&& f) const &&;
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())
@@ -1834,22 +1842,22 @@ member is direct-non-list-initialized with
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
 
 
1
  ## Expected objects <a id="expected">[[expected]]</a>
2
 
3
+ ### 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 `E` and manages the lifetime of the
8
+ contained objects.
9
 
10
  ### Header `<expected>` synopsis <a id="expected.syn">[[expected.syn]]</a>
11
 
12
  ``` cpp
13
+ // mostly freestanding
14
  namespace std {
15
  // [expected.unexpected], class template unexpected
16
  template<class E> class unexpected;
17
 
18
  // [expected.bad], class template bad_expected_access
 
26
  explicit unexpect_t() = default;
27
  };
28
  inline constexpr unexpect_t unexpect{};
29
 
30
  // [expected.expected], class template expected
31
+ template<class T, class E> class expected; // partially freestanding
32
 
33
  // [expected.void], partial specialization of expected for void types
34
+ template<class T, class E> requires is_void_v<T> class expected<T, E>; // partially freestanding
35
  }
36
  ```
37
 
38
  ### Class template `unexpected` <a id="expected.unexpected">[[expected.unexpected]]</a>
39
 
 
180
  ``` cpp
181
  namespace std {
182
  template<class E>
183
  class bad_expected_access : public bad_expected_access<void> {
184
  public:
185
+ constexpr explicit bad_expected_access(E);
186
+ constexpr const char* what() const noexcept override;
187
+ constexpr E& error() & noexcept;
188
+ constexpr const E& error() const & noexcept;
189
+ constexpr E&& error() && noexcept;
190
+ constexpr const E&& error() const && noexcept;
191
 
192
  private:
193
  E unex; // exposition only
194
  };
195
  }
 
199
  thrown as exceptions to report the situation where an attempt is made to
200
  access the value of an `expected<T, E>` object for which `has_value()`
201
  is `false`.
202
 
203
  ``` cpp
204
+ constexpr explicit bad_expected_access(E e);
205
  ```
206
 
207
  *Effects:* Initializes *unex* with `std::move(e)`.
208
 
209
  ``` cpp
210
+ constexpr const E& error() const & noexcept;
211
+ constexpr E& error() & noexcept;
212
  ```
213
 
214
  *Returns:* *unex*.
215
 
216
  ``` cpp
217
+ constexpr E&& error() && noexcept;
218
+ constexpr const E&& error() const && noexcept;
219
  ```
220
 
221
  *Returns:* `std::move(`*`unex`*`)`.
222
 
223
  ``` cpp
224
+ constexpr const char* what() const noexcept override;
225
  ```
226
 
227
+ *Returns:* An *implementation-defined* NTBS, which during constant
228
+ evaluation is encoded with the ordinary literal encoding [[lex.ccon]].
229
 
230
  ### Class template specialization `bad_expected_access<void>` <a id="expected.bad.void">[[expected.bad.void]]</a>
231
 
232
  ``` cpp
233
  namespace std {
234
  template<>
235
  class bad_expected_access<void> : public exception {
236
  protected:
237
+ constexpr bad_expected_access() noexcept;
238
+ constexpr bad_expected_access(const bad_expected_access&) noexcept;
239
+ constexpr bad_expected_access(bad_expected_access&&) noexcept;
240
+ constexpr bad_expected_access& operator=(const bad_expected_access&) noexcept;
241
+ constexpr bad_expected_access& operator=(bad_expected_access&&) noexcept;
242
+ constexpr ~bad_expected_access();
243
 
244
  public:
245
+ constexpr const char* what() const noexcept override;
246
  };
247
  }
248
  ```
249
 
250
  ``` cpp
251
+ constexpr const char* what() const noexcept override;
252
  ```
253
 
254
+ *Returns:* An *implementation-defined* NTBS, which during constant
255
+ evaluation is encoded with the ordinary literal encoding [[lex.ccon]].
256
 
257
  ### Class template `expected` <a id="expected.expected">[[expected.expected]]</a>
258
 
259
  #### General <a id="expected.object.general">[[expected.object.general]]</a>
260
 
 
277
  template<class U, class G>
278
  constexpr explicit(see below) expected(const expected<U, G>&);
279
  template<class U, class G>
280
  constexpr explicit(see below) expected(expected<U, G>&&);
281
 
282
+ template<class U = remove_cv_t<T>>
283
  constexpr explicit(see below) expected(U&& v);
284
 
285
  template<class G>
286
  constexpr explicit(see below) expected(const unexpected<G>&);
287
  template<class G>
 
300
  constexpr ~expected();
301
 
302
  // [expected.object.assign], assignment
303
  constexpr expected& operator=(const expected&);
304
  constexpr expected& operator=(expected&&) noexcept(see below);
305
+ template<class U = remove_cv_t<T>> constexpr expected& operator=(U&&);
306
  template<class G>
307
  constexpr expected& operator=(const unexpected<G>&);
308
  template<class G>
309
  constexpr expected& operator=(unexpected<G>&&);
310
 
 
324
  constexpr T& operator*() & noexcept;
325
  constexpr const T&& operator*() const && noexcept;
326
  constexpr T&& operator*() && noexcept;
327
  constexpr explicit operator bool() const noexcept;
328
  constexpr bool has_value() const noexcept;
329
+ constexpr const T& value() const &; // freestanding-deleted
330
+ constexpr T& value() &; // freestanding-deleted
331
+ constexpr const T&& value() const &&; // freestanding-deleted
332
+ constexpr T&& value() &&; // freestanding-deleted
333
  constexpr const E& error() const & noexcept;
334
  constexpr E& error() & noexcept;
335
  constexpr const E&& error() const && noexcept;
336
  constexpr E&& error() && noexcept;
337
+ template<class U = remove_cv_t<T>> constexpr T value_or(U&&) const &;
338
+ template<class U = remove_cv_t<T>> constexpr T value_or(U&&) &&;
339
  template<class G = E> constexpr E error_or(G&&) const &;
340
  template<class G = E> constexpr E error_or(G&&) &&;
341
 
342
  // [expected.object.monadic], monadic operations
343
  template<class F> constexpr auto and_then(F&& f) &;
 
374
  };
375
  }
376
  ```
377
 
378
  Any object of type `expected<T, E>` either contains a value of type `T`
379
+ or a value of type `E` nested within [[intro.object]] it. Member
380
+ *`has_val`* indicates whether the `expected<T, E>` object contains an
381
+ object of type `T`.
 
 
382
 
383
  A type `T` is a *valid value type for `expected`*, if `remove_cv_t<T>`
384
  is `void` or a complete non-array object type that is not `in_place_t`,
385
  `unexpect_t`, or a specialization of `unexpected`. A program which
386
  instantiates class template `expected<T, E>` with an argument `T` that
 
496
 
497
  *Remarks:* The expression inside `explicit` is equivalent to
498
  `!is_convertible_v<UF, T> || !is_convertible_v<GF, E>`.
499
 
500
  ``` cpp
501
+ template<class U = remove_cv_t<T>>
502
  constexpr explicit(!is_convertible_v<U, T>) expected(U&& v);
503
  ```
504
 
505
  *Constraints:*
506
 
507
  - `is_same_v<remove_cvref_t<U>, in_place_t>` is `false`; and
508
+ - `is_same_v<remove_cvref_t<U>, expected>` is `false`; and
509
+ - `is_same_v<remove_cvref_t<U>, unexpect_t>` is `false`; and
510
  - `remove_cvref_t<U>` is not a specialization of `unexpected`; and
511
  - `is_constructible_v<T, U>` is `true`; and
512
  - if `T` is cv `bool`, `remove_cvref_t<U>` is not a specialization of
513
  `expected`.
514
 
 
608
  `is_trivially_destructible_v<E>` is `true`, then this destructor is a
609
  trivial destructor.
610
 
611
  #### Assignment <a id="expected.object.assign">[[expected.object.assign]]</a>
612
 
613
+ This subclause makes use of the following exposition-only function
614
+ template:
615
 
616
  ``` cpp
617
  template<class T, class U, class... Args>
618
  constexpr void reinit-expected(T& newval, U& oldval, Args&&... args) { // exposition only
619
  if constexpr (is_nothrow_constructible_v<T, Args...>) {
 
706
  is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> &&
707
  is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>
708
  ```
709
 
710
  ``` cpp
711
+ template<class U = remove_cv_t<T>>
712
  constexpr expected& operator=(U&& v);
713
  ```
714
 
715
  *Constraints:*
716
 
 
822
 
823
  | \topline | `this->has_value()` | `!this->has_value()` |
824
  | -------- | ------------------- | -------------------- |
825
 
826
 
827
+ For the case where `rhs.has_value()` is `false` and `this->has_value()`
828
+ is `true`, equivalent to:
829
 
830
  ``` cpp
831
  if constexpr (is_nothrow_move_constructible_v<E>) {
832
  E tmp(std::move(rhs.unex));
833
  destroy_at(addressof(rhs.unex));
 
875
  ``` cpp
876
  constexpr const T* operator->() const noexcept;
877
  constexpr T* operator->() noexcept;
878
  ```
879
 
880
+ `has_value()` is `true`.
881
 
882
  *Returns:* `addressof(`*`val`*`)`.
883
 
884
  ``` cpp
885
  constexpr const T& operator*() const & noexcept;
886
  constexpr T& operator*() & noexcept;
887
  ```
888
 
889
+ `has_value()` is `true`.
890
 
891
  *Returns:* *val*.
892
 
893
  ``` cpp
894
  constexpr T&& operator*() && noexcept;
895
  constexpr const T&& operator*() const && noexcept;
896
  ```
897
 
898
+ `has_value()` is `true`.
899
 
900
  *Returns:* `std::move(`*`val`*`)`.
901
 
902
  ``` cpp
903
  constexpr explicit operator bool() const noexcept;
 
934
  ``` cpp
935
  constexpr const E& error() const & noexcept;
936
  constexpr E& error() & noexcept;
937
  ```
938
 
939
+ `has_value()` is `false`.
940
 
941
  *Returns:* *unex*.
942
 
943
  ``` cpp
944
  constexpr E&& error() && noexcept;
945
  constexpr const E&& error() const && noexcept;
946
  ```
947
 
948
+ `has_value()` is `false`.
949
 
950
  *Returns:* `std::move(`*`unex`*`)`.
951
 
952
  ``` cpp
953
+ template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;
954
  ```
955
 
956
  *Mandates:* `is_copy_constructible_v<T>` is `true` and
957
  `is_convertible_v<U, T>` is `true`.
958
 
959
  *Returns:* `has_value() ? **this : static_cast<T>(std::forward<U>(v))`.
960
 
961
  ``` cpp
962
+ template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;
963
  ```
964
 
965
  *Mandates:* `is_move_constructible_v<T>` is `true` and
966
  `is_convertible_v<U, T>` is `true`.
967
 
 
993
  ``` cpp
994
  template<class F> constexpr auto and_then(F&& f) &;
995
  template<class F> constexpr auto and_then(F&& f) const &;
996
  ```
997
 
998
+ Let `U` be `remove_cvref_t<invoke_result_t<F, decltype((`*`val`*`))>>`.
999
 
1000
  *Constraints:* `is_constructible_v<E, decltype(error())>` is `true`.
1001
 
1002
  *Mandates:* `U` is a specialization of `expected` and
1003
+ `is_same_v<typename U::error_type, E>` is `true`.
1004
 
1005
  *Effects:* Equivalent to:
1006
 
1007
  ``` cpp
1008
  if (has_value())
1009
+ return invoke(std::forward<F>(f), val);
1010
  else
1011
  return U(unexpect, error());
1012
  ```
1013
 
1014
  ``` cpp
1015
  template<class F> constexpr auto and_then(F&& f) &&;
1016
  template<class F> constexpr auto and_then(F&& f) const &&;
1017
  ```
1018
 
1019
  Let `U` be
1020
+ `remove_cvref_t<invoke_result_t<F, decltype(std::move(`*`val`*`))>>`.
1021
 
1022
  *Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
1023
  `true`.
1024
 
1025
  *Mandates:* `U` is a specialization of `expected` and
1026
+ `is_same_v<typename U::error_type, E>` is `true`.
1027
 
1028
  *Effects:* Equivalent to:
1029
 
1030
  ``` cpp
1031
  if (has_value())
1032
+ return invoke(std::forward<F>(f), std::move(val));
1033
  else
1034
  return U(unexpect, std::move(error()));
1035
  ```
1036
 
1037
  ``` cpp
 
1039
  template<class F> constexpr auto or_else(F&& f) const &;
1040
  ```
1041
 
1042
  Let `G` be `remove_cvref_t<invoke_result_t<F, decltype(error())>>`.
1043
 
1044
+ *Constraints:* `is_constructible_v<T, decltype((`*`val`*`))>` is `true`.
1045
 
1046
  *Mandates:* `G` is a specialization of `expected` and
1047
+ `is_same_v<typename G::value_type, T>` is `true`.
1048
 
1049
  *Effects:* Equivalent to:
1050
 
1051
  ``` cpp
1052
  if (has_value())
1053
+ return G(in_place, val);
1054
  else
1055
  return invoke(std::forward<F>(f), error());
1056
  ```
1057
 
1058
  ``` cpp
 
1061
  ```
1062
 
1063
  Let `G` be
1064
  `remove_cvref_t<invoke_result_t<F, decltype(std::move(error()))>>`.
1065
 
1066
+ *Constraints:* `is_constructible_v<T, decltype(std::move(`*`val`*`))>`
1067
+ is `true`.
1068
 
1069
  *Mandates:* `G` is a specialization of `expected` and
1070
+ `is_same_v<typename G::value_type, T>` is `true`.
1071
 
1072
  *Effects:* Equivalent to:
1073
 
1074
  ``` cpp
1075
  if (has_value())
1076
+ return G(in_place, std::move(val));
1077
  else
1078
  return invoke(std::forward<F>(f), std::move(error()));
1079
  ```
1080
 
1081
  ``` cpp
1082
  template<class F> constexpr auto transform(F&& f) &;
1083
  template<class F> constexpr auto transform(F&& f) const &;
1084
  ```
1085
 
1086
+ Let `U` be `remove_cv_t<invoke_result_t<F, decltype((`*`val`*`))>>`.
1087
 
1088
  *Constraints:* `is_constructible_v<E, decltype(error())>` is `true`.
1089
 
1090
  *Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
1091
  is `false`, the declaration
1092
 
1093
  ``` cpp
1094
+ U u(invoke(std::forward<F>(f), val));
1095
  ```
1096
 
1097
  is well-formed.
1098
 
1099
  *Effects:*
 
1101
  - If `has_value()` is `false`, returns
1102
  `expected<U, E>(unexpect, error())`.
1103
  - Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
1104
  object whose *has_val* member is `true` and *val* member is
1105
  direct-non-list-initialized with
1106
+ `invoke(std::forward<F>(f), `*`val`*`)`.
1107
+ - Otherwise, evaluates `invoke(std::forward<F>(f), `*`val`*`)` and then
1108
  returns `expected<U, E>()`.
1109
 
1110
  ``` cpp
1111
  template<class F> constexpr auto transform(F&& f) &&;
1112
  template<class F> constexpr auto transform(F&& f) const &&;
1113
  ```
1114
 
1115
  Let `U` be
1116
+ `remove_cv_t<invoke_result_t<F, decltype(std::move(`*`val`*`))>>`.
1117
 
1118
  *Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
1119
  `true`.
1120
 
1121
  *Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
1122
  is `false`, the declaration
1123
 
1124
  ``` cpp
1125
+ U u(invoke(std::forward<F>(f), std::move(val)));
1126
  ```
1127
 
1128
+ is well-formed.
1129
 
1130
  *Effects:*
1131
 
1132
  - If `has_value()` is `false`, returns
1133
  `expected<U, E>(unexpect, std::move(error()))`.
1134
  - Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
1135
  object whose *has_val* member is `true` and *val* member is
1136
  direct-non-list-initialized with
1137
+ `invoke(std::forward<F>(f), std::move(`*`val`*`))`.
1138
+ - Otherwise, evaluates
1139
+ `invoke(std::forward<F>(f), std::move(`*`val`*`))` and then returns
1140
+ `expected<U, E>()`.
1141
 
1142
  ``` cpp
1143
  template<class F> constexpr auto transform_error(F&& f) &;
1144
  template<class F> constexpr auto transform_error(F&& f) const &;
1145
  ```
1146
 
1147
  Let `G` be `remove_cv_t<invoke_result_t<F, decltype(error())>>`.
1148
 
1149
+ *Constraints:* `is_constructible_v<T, decltype((`*`val`*`))>` is `true`.
1150
 
1151
  *Mandates:* `G` is a valid template argument for `unexpected`
1152
  [[expected.un.general]] and the declaration
1153
 
1154
  ``` cpp
 
1156
  ```
1157
 
1158
  is well-formed.
1159
 
1160
  *Returns:* If `has_value()` is `true`,
1161
+ `expected<T, G>(in_place, `*`val`*`)`; otherwise, an `expected<T, G>`
1162
  object whose *has_val* member is `false` and *unex* member is
1163
  direct-non-list-initialized with `invoke(std::forward<F>(f), error())`.
1164
 
1165
  ``` cpp
1166
  template<class F> constexpr auto transform_error(F&& f) &&;
 
1168
  ```
1169
 
1170
  Let `G` be
1171
  `remove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>`.
1172
 
1173
+ *Constraints:* `is_constructible_v<T, decltype(std::move(`*`val`*`))>`
1174
+ is `true`.
1175
 
1176
  *Mandates:* `G` is a valid template argument for `unexpected`
1177
  [[expected.un.general]] and the declaration
1178
 
1179
  ``` cpp
 
1181
  ```
1182
 
1183
  is well-formed.
1184
 
1185
  *Returns:* If `has_value()` is `true`,
1186
+ `expected<T, G>(in_place, std::move(`*`val`*`))`; otherwise, an
1187
  `expected<T, G>` object whose *has_val* member is `false` and *unex*
1188
  member is direct-non-list-initialized with
1189
  `invoke(std::forward<F>(f), std::move(error()))`.
1190
 
1191
  #### Equality operators <a id="expected.object.eq">[[expected.object.eq]]</a>
 
1193
  ``` cpp
1194
  template<class T2, class E2> requires (!is_void_v<T2>)
1195
  friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
1196
  ```
1197
 
1198
+ *Constraints:* The expressions `*x == *y` and `x.error() == y.error()`
1199
+ are well-formed and their results are convertible to `bool`.
1200
 
1201
  *Returns:* If `x.has_value()` does not equal `y.has_value()`, `false`;
1202
  otherwise if `x.has_value()` is `true`, `*x == *y`; otherwise
1203
  `x.error() == y.error()`.
1204
 
1205
  ``` cpp
1206
  template<class T2> friend constexpr bool operator==(const expected& x, const T2& v);
1207
  ```
1208
 
1209
+ *Constraints:* `T2` is not a specialization of `expected`. The
1210
+ expression `*x == v` is well-formed and its result is convertible to
1211
+ `bool`.
1212
 
1213
  [*Note 1*: `T` need not be *Cpp17EqualityComparable*. — *end note*]
1214
 
1215
  *Returns:* `x.has_value() && static_cast<bool>(*x == v)`.
1216
 
1217
  ``` cpp
1218
  template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
1219
  ```
1220
 
1221
+ *Constraints:* The expression `x.error() == e.error()` is well-formed
1222
+ and its result is convertible to `bool`.
1223
 
1224
  *Returns:*
1225
  `!x.has_value() && static_cast<bool>(x.error() == e.error())`.
1226
 
1227
  ### Partial specialization of `expected` for `void` types <a id="expected.void">[[expected.void]]</a>
 
1278
 
1279
  // [expected.void.obs], observers
1280
  constexpr explicit operator bool() const noexcept;
1281
  constexpr bool has_value() const noexcept;
1282
  constexpr void operator*() const noexcept;
1283
+ constexpr void value() const &; // freestanding-deleted
1284
+ constexpr void value() &&; // freestanding-deleted
1285
  constexpr const E& error() const & noexcept;
1286
  constexpr E& error() & noexcept;
1287
  constexpr const E&& error() const && noexcept;
1288
  constexpr E&& error() && noexcept;
1289
  template<class G = E> constexpr E error_or(G&&) const &;
 
1320
  };
1321
  };
1322
  ```
1323
 
1324
  Any object of type `expected<T, E>` either represents a value of type
1325
+ `T`, or contains a value of type `E` nested within [[intro.object]] it.
1326
+ Member *`has_val`* indicates whether the `expected<T, E>` object
1327
+ represents a value of type `T`.
 
 
1328
 
1329
  A program that instantiates the definition of the template
1330
  `expected<T, E>` with a type for the `E` parameter that is not a valid
1331
  template argument for `unexpected` is ill-formed.
1332
 
 
1491
 
1492
  ``` cpp
1493
  constexpr expected& operator=(expected&& rhs) noexcept(see below);
1494
  ```
1495
 
1496
+ *Constraints:* `is_move_constructible_v<E>` is `true` and
1497
+ `is_move_assignable_v<E>` is `true`.
1498
+
1499
  *Effects:*
1500
 
1501
  - If `this->has_value() && rhs.has_value()` is `true`, no effects.
1502
  - Otherwise, if `this->has_value()` is `true`, equivalent to:
1503
  ``` cpp
 
1511
  *Returns:* `*this`.
1512
 
1513
  *Remarks:* The exception specification is equivalent to
1514
  `is_nothrow_move_constructible_v<E> && is_nothrow_move_assignable_v<E>`.
1515
 
 
 
 
1516
  ``` cpp
1517
  template<class G>
1518
  constexpr expected& operator=(const unexpected<G>& e);
1519
  template<class G>
1520
  constexpr expected& operator=(unexpected<G>&& e);
 
1559
 
1560
  | \topline | `this->has_value()` | `!this->has_value()` |
1561
  | -------- | ------------------- | -------------------- |
1562
 
1563
 
1564
+ For the case where `rhs.has_value()` is `false` and `this->has_value()`
1565
+ is `true`, equivalent to:
1566
 
1567
  ``` cpp
1568
  construct_at(addressof(unex), std::move(rhs.unex));
1569
  destroy_at(addressof(rhs.unex));
1570
  has_val = false;
 
1593
 
1594
  ``` cpp
1595
  constexpr void operator*() const noexcept;
1596
  ```
1597
 
1598
+ `has_value()` is `true`.
1599
 
1600
  ``` cpp
1601
  constexpr void value() const &;
1602
  ```
1603
 
1604
+ *Mandates:* `is_copy_constructible_v<E>` is `true`.
1605
+
1606
  *Throws:* `bad_expected_access(error())` if `has_value()` is `false`.
1607
 
1608
  ``` cpp
1609
  constexpr void value() &&;
1610
  ```
1611
 
1612
+ *Mandates:* `is_copy_constructible_v<E>` is `true` and
1613
+ `is_move_constructible_v<E>` is `true`.
1614
+
1615
  *Throws:* `bad_expected_access(std::move(error()))` if `has_value()` is
1616
  `false`.
1617
 
1618
  ``` cpp
1619
  constexpr const E& error() const & noexcept;
1620
  constexpr E& error() & noexcept;
1621
  ```
1622
 
1623
+ `has_value()` is `false`.
1624
 
1625
  *Returns:* *unex*.
1626
 
1627
  ``` cpp
1628
  constexpr E&& error() && noexcept;
1629
  constexpr const E&& error() const && noexcept;
1630
  ```
1631
 
1632
+ `has_value()` is `false`.
1633
 
1634
  *Returns:* `std::move(`*`unex`*`)`.
1635
 
1636
  ``` cpp
1637
  template<class G = E> constexpr E error_or(G&& e) const &;
 
1663
  Let `U` be `remove_cvref_t<invoke_result_t<F>>`.
1664
 
1665
  *Constraints:* `is_constructible_v<E, decltype(error())>>` is `true`.
1666
 
1667
  *Mandates:* `U` is a specialization of `expected` and
1668
+ `is_same_v<typename U::error_type, E>` is `true`.
1669
 
1670
  *Effects:* Equivalent to:
1671
 
1672
  ``` cpp
1673
  if (has_value())
 
1685
 
1686
  *Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
1687
  `true`.
1688
 
1689
  *Mandates:* `U` is a specialization of `expected` and
1690
+ `is_same_v<typename U::error_type, E>` is `true`.
1691
 
1692
  *Effects:* Equivalent to:
1693
 
1694
  ``` cpp
1695
  if (has_value())
 
1704
  ```
1705
 
1706
  Let `G` be `remove_cvref_t<invoke_result_t<F, decltype(error())>>`.
1707
 
1708
  *Mandates:* `G` is a specialization of `expected` and
1709
+ `is_same_v<typename G::value_type, T>` is `true`.
1710
 
1711
  *Effects:* Equivalent to:
1712
 
1713
  ``` cpp
1714
  if (has_value())
 
1724
 
1725
  Let `G` be
1726
  `remove_cvref_t<invoke_result_t<F, decltype(std::move(error()))>>`.
1727
 
1728
  *Mandates:* `G` is a specialization of `expected` and
1729
+ `is_same_v<typename G::value_type, T>` is `true`.
1730
 
1731
  *Effects:* Equivalent to:
1732
 
1733
  ``` cpp
1734
  if (has_value())
 
1842
  ``` cpp
1843
  template<class T2, class E2> requires is_void_v<T2>
1844
  friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
1845
  ```
1846
 
1847
+ *Constraints:* The expression `x.error() == y.error()` is well-formed
1848
+ and its result is convertible to `bool`.
1849
 
1850
  *Returns:* If `x.has_value()` does not equal `y.has_value()`, `false`;
1851
  otherwise `x.has_value() || static_cast<bool>(x.error() == y.error())`.
1852
 
1853
  ``` cpp
1854
  template<class E2>
1855
  friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
1856
  ```
1857
 
1858
+ *Constraints:* The expression `x.error() == e.error()` is well-formed
1859
+ and its result is convertible to `bool`.
1860
 
1861
  *Returns:*
1862
  `!x.has_value() && static_cast<bool>(x.error() == e.error())`.
1863