@@ -119,9 +119,7 @@ class expected {
119
119
_LIBCPP_HIDE_FROM_ABI constexpr expected ()
120
120
noexcept (is_nothrow_default_constructible_v<_Tp>) // strengthened
121
121
requires is_default_constructible_v<_Tp>
122
- : __has_val_(true ) {
123
- std::construct_at (std::addressof (__union_.__val_ ));
124
- }
122
+ : __union_(__construct_in_place_tag{}), __has_val_(true ) {}
125
123
126
124
_LIBCPP_HIDE_FROM_ABI constexpr expected (const expected&) = delete;
127
125
@@ -136,14 +134,7 @@ class expected {
136
134
noexcept (is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened
137
135
requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
138
136
!(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>))
139
- : __has_val_(__other.__has_val_) {
140
- if (__has_val_) {
141
- std::construct_at (std::addressof (__union_.__val_ ), __other.__union_ .__val_ );
142
- } else {
143
- std::construct_at (std::addressof (__union_.__unex_ ), __other.__union_ .__unex_ );
144
- }
145
- }
146
-
137
+ : __union_(__union_from_expected(__other)), __has_val_(__other.__has_val_) { }
147
138
148
139
_LIBCPP_HIDE_FROM_ABI constexpr expected (expected&&)
149
140
requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err>
@@ -154,13 +145,7 @@ class expected {
154
145
noexcept (is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>)
155
146
requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
156
147
!(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>))
157
- : __has_val_(__other.__has_val_) {
158
- if (__has_val_) {
159
- std::construct_at (std::addressof (__union_.__val_ ), std::move (__other.__union_ .__val_ ));
160
- } else {
161
- std::construct_at (std::addressof (__union_.__unex_ ), std::move (__other.__union_ .__unex_ ));
162
- }
163
- }
148
+ : __union_(__union_from_expected(std::move(__other))), __has_val_(__other.__has_val_) { }
164
149
165
150
private:
166
151
template <class _Up , class _OtherErr , class _UfQual , class _OtherErrQual >
@@ -200,88 +185,62 @@ class expected {
200
185
expected(const expected<_Up, _OtherErr>& __other)
201
186
noexcept (is_nothrow_constructible_v<_Tp, const _Up&> &&
202
187
is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
203
- : __has_val_(__other.__has_val_) {
204
- if (__has_val_) {
205
- std::construct_at (std::addressof (__union_.__val_ ), __other.__union_ .__val_ );
206
- } else {
207
- std::construct_at (std::addressof (__union_.__unex_ ), __other.__union_ .__unex_ );
208
- }
209
- }
188
+ : __union_(__union_from_expected(__other)), __has_val_(__other.__has_val_) {}
210
189
211
190
template <class _Up , class _OtherErr >
212
191
requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value
213
192
_LIBCPP_HIDE_FROM_ABI constexpr explicit (!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>)
214
193
expected(expected<_Up, _OtherErr>&& __other)
215
194
noexcept (is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
216
- : __has_val_(__other.__has_val_) {
217
- if (__has_val_) {
218
- std::construct_at (std::addressof (__union_.__val_ ), std::move (__other.__union_ .__val_ ));
219
- } else {
220
- std::construct_at (std::addressof (__union_.__unex_ ), std::move (__other.__union_ .__unex_ ));
221
- }
222
- }
195
+ : __union_(__union_from_expected(std::move(__other))), __has_val_(__other.__has_val_) {}
223
196
224
197
template <class _Up = _Tp>
225
198
requires (!is_same_v<remove_cvref_t <_Up>, in_place_t > && !is_same_v<expected, remove_cvref_t <_Up>> &&
226
199
is_constructible_v<_Tp, _Up> && !__is_std_unexpected<remove_cvref_t <_Up>>::value &&
227
200
(!is_same_v<remove_cv_t <_Tp>, bool > || !__is_std_expected<remove_cvref_t <_Up>>::value))
228
201
_LIBCPP_HIDE_FROM_ABI constexpr explicit (!is_convertible_v<_Up, _Tp>)
229
202
expected(_Up&& __u) noexcept (is_nothrow_constructible_v<_Tp, _Up>) // strengthened
230
- : __has_val_(true ) {
231
- std::construct_at (std::addressof (__union_.__val_ ), std::forward<_Up>(__u));
232
- }
203
+ : __union_(__construct_in_place_tag{}, std::forward<_Up>(__u)), __has_val_(true ) {}
233
204
234
205
template <class _OtherErr >
235
206
requires is_constructible_v<_Err, const _OtherErr&>
236
207
_LIBCPP_HIDE_FROM_ABI constexpr explicit (!is_convertible_v<const _OtherErr&, _Err>)
237
208
expected(const unexpected<_OtherErr>& __unex)
238
209
noexcept (is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
239
- : __has_val_(false ) {
240
- std::construct_at (std::addressof (__union_.__unex_ ), __unex.error ());
241
- }
210
+ : __union_(__construct_unexpected_tag{}, __unex.error()), __has_val_(false ) {}
242
211
243
212
template <class _OtherErr >
244
213
requires is_constructible_v<_Err, _OtherErr>
245
214
_LIBCPP_HIDE_FROM_ABI constexpr explicit (!is_convertible_v<_OtherErr, _Err>)
246
215
expected(unexpected<_OtherErr>&& __unex)
247
216
noexcept (is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
248
- : __has_val_(false ) {
249
- std::construct_at (std::addressof (__union_.__unex_ ), std::move (__unex.error ()));
250
- }
217
+ : __union_(__construct_unexpected_tag{}, std::move(__unex.error())), __has_val_(false ) {}
251
218
252
219
template <class ... _Args>
253
220
requires is_constructible_v<_Tp, _Args...>
254
221
_LIBCPP_HIDE_FROM_ABI constexpr explicit expected (in_place_t , _Args&&... __args)
255
222
noexcept (is_nothrow_constructible_v<_Tp, _Args...>) // strengthened
256
- : __has_val_(true ) {
257
- std::construct_at (std::addressof (__union_.__val_ ), std::forward<_Args>(__args)...);
258
- }
223
+ : __union_(__construct_in_place_tag{}, std::forward<_Args>(__args)...), __has_val_(true ) {}
259
224
260
225
template <class _Up , class ... _Args>
261
226
requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... >
262
227
_LIBCPP_HIDE_FROM_ABI constexpr explicit
263
228
expected (in_place_t , initializer_list<_Up> __il, _Args&&... __args)
264
229
noexcept (is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened
265
- : __has_val_(true ) {
266
- std::construct_at (std::addressof (__union_.__val_ ), __il, std::forward<_Args>(__args)...);
267
- }
230
+ : __union_(__construct_in_place_tag{}, __il, std::forward<_Args>(__args)...), __has_val_(true ) {}
268
231
269
232
template <class ... _Args>
270
233
requires is_constructible_v<_Err, _Args...>
271
234
_LIBCPP_HIDE_FROM_ABI constexpr explicit expected (unexpect_t , _Args&&... __args)
272
- noexcept (is_nothrow_constructible_v<_Err, _Args...>) // strengthened
273
- : __has_val_(false ) {
274
- std::construct_at (std::addressof (__union_.__unex_ ), std::forward<_Args>(__args)...);
275
- }
235
+ noexcept (is_nothrow_constructible_v<_Err, _Args...>) // strengthened
236
+ : __union_(__construct_unexpected_tag{}, std::forward<_Args>(__args)...), __has_val_(false ) {}
276
237
277
238
template <class _Up , class ... _Args>
278
239
requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
279
240
_LIBCPP_HIDE_FROM_ABI constexpr explicit
280
241
expected (unexpect_t , initializer_list<_Up> __il, _Args&&... __args)
281
242
noexcept (is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
282
- : __has_val_(false ) {
283
- std::construct_at (std::addressof (__union_.__unex_ ), __il, std::forward<_Args>(__args)...);
284
- }
243
+ : __union_(__construct_unexpected_tag{}, __il, std::forward<_Args>(__args)...), __has_val_(false ) {}
285
244
286
245
// [expected.object.dtor], destructor
287
246
@@ -440,9 +399,10 @@ class expected {
440
399
std::destroy_at (std::addressof (__union_.__val_ ));
441
400
} else {
442
401
std::destroy_at (std::addressof (__union_.__unex_ ));
443
- __has_val_ = true ;
444
402
}
445
- return *std::construct_at (std::addressof (__union_.__val_ ), std::forward<_Args>(__args)...);
403
+ std::construct_at (std::addressof (__union_.__val_ ), std::forward<_Args>(__args)...);
404
+ __has_val_ = true ;
405
+ return *std::addressof (__union_.__val_ );
446
406
}
447
407
448
408
template <class _Up , class ... _Args>
@@ -452,9 +412,10 @@ class expected {
452
412
std::destroy_at (std::addressof (__union_.__val_ ));
453
413
} else {
454
414
std::destroy_at (std::addressof (__union_.__unex_ ));
455
- __has_val_ = true ;
456
415
}
457
- return *std::construct_at (std::addressof (__union_.__val_ ), __il, std::forward<_Args>(__args)...);
416
+ std::construct_at (std::addressof (__union_.__val_ ), __il, std::forward<_Args>(__args)...);
417
+ __has_val_ = true ;
418
+ return *std::addressof (__union_.__val_ );
458
419
}
459
420
460
421
@@ -894,11 +855,21 @@ class expected {
894
855
895
856
private:
896
857
struct __empty_t {};
858
+ struct __construct_in_place_tag {};
859
+ struct __construct_unexpected_tag {};
897
860
898
861
template <class _ValueType , class _ErrorType >
899
862
union __union_t {
900
863
_LIBCPP_HIDE_FROM_ABI constexpr __union_t () {}
901
864
865
+ template <class ... _Args>
866
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t (__construct_in_place_tag, _Args&&... __args)
867
+ : __val_ (std::forward<_Args>(__args)...) {}
868
+
869
+ template <class ... _Args>
870
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t (__construct_unexpected_tag, _Args&&... __args)
871
+ : __unex_ (std::forward<_Args>(__args)...) {}
872
+
902
873
template <class _Func , class ... _Args>
903
874
_LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t (
904
875
std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args)
@@ -931,6 +902,14 @@ class expected {
931
902
_LIBCPP_HIDE_FROM_ABI constexpr __union_t (const __union_t &) = default ;
932
903
_LIBCPP_HIDE_FROM_ABI constexpr __union_t & operator =(const __union_t &) = default ;
933
904
905
+ template <class ... _Args>
906
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t (__construct_in_place_tag, _Args&&... __args)
907
+ : __val_ (std::forward<_Args>(__args)...) {}
908
+
909
+ template <class ... _Args>
910
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t (__construct_unexpected_tag, _Args&&... __args)
911
+ : __unex_ (std::forward<_Args>(__args)...) {}
912
+
934
913
template <class _Func , class ... _Args>
935
914
_LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t (
936
915
std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args)
@@ -955,6 +934,18 @@ class expected {
955
934
_LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_;
956
935
};
957
936
937
+ template <class _Up , class _OtherErr >
938
+ _LIBCPP_HIDE_FROM_ABI constexpr __union_t <_Tp, _Err> __union_from_expected (const expected<_Up, _OtherErr>& __other) {
939
+ return __other.__has_val_ ? __union_t <_Tp, _Err>(__construct_in_place_tag{}, __other.__union_ .__val_ )
940
+ : __union_t <_Tp, _Err>(__construct_unexpected_tag{}, __other.__union_ .__unex_ );
941
+ }
942
+
943
+ template <class _Up , class _OtherErr >
944
+ _LIBCPP_HIDE_FROM_ABI constexpr __union_t <_Tp, _Err> __union_from_expected (expected<_Up, _OtherErr>&& __other) {
945
+ return __other.__has_val_ ? __union_t <_Tp, _Err>(__construct_in_place_tag{}, std::move (__other.__union_ .__val_ ))
946
+ : __union_t <_Tp, _Err>(__construct_unexpected_tag{}, std::move (__other.__union_ .__unex_ ));
947
+ }
948
+
958
949
_LIBCPP_NO_UNIQUE_ADDRESS __union_t <_Tp, _Err> __union_;
959
950
bool __has_val_;
960
951
};
@@ -998,11 +989,7 @@ class expected<_Tp, _Err> {
998
989
_LIBCPP_HIDE_FROM_ABI constexpr expected (const expected& __rhs)
999
990
noexcept (is_nothrow_copy_constructible_v<_Err>) // strengthened
1000
991
requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>)
1001
- : __has_val_(__rhs.__has_val_) {
1002
- if (!__rhs.__has_val_ ) {
1003
- std::construct_at (std::addressof (__union_.__unex_ ), __rhs.__union_ .__unex_ );
1004
- }
1005
- }
992
+ : __union_(__union_from_expected(__rhs)), __has_val_(__rhs.__has_val_) {}
1006
993
1007
994
_LIBCPP_HIDE_FROM_ABI constexpr expected (expected&&)
1008
995
requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
@@ -1011,69 +998,49 @@ class expected<_Tp, _Err> {
1011
998
_LIBCPP_HIDE_FROM_ABI constexpr expected (expected&& __rhs)
1012
999
noexcept (is_nothrow_move_constructible_v<_Err>)
1013
1000
requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>)
1014
- : __has_val_(__rhs.__has_val_) {
1015
- if (!__rhs.__has_val_ ) {
1016
- std::construct_at (std::addressof (__union_.__unex_ ), std::move (__rhs.__union_ .__unex_ ));
1017
- }
1018
- }
1001
+ : __union_(__union_from_expected(std::move(__rhs))), __has_val_(__rhs.__has_val_) {}
1019
1002
1020
1003
template <class _Up , class _OtherErr >
1021
1004
requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value
1022
1005
_LIBCPP_HIDE_FROM_ABI constexpr explicit (!is_convertible_v<const _OtherErr&, _Err>)
1023
1006
expected(const expected<_Up, _OtherErr>& __rhs)
1024
1007
noexcept (is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
1025
- : __has_val_(__rhs.__has_val_) {
1026
- if (!__rhs.__has_val_ ) {
1027
- std::construct_at (std::addressof (__union_.__unex_ ), __rhs.__union_ .__unex_ );
1028
- }
1029
- }
1008
+ : __union_(__union_from_expected(__rhs)), __has_val_(__rhs.__has_val_) {}
1030
1009
1031
1010
template <class _Up , class _OtherErr >
1032
1011
requires __can_convert<_Up, _OtherErr, _OtherErr>::value
1033
1012
_LIBCPP_HIDE_FROM_ABI constexpr explicit (!is_convertible_v<_OtherErr, _Err>)
1034
1013
expected(expected<_Up, _OtherErr>&& __rhs)
1035
1014
noexcept (is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
1036
- : __has_val_(__rhs.__has_val_) {
1037
- if (!__rhs.__has_val_ ) {
1038
- std::construct_at (std::addressof (__union_.__unex_ ), std::move (__rhs.__union_ .__unex_ ));
1039
- }
1040
- }
1015
+ : __union_(__union_from_expected(std::move(__rhs))), __has_val_(__rhs.__has_val_) {}
1041
1016
1042
1017
template <class _OtherErr >
1043
1018
requires is_constructible_v<_Err, const _OtherErr&>
1044
1019
_LIBCPP_HIDE_FROM_ABI constexpr explicit (!is_convertible_v<const _OtherErr&, _Err>)
1045
1020
expected(const unexpected<_OtherErr>& __unex)
1046
1021
noexcept (is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
1047
- : __has_val_(false ) {
1048
- std::construct_at (std::addressof (__union_.__unex_ ), __unex.error ());
1049
- }
1022
+ : __union_(__construct_unexpected_tag{}, __unex.error()), __has_val_(false ) {}
1050
1023
1051
1024
template <class _OtherErr >
1052
1025
requires is_constructible_v<_Err, _OtherErr>
1053
1026
_LIBCPP_HIDE_FROM_ABI constexpr explicit (!is_convertible_v<_OtherErr, _Err>)
1054
1027
expected(unexpected<_OtherErr>&& __unex)
1055
1028
noexcept (is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
1056
- : __has_val_(false ) {
1057
- std::construct_at (std::addressof (__union_.__unex_ ), std::move (__unex.error ()));
1058
- }
1029
+ : __union_(__construct_unexpected_tag{}, std::move(__unex.error())), __has_val_(false ) {}
1059
1030
1060
1031
_LIBCPP_HIDE_FROM_ABI constexpr explicit expected (in_place_t ) noexcept : __has_val_(true ) {}
1061
1032
1062
1033
template <class ... _Args>
1063
1034
requires is_constructible_v<_Err, _Args...>
1064
1035
_LIBCPP_HIDE_FROM_ABI constexpr explicit expected (unexpect_t , _Args&&... __args)
1065
1036
noexcept (is_nothrow_constructible_v<_Err, _Args...>) // strengthened
1066
- : __has_val_(false ) {
1067
- std::construct_at (std::addressof (__union_.__unex_ ), std::forward<_Args>(__args)...);
1068
- }
1037
+ : __union_(__construct_unexpected_tag{}, std::forward<_Args>(__args)...), __has_val_(false ) {}
1069
1038
1070
1039
template <class _Up , class ... _Args>
1071
1040
requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
1072
1041
_LIBCPP_HIDE_FROM_ABI constexpr explicit expected (unexpect_t , initializer_list<_Up> __il, _Args&&... __args)
1073
1042
noexcept (is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
1074
- : __has_val_(false ) {
1075
- std::construct_at (std::addressof (__union_.__unex_ ), __il, std::forward<_Args>(__args)...);
1076
- }
1043
+ : __union_(__construct_unexpected_tag{}, __il, std::forward<_Args>(__args)...), __has_val_(false ) {}
1077
1044
1078
1045
private:
1079
1046
template <class _Func >
@@ -1502,11 +1469,16 @@ class expected<_Tp, _Err> {
1502
1469
1503
1470
private:
1504
1471
struct __empty_t {};
1472
+ struct __construct_unexpected_tag {};
1505
1473
1506
1474
template <class _ErrorType >
1507
1475
union __union_t {
1508
1476
_LIBCPP_HIDE_FROM_ABI constexpr __union_t () : __empty_ () {}
1509
1477
1478
+ template <class ... _Args>
1479
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t (__construct_unexpected_tag, _Args&&... __args)
1480
+ : __unex_ (std::forward<_Args>(__args)...) {}
1481
+
1510
1482
template <class _Func , class ... _Args>
1511
1483
_LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t (
1512
1484
__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
@@ -1534,6 +1506,10 @@ class expected<_Tp, _Err> {
1534
1506
_LIBCPP_HIDE_FROM_ABI constexpr __union_t (const __union_t &) = default ;
1535
1507
_LIBCPP_HIDE_FROM_ABI constexpr __union_t & operator =(const __union_t &) = default ;
1536
1508
1509
+ template <class ... _Args>
1510
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t (__construct_unexpected_tag, _Args&&... __args)
1511
+ : __unex_ (std::forward<_Args>(__args)...) {}
1512
+
1537
1513
template <class _Func , class ... _Args>
1538
1514
_LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t (
1539
1515
__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
@@ -1552,6 +1528,18 @@ class expected<_Tp, _Err> {
1552
1528
_LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_;
1553
1529
};
1554
1530
1531
+ template <class _Up , class _OtherErr >
1532
+ _LIBCPP_HIDE_FROM_ABI constexpr __union_t <_Err> __union_from_expected (const expected<_Up, _OtherErr>& __other) {
1533
+ return __other.__has_val_ ? __union_t <_Err>()
1534
+ : __union_t <_Err>(__construct_unexpected_tag{}, __other.__union_ .__unex_ );
1535
+ }
1536
+
1537
+ template <class _Up , class _OtherErr >
1538
+ _LIBCPP_HIDE_FROM_ABI constexpr __union_t <_Err> __union_from_expected (expected<_Up, _OtherErr>&& __other) {
1539
+ return __other.__has_val_ ? __union_t <_Err>()
1540
+ : __union_t <_Err>(__construct_unexpected_tag{}, std::move (__other.__union_ .__unex_ ));
1541
+ }
1542
+
1555
1543
_LIBCPP_NO_UNIQUE_ADDRESS __union_t <_Err> __union_;
1556
1544
bool __has_val_;
1557
1545
};
0 commit comments