2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___EXPECTED_EXPECTED_H
10 #define _LIBCPP___EXPECTED_EXPECTED_H
14 #include <__expected/bad_expected_access.h>
15 #include <__expected/unexpect.h>
16 #include <__expected/unexpected.h>
17 #include <__functional/invoke.h>
18 #include <__memory/addressof.h>
19 #include <__memory/construct_at.h>
20 #include <__type_traits/conjunction.h>
21 #include <__type_traits/disjunction.h>
22 #include <__type_traits/integral_constant.h>
23 #include <__type_traits/is_assignable.h>
24 #include <__type_traits/is_constructible.h>
25 #include <__type_traits/is_convertible.h>
26 #include <__type_traits/is_copy_assignable.h>
27 #include <__type_traits/is_copy_constructible.h>
28 #include <__type_traits/is_default_constructible.h>
29 #include <__type_traits/is_function.h>
30 #include <__type_traits/is_move_assignable.h>
31 #include <__type_traits/is_move_constructible.h>
32 #include <__type_traits/is_nothrow_constructible.h>
33 #include <__type_traits/is_nothrow_copy_assignable.h>
34 #include <__type_traits/is_nothrow_copy_constructible.h>
35 #include <__type_traits/is_nothrow_default_constructible.h>
36 #include <__type_traits/is_nothrow_move_assignable.h>
37 #include <__type_traits/is_nothrow_move_constructible.h>
38 #include <__type_traits/is_reference.h>
39 #include <__type_traits/is_same.h>
40 #include <__type_traits/is_swappable.h>
41 #include <__type_traits/is_trivially_copy_constructible.h>
42 #include <__type_traits/is_trivially_destructible.h>
43 #include <__type_traits/is_trivially_move_constructible.h>
44 #include <__type_traits/is_void.h>
45 #include <__type_traits/lazy.h>
46 #include <__type_traits/negation.h>
47 #include <__type_traits/remove_cv.h>
48 #include <__type_traits/remove_cvref.h>
49 #include <__utility/as_const.h>
50 #include <__utility/exception_guard.h>
51 #include <__utility/forward.h>
52 #include <__utility/in_place.h>
53 #include <__utility/move.h>
54 #include <__utility/swap.h>
55 #include <__verbose_abort>
56 #include <initializer_list>
58 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
59 # pragma GCC system_header
63 #include <__undef_macros>
65 #if _LIBCPP_STD_VER >= 23
67 _LIBCPP_BEGIN_NAMESPACE_STD
69 template <class _Tp
, class _Err
>
73 struct __is_std_expected
: false_type
{};
75 template <class _Tp
, class _Err
>
76 struct __is_std_expected
<expected
<_Tp
, _Err
>> : true_type
{};
78 struct __expected_construct_in_place_from_invoke_tag
{};
79 struct __expected_construct_unexpected_from_invoke_tag
{};
81 template <class _Err
, class _Arg
>
82 _LIBCPP_HIDE_FROM_ABI
void __throw_bad_expected_access(_Arg
&& __arg
) {
83 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
84 throw bad_expected_access
<_Err
>(std::forward
<_Arg
>(__arg
));
87 _LIBCPP_VERBOSE_ABORT("bad_expected_access was thrown in -fno-exceptions mode");
91 template <class _Tp
, class _Err
>
94 !is_reference_v
<_Tp
> &&
95 !is_function_v
<_Tp
> &&
96 !is_same_v
<remove_cv_t
<_Tp
>, in_place_t
> &&
97 !is_same_v
<remove_cv_t
<_Tp
>, unexpect_t
> &&
98 !__is_std_unexpected
<remove_cv_t
<_Tp
>>::value
&&
99 __valid_std_unexpected
<_Err
>::value
101 "[expected.object.general] A program that instantiates the definition of template expected<T, E> for a "
102 "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a "
103 "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the "
104 "definition of the template expected<T, E> with a type for the E parameter that is not a valid "
105 "template argument for unexpected is ill-formed.");
107 template <class _Up
, class _OtherErr
>
108 friend class expected
;
111 using value_type
= _Tp
;
112 using error_type
= _Err
;
113 using unexpected_type
= unexpected
<_Err
>;
116 using rebind
= expected
<_Up
, error_type
>;
118 // [expected.object.ctor], constructors
119 _LIBCPP_HIDE_FROM_ABI
constexpr expected()
120 noexcept(is_nothrow_default_constructible_v
<_Tp
>) // strengthened
121 requires is_default_constructible_v
<_Tp
>
122 : __union_(std::in_place
), __has_val_(true) {}
124 _LIBCPP_HIDE_FROM_ABI
constexpr expected(const expected
&) = delete;
126 _LIBCPP_HIDE_FROM_ABI
constexpr expected(const expected
&)
127 requires(is_copy_constructible_v
<_Tp
> &&
128 is_copy_constructible_v
<_Err
> &&
129 is_trivially_copy_constructible_v
<_Tp
> &&
130 is_trivially_copy_constructible_v
<_Err
>)
133 _LIBCPP_HIDE_FROM_ABI
constexpr expected(const expected
& __other
)
134 noexcept(is_nothrow_copy_constructible_v
<_Tp
> && is_nothrow_copy_constructible_v
<_Err
>) // strengthened
135 requires(is_copy_constructible_v
<_Tp
> && is_copy_constructible_v
<_Err
> &&
136 !(is_trivially_copy_constructible_v
<_Tp
> && is_trivially_copy_constructible_v
<_Err
>))
137 : __union_(__other
.__has_val_
, __other
.__union_
), __has_val_(__other
.__has_val_
) { }
139 _LIBCPP_HIDE_FROM_ABI
constexpr expected(expected
&&)
140 requires(is_move_constructible_v
<_Tp
> && is_move_constructible_v
<_Err
>
141 && is_trivially_move_constructible_v
<_Tp
> && is_trivially_move_constructible_v
<_Err
>)
144 _LIBCPP_HIDE_FROM_ABI
constexpr expected(expected
&& __other
)
145 noexcept(is_nothrow_move_constructible_v
<_Tp
> && is_nothrow_move_constructible_v
<_Err
>)
146 requires(is_move_constructible_v
<_Tp
> && is_move_constructible_v
<_Err
> &&
147 !(is_trivially_move_constructible_v
<_Tp
> && is_trivially_move_constructible_v
<_Err
>))
148 : __union_(__other
.__has_val_
, std::move(__other
.__union_
)), __has_val_(__other
.__has_val_
) { }
151 template <class _Up
, class _OtherErr
, class _UfQual
, class _OtherErrQual
>
152 using __can_convert
=
153 _And
< is_constructible
<_Tp
, _UfQual
>,
154 is_constructible
<_Err
, _OtherErrQual
>,
155 _If
<_Not
<is_same
<remove_cv_t
<_Tp
>, bool>>::value
,
156 _And
< _Not
<is_constructible
<_Tp
, expected
<_Up
, _OtherErr
>&>>,
157 _Not
<is_constructible
<_Tp
, expected
<_Up
, _OtherErr
>>>,
158 _Not
<is_constructible
<_Tp
, const expected
<_Up
, _OtherErr
>&>>,
159 _Not
<is_constructible
<_Tp
, const expected
<_Up
, _OtherErr
>>>,
160 _Not
<is_convertible
<expected
<_Up
, _OtherErr
>&, _Tp
>>,
161 _Not
<is_convertible
<expected
<_Up
, _OtherErr
>&&, _Tp
>>,
162 _Not
<is_convertible
<const expected
<_Up
, _OtherErr
>&, _Tp
>>,
163 _Not
<is_convertible
<const expected
<_Up
, _OtherErr
>&&, _Tp
>>>,
165 _Not
<is_constructible
<unexpected
<_Err
>, expected
<_Up
, _OtherErr
>&>>,
166 _Not
<is_constructible
<unexpected
<_Err
>, expected
<_Up
, _OtherErr
>>>,
167 _Not
<is_constructible
<unexpected
<_Err
>, const expected
<_Up
, _OtherErr
>&>>,
168 _Not
<is_constructible
<unexpected
<_Err
>, const expected
<_Up
, _OtherErr
>>> >;
170 template <class _Func
, class... _Args
>
171 _LIBCPP_HIDE_FROM_ABI
constexpr explicit expected(
172 std::__expected_construct_in_place_from_invoke_tag __tag
, _Func
&& __f
, _Args
&&... __args
)
173 : __union_(__tag
, std::forward
<_Func
>(__f
), std::forward
<_Args
>(__args
)...), __has_val_(true) {}
175 template <class _Func
, class... _Args
>
176 _LIBCPP_HIDE_FROM_ABI
constexpr explicit expected(
177 std::__expected_construct_unexpected_from_invoke_tag __tag
, _Func
&& __f
, _Args
&&... __args
)
178 : __union_(__tag
, std::forward
<_Func
>(__f
), std::forward
<_Args
>(__args
)...), __has_val_(false) {}
181 template <class _Up
, class _OtherErr
>
182 requires __can_convert
<_Up
, _OtherErr
, const _Up
&, const _OtherErr
&>::value
183 _LIBCPP_HIDE_FROM_ABI
constexpr explicit(!is_convertible_v
<const _Up
&, _Tp
> ||
184 !is_convertible_v
<const _OtherErr
&, _Err
>)
185 expected(const expected
<_Up
, _OtherErr
>& __other
)
186 noexcept(is_nothrow_constructible_v
<_Tp
, const _Up
&> &&
187 is_nothrow_constructible_v
<_Err
, const _OtherErr
&>) // strengthened
188 : __union_(__other
.__has_val_
, __other
.__union_
), __has_val_(__other
.__has_val_
) {}
190 template <class _Up
, class _OtherErr
>
191 requires __can_convert
<_Up
, _OtherErr
, _Up
, _OtherErr
>::value
192 _LIBCPP_HIDE_FROM_ABI
constexpr explicit(!is_convertible_v
<_Up
, _Tp
> || !is_convertible_v
<_OtherErr
, _Err
>)
193 expected(expected
<_Up
, _OtherErr
>&& __other
)
194 noexcept(is_nothrow_constructible_v
<_Tp
, _Up
> && is_nothrow_constructible_v
<_Err
, _OtherErr
>) // strengthened
195 : __union_(__other
.__has_val_
, std::move(__other
.__union_
)), __has_val_(__other
.__has_val_
) {}
197 template <class _Up
= _Tp
>
198 requires(!is_same_v
<remove_cvref_t
<_Up
>, in_place_t
> && !is_same_v
<expected
, remove_cvref_t
<_Up
>> &&
199 is_constructible_v
<_Tp
, _Up
> && !__is_std_unexpected
<remove_cvref_t
<_Up
>>::value
&&
200 (!is_same_v
<remove_cv_t
<_Tp
>, bool> || !__is_std_expected
<remove_cvref_t
<_Up
>>::value
))
201 _LIBCPP_HIDE_FROM_ABI
constexpr explicit(!is_convertible_v
<_Up
, _Tp
>)
202 expected(_Up
&& __u
) noexcept(is_nothrow_constructible_v
<_Tp
, _Up
>) // strengthened
203 : __union_(std::in_place
, std::forward
<_Up
>(__u
)), __has_val_(true) {}
205 template <class _OtherErr
>
206 requires is_constructible_v
<_Err
, const _OtherErr
&>
207 _LIBCPP_HIDE_FROM_ABI
constexpr explicit(!is_convertible_v
<const _OtherErr
&, _Err
>)
208 expected(const unexpected
<_OtherErr
>& __unex
)
209 noexcept(is_nothrow_constructible_v
<_Err
, const _OtherErr
&>) // strengthened
210 : __union_(std::unexpect
, __unex
.error()), __has_val_(false) {}
212 template <class _OtherErr
>
213 requires is_constructible_v
<_Err
, _OtherErr
>
214 _LIBCPP_HIDE_FROM_ABI
constexpr explicit(!is_convertible_v
<_OtherErr
, _Err
>)
215 expected(unexpected
<_OtherErr
>&& __unex
)
216 noexcept(is_nothrow_constructible_v
<_Err
, _OtherErr
>) // strengthened
217 : __union_(std::unexpect
, std::move(__unex
.error())), __has_val_(false) {}
219 template <class... _Args
>
220 requires is_constructible_v
<_Tp
, _Args
...>
221 _LIBCPP_HIDE_FROM_ABI
constexpr explicit expected(in_place_t
, _Args
&&... __args
)
222 noexcept(is_nothrow_constructible_v
<_Tp
, _Args
...>) // strengthened
223 : __union_(std::in_place
, std::forward
<_Args
>(__args
)...), __has_val_(true) {}
225 template <class _Up
, class... _Args
>
226 requires is_constructible_v
< _Tp
, initializer_list
<_Up
>&, _Args
... >
227 _LIBCPP_HIDE_FROM_ABI
constexpr explicit
228 expected(in_place_t
, initializer_list
<_Up
> __il
, _Args
&&... __args
)
229 noexcept(is_nothrow_constructible_v
<_Tp
, initializer_list
<_Up
>&, _Args
...>) // strengthened
230 : __union_(std::in_place
, __il
, std::forward
<_Args
>(__args
)...), __has_val_(true) {}
232 template <class... _Args
>
233 requires is_constructible_v
<_Err
, _Args
...>
234 _LIBCPP_HIDE_FROM_ABI
constexpr explicit expected(unexpect_t
, _Args
&&... __args
)
235 noexcept(is_nothrow_constructible_v
<_Err
, _Args
...>) // strengthened
236 : __union_(std::unexpect
, std::forward
<_Args
>(__args
)...), __has_val_(false) {}
238 template <class _Up
, class... _Args
>
239 requires is_constructible_v
< _Err
, initializer_list
<_Up
>&, _Args
... >
240 _LIBCPP_HIDE_FROM_ABI
constexpr explicit
241 expected(unexpect_t
, initializer_list
<_Up
> __il
, _Args
&&... __args
)
242 noexcept(is_nothrow_constructible_v
<_Err
, initializer_list
<_Up
>&, _Args
...>) // strengthened
243 : __union_(std::unexpect
, __il
, std::forward
<_Args
>(__args
)...), __has_val_(false) {}
245 // [expected.object.dtor], destructor
247 _LIBCPP_HIDE_FROM_ABI
constexpr ~expected()
248 requires(is_trivially_destructible_v
<_Tp
> && is_trivially_destructible_v
<_Err
>)
251 _LIBCPP_HIDE_FROM_ABI
constexpr ~expected()
252 requires(!is_trivially_destructible_v
<_Tp
> || !is_trivially_destructible_v
<_Err
>)
255 std::destroy_at(std::addressof(__union_
.__val_
));
257 std::destroy_at(std::addressof(__union_
.__unex_
));
262 template <class _T1
, class _T2
, class... _Args
>
263 _LIBCPP_HIDE_FROM_ABI
static constexpr void __reinit_expected(_T1
& __newval
, _T2
& __oldval
, _Args
&&... __args
) {
264 if constexpr (is_nothrow_constructible_v
<_T1
, _Args
...>) {
265 std::destroy_at(std::addressof(__oldval
));
266 std::construct_at(std::addressof(__newval
), std::forward
<_Args
>(__args
)...);
267 } else if constexpr (is_nothrow_move_constructible_v
<_T1
>) {
268 _T1
__tmp(std::forward
<_Args
>(__args
)...);
269 std::destroy_at(std::addressof(__oldval
));
270 std::construct_at(std::addressof(__newval
), std::move(__tmp
));
273 is_nothrow_move_constructible_v
<_T2
>,
274 "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can "
275 "be reverted to the previous state in case an exception is thrown during the assignment.");
276 _T2
__tmp(std::move(__oldval
));
277 std::destroy_at(std::addressof(__oldval
));
279 std::__make_exception_guard([&] { std::construct_at(std::addressof(__oldval
), std::move(__tmp
)); });
280 std::construct_at(std::addressof(__newval
), std::forward
<_Args
>(__args
)...);
281 __trans
.__complete();
286 // [expected.object.assign], assignment
287 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(const expected
&) = delete;
289 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(const expected
& __rhs
)
290 noexcept(is_nothrow_copy_assignable_v
<_Tp
> &&
291 is_nothrow_copy_constructible_v
<_Tp
> &&
292 is_nothrow_copy_assignable_v
<_Err
> &&
293 is_nothrow_copy_constructible_v
<_Err
>) // strengthened
294 requires(is_copy_assignable_v
<_Tp
> &&
295 is_copy_constructible_v
<_Tp
> &&
296 is_copy_assignable_v
<_Err
> &&
297 is_copy_constructible_v
<_Err
> &&
298 (is_nothrow_move_constructible_v
<_Tp
> ||
299 is_nothrow_move_constructible_v
<_Err
>))
301 if (__has_val_
&& __rhs
.__has_val_
) {
302 __union_
.__val_
= __rhs
.__union_
.__val_
;
303 } else if (__has_val_
) {
304 __reinit_expected(__union_
.__unex_
, __union_
.__val_
, __rhs
.__union_
.__unex_
);
305 } else if (__rhs
.__has_val_
) {
306 __reinit_expected(__union_
.__val_
, __union_
.__unex_
, __rhs
.__union_
.__val_
);
308 __union_
.__unex_
= __rhs
.__union_
.__unex_
;
310 // note: only reached if no exception+rollback was done inside __reinit_expected
311 __has_val_
= __rhs
.__has_val_
;
315 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(expected
&& __rhs
)
316 noexcept(is_nothrow_move_assignable_v
<_Tp
> &&
317 is_nothrow_move_constructible_v
<_Tp
> &&
318 is_nothrow_move_assignable_v
<_Err
> &&
319 is_nothrow_move_constructible_v
<_Err
>)
320 requires(is_move_constructible_v
<_Tp
> &&
321 is_move_assignable_v
<_Tp
> &&
322 is_move_constructible_v
<_Err
> &&
323 is_move_assignable_v
<_Err
> &&
324 (is_nothrow_move_constructible_v
<_Tp
> ||
325 is_nothrow_move_constructible_v
<_Err
>))
327 if (__has_val_
&& __rhs
.__has_val_
) {
328 __union_
.__val_
= std::move(__rhs
.__union_
.__val_
);
329 } else if (__has_val_
) {
330 __reinit_expected(__union_
.__unex_
, __union_
.__val_
, std::move(__rhs
.__union_
.__unex_
));
331 } else if (__rhs
.__has_val_
) {
332 __reinit_expected(__union_
.__val_
, __union_
.__unex_
, std::move(__rhs
.__union_
.__val_
));
334 __union_
.__unex_
= std::move(__rhs
.__union_
.__unex_
);
336 // note: only reached if no exception+rollback was done inside __reinit_expected
337 __has_val_
= __rhs
.__has_val_
;
341 template <class _Up
= _Tp
>
342 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(_Up
&& __v
)
343 requires(!is_same_v
<expected
, remove_cvref_t
<_Up
>> &&
344 !__is_std_unexpected
<remove_cvref_t
<_Up
>>::value
&&
345 is_constructible_v
<_Tp
, _Up
> &&
346 is_assignable_v
<_Tp
&, _Up
> &&
347 (is_nothrow_constructible_v
<_Tp
, _Up
> ||
348 is_nothrow_move_constructible_v
<_Tp
> ||
349 is_nothrow_move_constructible_v
<_Err
>))
352 __union_
.__val_
= std::forward
<_Up
>(__v
);
354 __reinit_expected(__union_
.__val_
, __union_
.__unex_
, std::forward
<_Up
>(__v
));
361 template <class _OtherErrQual
>
362 static constexpr bool __can_assign_from_unexpected
=
363 _And
< is_constructible
<_Err
, _OtherErrQual
>,
364 is_assignable
<_Err
&, _OtherErrQual
>,
366 is_nothrow_constructible
<_Err
, _OtherErrQual
>,
367 is_nothrow_move_constructible
<_Tp
>,
368 is_nothrow_move_constructible
<_Err
>> >::value
;
371 template <class _OtherErr
>
372 requires(__can_assign_from_unexpected
<const _OtherErr
&>)
373 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(const unexpected
<_OtherErr
>& __un
) {
375 __reinit_expected(__union_
.__unex_
, __union_
.__val_
, __un
.error());
378 __union_
.__unex_
= __un
.error();
383 template <class _OtherErr
>
384 requires(__can_assign_from_unexpected
<_OtherErr
>)
385 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(unexpected
<_OtherErr
>&& __un
) {
387 __reinit_expected(__union_
.__unex_
, __union_
.__val_
, std::move(__un
.error()));
390 __union_
.__unex_
= std::move(__un
.error());
395 template <class... _Args
>
396 requires is_nothrow_constructible_v
<_Tp
, _Args
...>
397 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
& emplace(_Args
&&... __args
) noexcept
{
399 std::destroy_at(std::addressof(__union_
.__val_
));
401 std::destroy_at(std::addressof(__union_
.__unex_
));
403 std::construct_at(std::addressof(__union_
.__val_
), std::forward
<_Args
>(__args
)...);
405 return __union_
.__val_
;
408 template <class _Up
, class... _Args
>
409 requires is_nothrow_constructible_v
< _Tp
, initializer_list
<_Up
>&, _Args
... >
410 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
& emplace(initializer_list
<_Up
> __il
, _Args
&&... __args
) noexcept
{
412 std::destroy_at(std::addressof(__union_
.__val_
));
414 std::destroy_at(std::addressof(__union_
.__unex_
));
416 std::construct_at(std::addressof(__union_
.__val_
), __il
, std::forward
<_Args
>(__args
)...);
418 return __union_
.__val_
;
423 // [expected.object.swap], swap
424 _LIBCPP_HIDE_FROM_ABI
constexpr void swap(expected
& __rhs
)
425 noexcept(is_nothrow_move_constructible_v
<_Tp
> &&
426 is_nothrow_swappable_v
<_Tp
> &&
427 is_nothrow_move_constructible_v
<_Err
> &&
428 is_nothrow_swappable_v
<_Err
>)
429 requires(is_swappable_v
<_Tp
> &&
430 is_swappable_v
<_Err
> &&
431 is_move_constructible_v
<_Tp
> &&
432 is_move_constructible_v
<_Err
> &&
433 (is_nothrow_move_constructible_v
<_Tp
> ||
434 is_nothrow_move_constructible_v
<_Err
>))
436 auto __swap_val_unex_impl
= [&](expected
& __with_val
, expected
& __with_err
) {
437 if constexpr (is_nothrow_move_constructible_v
<_Err
>) {
438 _Err
__tmp(std::move(__with_err
.__union_
.__unex_
));
439 std::destroy_at(std::addressof(__with_err
.__union_
.__unex_
));
440 auto __trans
= std::__make_exception_guard([&] {
441 std::construct_at(std::addressof(__with_err
.__union_
.__unex_
), std::move(__tmp
));
443 std::construct_at(std::addressof(__with_err
.__union_
.__val_
), std::move(__with_val
.__union_
.__val_
));
444 __trans
.__complete();
445 std::destroy_at(std::addressof(__with_val
.__union_
.__val_
));
446 std::construct_at(std::addressof(__with_val
.__union_
.__unex_
), std::move(__tmp
));
448 static_assert(is_nothrow_move_constructible_v
<_Tp
>,
449 "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so "
450 "that it can be reverted to the previous state in case an exception is thrown during swap.");
451 _Tp
__tmp(std::move(__with_val
.__union_
.__val_
));
452 std::destroy_at(std::addressof(__with_val
.__union_
.__val_
));
453 auto __trans
= std::__make_exception_guard([&] {
454 std::construct_at(std::addressof(__with_val
.__union_
.__val_
), std::move(__tmp
));
456 std::construct_at(std::addressof(__with_val
.__union_
.__unex_
), std::move(__with_err
.__union_
.__unex_
));
457 __trans
.__complete();
458 std::destroy_at(std::addressof(__with_err
.__union_
.__unex_
));
459 std::construct_at(std::addressof(__with_err
.__union_
.__val_
), std::move(__tmp
));
461 __with_val
.__has_val_
= false;
462 __with_err
.__has_val_
= true;
466 if (__rhs
.__has_val_
) {
468 swap(__union_
.__val_
, __rhs
.__union_
.__val_
);
470 __swap_val_unex_impl(*this, __rhs
);
473 if (__rhs
.__has_val_
) {
474 __swap_val_unex_impl(__rhs
, *this);
477 swap(__union_
.__unex_
, __rhs
.__union_
.__unex_
);
482 _LIBCPP_HIDE_FROM_ABI
friend constexpr void swap(expected
& __x
, expected
& __y
)
483 noexcept(noexcept(__x
.swap(__y
)))
484 requires requires
{ __x
.swap(__y
); }
489 // [expected.object.obs], observers
490 _LIBCPP_HIDE_FROM_ABI
constexpr const _Tp
* operator->() const noexcept
{
491 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_
, "expected::operator-> requires the expected to contain a value");
492 return std::addressof(__union_
.__val_
);
495 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
* operator->() noexcept
{
496 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_
, "expected::operator-> requires the expected to contain a value");
497 return std::addressof(__union_
.__val_
);
500 _LIBCPP_HIDE_FROM_ABI
constexpr const _Tp
& operator*() const& noexcept
{
501 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_
, "expected::operator* requires the expected to contain a value");
502 return __union_
.__val_
;
505 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
& operator*() & noexcept
{
506 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_
, "expected::operator* requires the expected to contain a value");
507 return __union_
.__val_
;
510 _LIBCPP_HIDE_FROM_ABI
constexpr const _Tp
&& operator*() const&& noexcept
{
511 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_
, "expected::operator* requires the expected to contain a value");
512 return std::move(__union_
.__val_
);
515 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
&& operator*() && noexcept
{
516 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_
, "expected::operator* requires the expected to contain a value");
517 return std::move(__union_
.__val_
);
520 _LIBCPP_HIDE_FROM_ABI
constexpr explicit operator bool() const noexcept
{ return __has_val_
; }
522 _LIBCPP_HIDE_FROM_ABI
constexpr bool has_value() const noexcept
{ return __has_val_
; }
524 _LIBCPP_HIDE_FROM_ABI
constexpr const _Tp
& value() const& {
525 static_assert(is_copy_constructible_v
<_Err
>, "error_type has to be copy constructible");
527 std::__throw_bad_expected_access
<_Err
>(std::as_const(error()));
529 return __union_
.__val_
;
532 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
& value() & {
533 static_assert(is_copy_constructible_v
<_Err
>, "error_type has to be copy constructible");
535 std::__throw_bad_expected_access
<_Err
>(std::as_const(error()));
537 return __union_
.__val_
;
540 _LIBCPP_HIDE_FROM_ABI
constexpr const _Tp
&& value() const&& {
541 static_assert(is_copy_constructible_v
<_Err
> && is_constructible_v
<_Err
, decltype(std::move(error()))>,
542 "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
544 std::__throw_bad_expected_access
<_Err
>(std::move(error()));
546 return std::move(__union_
.__val_
);
549 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
&& value() && {
550 static_assert(is_copy_constructible_v
<_Err
> && is_constructible_v
<_Err
, decltype(std::move(error()))>,
551 "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
553 std::__throw_bad_expected_access
<_Err
>(std::move(error()));
555 return std::move(__union_
.__val_
);
558 _LIBCPP_HIDE_FROM_ABI
constexpr const _Err
& error() const& noexcept
{
559 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_
, "expected::error requires the expected to contain an error");
560 return __union_
.__unex_
;
563 _LIBCPP_HIDE_FROM_ABI
constexpr _Err
& error() & noexcept
{
564 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_
, "expected::error requires the expected to contain an error");
565 return __union_
.__unex_
;
568 _LIBCPP_HIDE_FROM_ABI
constexpr const _Err
&& error() const&& noexcept
{
569 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_
, "expected::error requires the expected to contain an error");
570 return std::move(__union_
.__unex_
);
573 _LIBCPP_HIDE_FROM_ABI
constexpr _Err
&& error() && noexcept
{
574 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_
, "expected::error requires the expected to contain an error");
575 return std::move(__union_
.__unex_
);
579 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
value_or(_Up
&& __v
) const& {
580 static_assert(is_copy_constructible_v
<_Tp
>, "value_type has to be copy constructible");
581 static_assert(is_convertible_v
<_Up
, _Tp
>, "argument has to be convertible to value_type");
582 return __has_val_
? __union_
.__val_
: static_cast<_Tp
>(std::forward
<_Up
>(__v
));
586 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
value_or(_Up
&& __v
) && {
587 static_assert(is_move_constructible_v
<_Tp
>, "value_type has to be move constructible");
588 static_assert(is_convertible_v
<_Up
, _Tp
>, "argument has to be convertible to value_type");
589 return __has_val_
? std::move(__union_
.__val_
) : static_cast<_Tp
>(std::forward
<_Up
>(__v
));
592 template <class _Up
= _Err
>
593 _LIBCPP_HIDE_FROM_ABI
constexpr _Err
error_or(_Up
&& __error
) const& {
594 static_assert(is_copy_constructible_v
<_Err
>, "error_type has to be copy constructible");
595 static_assert(is_convertible_v
<_Up
, _Err
>, "argument has to be convertible to error_type");
597 return std::forward
<_Up
>(__error
);
601 template <class _Up
= _Err
>
602 _LIBCPP_HIDE_FROM_ABI
constexpr _Err
error_or(_Up
&& __error
) && {
603 static_assert(is_move_constructible_v
<_Err
>, "error_type has to be move constructible");
604 static_assert(is_convertible_v
<_Up
, _Err
>, "argument has to be convertible to error_type");
606 return std::forward
<_Up
>(__error
);
607 return std::move(error());
610 // [expected.void.monadic], monadic
611 template <class _Func
>
612 requires is_constructible_v
<_Err
, _Err
&>
613 _LIBCPP_HIDE_FROM_ABI
constexpr auto and_then(_Func
&& __f
) & {
614 using _Up
= remove_cvref_t
<invoke_result_t
<_Func
, _Tp
&>>;
615 static_assert(__is_std_expected
<_Up
>::value
, "The result of f(**this) must be a specialization of std::expected");
616 static_assert(is_same_v
<typename
_Up::error_type
, _Err
>,
617 "The result of f(**this) must have the same error_type as this expected");
619 return std::invoke(std::forward
<_Func
>(__f
), __union_
.__val_
);
621 return _Up(unexpect
, error());
624 template <class _Func
>
625 requires is_constructible_v
<_Err
, const _Err
&>
626 _LIBCPP_HIDE_FROM_ABI
constexpr auto and_then(_Func
&& __f
) const& {
627 using _Up
= remove_cvref_t
<invoke_result_t
<_Func
, const _Tp
&>>;
628 static_assert(__is_std_expected
<_Up
>::value
, "The result of f(**this) must be a specialization of std::expected");
629 static_assert(is_same_v
<typename
_Up::error_type
, _Err
>,
630 "The result of f(**this) must have the same error_type as this expected");
632 return std::invoke(std::forward
<_Func
>(__f
), __union_
.__val_
);
634 return _Up(unexpect
, error());
637 template <class _Func
>
638 requires is_constructible_v
<_Err
, _Err
&&>
639 _LIBCPP_HIDE_FROM_ABI
constexpr auto and_then(_Func
&& __f
) && {
640 using _Up
= remove_cvref_t
<invoke_result_t
<_Func
, _Tp
&&>>;
642 __is_std_expected
<_Up
>::value
, "The result of f(std::move(**this)) must be a specialization of std::expected");
643 static_assert(is_same_v
<typename
_Up::error_type
, _Err
>,
644 "The result of f(std::move(**this)) must have the same error_type as this expected");
646 return std::invoke(std::forward
<_Func
>(__f
), std::move(__union_
.__val_
));
648 return _Up(unexpect
, std::move(error()));
651 template <class _Func
>
652 requires is_constructible_v
<_Err
, const _Err
&&>
653 _LIBCPP_HIDE_FROM_ABI
constexpr auto and_then(_Func
&& __f
) const&& {
654 using _Up
= remove_cvref_t
<invoke_result_t
<_Func
, const _Tp
&&>>;
656 __is_std_expected
<_Up
>::value
, "The result of f(std::move(**this)) must be a specialization of std::expected");
657 static_assert(is_same_v
<typename
_Up::error_type
, _Err
>,
658 "The result of f(std::move(**this)) must have the same error_type as this expected");
660 return std::invoke(std::forward
<_Func
>(__f
), std::move(__union_
.__val_
));
662 return _Up(unexpect
, std::move(error()));
665 template <class _Func
>
666 requires is_constructible_v
<_Tp
, _Tp
&>
667 _LIBCPP_HIDE_FROM_ABI
constexpr auto or_else(_Func
&& __f
) & {
668 using _Gp
= remove_cvref_t
<invoke_result_t
<_Func
, _Err
&>>;
669 static_assert(__is_std_expected
<_Gp
>::value
, "The result of f(error()) must be a specialization of std::expected");
670 static_assert(is_same_v
<typename
_Gp::value_type
, _Tp
>,
671 "The result of f(error()) must have the same value_type as this expected");
673 return _Gp(in_place
, __union_
.__val_
);
675 return std::invoke(std::forward
<_Func
>(__f
), error());
678 template <class _Func
>
679 requires is_constructible_v
<_Tp
, const _Tp
&>
680 _LIBCPP_HIDE_FROM_ABI
constexpr auto or_else(_Func
&& __f
) const& {
681 using _Gp
= remove_cvref_t
<invoke_result_t
<_Func
, const _Err
&>>;
682 static_assert(__is_std_expected
<_Gp
>::value
, "The result of f(error()) must be a specialization of std::expected");
683 static_assert(is_same_v
<typename
_Gp::value_type
, _Tp
>,
684 "The result of f(error()) must have the same value_type as this expected");
686 return _Gp(in_place
, __union_
.__val_
);
688 return std::invoke(std::forward
<_Func
>(__f
), error());
691 template <class _Func
>
692 requires is_constructible_v
<_Tp
, _Tp
&&>
693 _LIBCPP_HIDE_FROM_ABI
constexpr auto or_else(_Func
&& __f
) && {
694 using _Gp
= remove_cvref_t
<invoke_result_t
<_Func
, _Err
&&>>;
696 __is_std_expected
<_Gp
>::value
, "The result of f(std::move(error())) must be a specialization of std::expected");
697 static_assert(is_same_v
<typename
_Gp::value_type
, _Tp
>,
698 "The result of f(std::move(error())) must have the same value_type as this expected");
700 return _Gp(in_place
, std::move(__union_
.__val_
));
702 return std::invoke(std::forward
<_Func
>(__f
), std::move(error()));
705 template <class _Func
>
706 requires is_constructible_v
<_Tp
, const _Tp
&&>
707 _LIBCPP_HIDE_FROM_ABI
constexpr auto or_else(_Func
&& __f
) const&& {
708 using _Gp
= remove_cvref_t
<invoke_result_t
<_Func
, const _Err
&&>>;
710 __is_std_expected
<_Gp
>::value
, "The result of f(std::move(error())) must be a specialization of std::expected");
711 static_assert(is_same_v
<typename
_Gp::value_type
, _Tp
>,
712 "The result of f(std::move(error())) must have the same value_type as this expected");
714 return _Gp(in_place
, std::move(__union_
.__val_
));
716 return std::invoke(std::forward
<_Func
>(__f
), std::move(error()));
719 template <class _Func
>
720 requires is_constructible_v
<_Err
, _Err
&>
721 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform(_Func
&& __f
) & {
722 using _Up
= remove_cv_t
<invoke_result_t
<_Func
, _Tp
&>>;
724 return expected
<_Up
, _Err
>(unexpect
, error());
726 if constexpr (!is_void_v
<_Up
>) {
727 return expected
<_Up
, _Err
>(__expected_construct_in_place_from_invoke_tag
{}, std::forward
<_Func
>(__f
), __union_
.__val_
);
729 std::invoke(std::forward
<_Func
>(__f
), __union_
.__val_
);
730 return expected
<_Up
, _Err
>();
734 template <class _Func
>
735 requires is_constructible_v
<_Err
, const _Err
&>
736 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform(_Func
&& __f
) const& {
737 using _Up
= remove_cv_t
<invoke_result_t
<_Func
, const _Tp
&>>;
739 return expected
<_Up
, _Err
>(unexpect
, error());
741 if constexpr (!is_void_v
<_Up
>) {
742 return expected
<_Up
, _Err
>(__expected_construct_in_place_from_invoke_tag
{}, std::forward
<_Func
>(__f
), __union_
.__val_
);
744 std::invoke(std::forward
<_Func
>(__f
), __union_
.__val_
);
745 return expected
<_Up
, _Err
>();
749 template <class _Func
>
750 requires is_constructible_v
<_Err
, _Err
&&>
751 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform(_Func
&& __f
) && {
752 using _Up
= remove_cv_t
<invoke_result_t
<_Func
, _Tp
&&>>;
754 return expected
<_Up
, _Err
>(unexpect
, std::move(error()));
756 if constexpr (!is_void_v
<_Up
>) {
757 return expected
<_Up
, _Err
>(
758 __expected_construct_in_place_from_invoke_tag
{}, std::forward
<_Func
>(__f
), std::move(__union_
.__val_
));
760 std::invoke(std::forward
<_Func
>(__f
), std::move(__union_
.__val_
));
761 return expected
<_Up
, _Err
>();
765 template <class _Func
>
766 requires is_constructible_v
<_Err
, const _Err
&&>
767 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform(_Func
&& __f
) const&& {
768 using _Up
= remove_cv_t
<invoke_result_t
<_Func
, const _Tp
&&>>;
770 return expected
<_Up
, _Err
>(unexpect
, std::move(error()));
772 if constexpr (!is_void_v
<_Up
>) {
773 return expected
<_Up
, _Err
>(
774 __expected_construct_in_place_from_invoke_tag
{}, std::forward
<_Func
>(__f
), std::move(__union_
.__val_
));
776 std::invoke(std::forward
<_Func
>(__f
), std::move(__union_
.__val_
));
777 return expected
<_Up
, _Err
>();
781 template <class _Func
>
782 requires is_constructible_v
<_Tp
, _Tp
&>
783 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform_error(_Func
&& __f
) & {
784 using _Gp
= remove_cv_t
<invoke_result_t
<_Func
, _Err
&>>;
785 static_assert(__valid_std_unexpected
<_Gp
>::value
,
786 "The result of f(error()) must be a valid template argument for unexpected");
788 return expected
<_Tp
, _Gp
>(in_place
, __union_
.__val_
);
790 return expected
<_Tp
, _Gp
>(__expected_construct_unexpected_from_invoke_tag
{}, std::forward
<_Func
>(__f
), error());
793 template <class _Func
>
794 requires is_constructible_v
<_Tp
, const _Tp
&>
795 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform_error(_Func
&& __f
) const& {
796 using _Gp
= remove_cv_t
<invoke_result_t
<_Func
, const _Err
&>>;
797 static_assert(__valid_std_unexpected
<_Gp
>::value
,
798 "The result of f(error()) must be a valid template argument for unexpected");
800 return expected
<_Tp
, _Gp
>(in_place
, __union_
.__val_
);
802 return expected
<_Tp
, _Gp
>(__expected_construct_unexpected_from_invoke_tag
{}, std::forward
<_Func
>(__f
), error());
805 template <class _Func
>
806 requires is_constructible_v
<_Tp
, _Tp
&&>
807 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform_error(_Func
&& __f
) && {
808 using _Gp
= remove_cv_t
<invoke_result_t
<_Func
, _Err
&&>>;
809 static_assert(__valid_std_unexpected
<_Gp
>::value
,
810 "The result of f(std::move(error())) must be a valid template argument for unexpected");
812 return expected
<_Tp
, _Gp
>(in_place
, std::move(__union_
.__val_
));
814 return expected
<_Tp
, _Gp
>(
815 __expected_construct_unexpected_from_invoke_tag
{}, std::forward
<_Func
>(__f
), std::move(error()));
818 template <class _Func
>
819 requires is_constructible_v
<_Tp
, const _Tp
&&>
820 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform_error(_Func
&& __f
) const&& {
821 using _Gp
= remove_cv_t
<invoke_result_t
<_Func
, const _Err
&&>>;
822 static_assert(__valid_std_unexpected
<_Gp
>::value
,
823 "The result of f(std::move(error())) must be a valid template argument for unexpected");
825 return expected
<_Tp
, _Gp
>(in_place
, std::move(__union_
.__val_
));
827 return expected
<_Tp
, _Gp
>(
828 __expected_construct_unexpected_from_invoke_tag
{}, std::forward
<_Func
>(__f
), std::move(error()));
831 // [expected.object.eq], equality operators
832 template <class _T2
, class _E2
>
833 requires(!is_void_v
<_T2
>)
834 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const expected
& __x
, const expected
<_T2
, _E2
>& __y
) {
835 if (__x
.__has_val_
!= __y
.__has_val_
) {
838 if (__x
.__has_val_
) {
839 return __x
.__union_
.__val_
== __y
.__union_
.__val_
;
841 return __x
.__union_
.__unex_
== __y
.__union_
.__unex_
;
847 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const expected
& __x
, const _T2
& __v
) {
848 return __x
.__has_val_
&& static_cast<bool>(__x
.__union_
.__val_
== __v
);
852 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const expected
& __x
, const unexpected
<_E2
>& __e
) {
853 return !__x
.__has_val_
&& static_cast<bool>(__x
.__union_
.__unex_
== __e
.error());
857 template <class _ValueType
, class _ErrorType
>
859 template <class... _Args
>
860 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(std::in_place_t
, _Args
&&... __args
)
861 : __val_(std::forward
<_Args
>(__args
)...) {}
863 template <class... _Args
>
864 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(std::unexpect_t
, _Args
&&... __args
)
865 : __unex_(std::forward
<_Args
>(__args
)...) {}
867 template <class _Func
, class... _Args
>
868 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(
869 std::__expected_construct_in_place_from_invoke_tag
, _Func
&& __f
, _Args
&&... __args
)
870 : __val_(std::invoke(std::forward
<_Func
>(__f
), std::forward
<_Args
>(__args
)...)) {}
872 template <class _Func
, class... _Args
>
873 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(
874 std::__expected_construct_unexpected_from_invoke_tag
, _Func
&& __f
, _Args
&&... __args
)
875 : __unex_(std::invoke(std::forward
<_Func
>(__f
), std::forward
<_Args
>(__args
)...)) {}
877 template <class _Union
>
878 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(bool __has_val
, _Union
&& __other
) {
880 std::construct_at(std::addressof(__val_
), std::forward
<_Union
>(__other
).__val_
);
882 std::construct_at(std::addressof(__unex_
), std::forward
<_Union
>(__other
).__unex_
);
885 _LIBCPP_HIDE_FROM_ABI
constexpr ~__union_t()
886 requires(is_trivially_destructible_v
<_ValueType
> && is_trivially_destructible_v
<_ErrorType
>)
889 // the expected's destructor handles this
890 _LIBCPP_HIDE_FROM_ABI
constexpr ~__union_t() {}
896 // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
897 // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
898 // it's not clear that it's implementable, given that the function is allowed to clobber
899 // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
900 template <class _ValueType
, class _ErrorType
>
901 requires(is_trivially_move_constructible_v
<_ValueType
> && is_trivially_move_constructible_v
<_ErrorType
>)
902 union __union_t
<_ValueType
, _ErrorType
> {
903 _LIBCPP_HIDE_FROM_ABI
constexpr __union_t(const __union_t
&) = default;
904 _LIBCPP_HIDE_FROM_ABI
constexpr __union_t
& operator=(const __union_t
&) = default;
906 template <class... _Args
>
907 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(std::in_place_t
, _Args
&&... __args
)
908 : __val_(std::forward
<_Args
>(__args
)...) {}
910 template <class... _Args
>
911 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(std::unexpect_t
, _Args
&&... __args
)
912 : __unex_(std::forward
<_Args
>(__args
)...) {}
914 template <class _Func
, class... _Args
>
915 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(
916 std::__expected_construct_in_place_from_invoke_tag
, _Func
&& __f
, _Args
&&... __args
)
917 : __val_(std::invoke(std::forward
<_Func
>(__f
), std::forward
<_Args
>(__args
)...)) {}
919 template <class _Func
, class... _Args
>
920 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(
921 std::__expected_construct_unexpected_from_invoke_tag
, _Func
&& __f
, _Args
&&... __args
)
922 : __unex_(std::invoke(std::forward
<_Func
>(__f
), std::forward
<_Args
>(__args
)...)) {}
924 template <class _Union
>
925 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(bool __has_val
, _Union
&& __other
) {
927 std::construct_at(std::addressof(__val_
), std::forward
<_Union
>(__other
).__val_
);
929 std::construct_at(std::addressof(__unex_
), std::forward
<_Union
>(__other
).__unex_
);
932 _LIBCPP_HIDE_FROM_ABI
constexpr ~__union_t()
933 requires(is_trivially_destructible_v
<_ValueType
> && is_trivially_destructible_v
<_ErrorType
>)
936 // the expected's destructor handles this
937 _LIBCPP_HIDE_FROM_ABI
constexpr ~__union_t()
938 requires(!is_trivially_destructible_v
<_ValueType
> || !is_trivially_destructible_v
<_ErrorType
>)
941 _LIBCPP_NO_UNIQUE_ADDRESS _ValueType __val_
;
942 _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_
;
945 _LIBCPP_NO_UNIQUE_ADDRESS __union_t
<_Tp
, _Err
> __union_
;
949 template <class _Tp
, class _Err
>
950 requires is_void_v
<_Tp
>
951 class expected
<_Tp
, _Err
> {
952 static_assert(__valid_std_unexpected
<_Err
>::value
,
953 "[expected.void.general] A program that instantiates expected<T, E> with a E that is not a "
954 "valid argument for unexpected<E> is ill-formed");
956 template <class, class>
957 friend class expected
;
959 template <class _Up
, class _OtherErr
, class _OtherErrQual
>
960 using __can_convert
=
962 is_constructible
<_Err
, _OtherErrQual
>,
963 _Not
<is_constructible
<unexpected
<_Err
>, expected
<_Up
, _OtherErr
>&>>,
964 _Not
<is_constructible
<unexpected
<_Err
>, expected
<_Up
, _OtherErr
>>>,
965 _Not
<is_constructible
<unexpected
<_Err
>, const expected
<_Up
, _OtherErr
>&>>,
966 _Not
<is_constructible
<unexpected
<_Err
>, const expected
<_Up
, _OtherErr
>>>>;
969 using value_type
= _Tp
;
970 using error_type
= _Err
;
971 using unexpected_type
= unexpected
<_Err
>;
974 using rebind
= expected
<_Up
, error_type
>;
976 // [expected.void.ctor], constructors
977 _LIBCPP_HIDE_FROM_ABI
constexpr expected() noexcept
: __has_val_(true) {}
979 _LIBCPP_HIDE_FROM_ABI
constexpr expected(const expected
&) = delete;
981 _LIBCPP_HIDE_FROM_ABI
constexpr expected(const expected
&)
982 requires(is_copy_constructible_v
<_Err
> && is_trivially_copy_constructible_v
<_Err
>)
985 _LIBCPP_HIDE_FROM_ABI
constexpr expected(const expected
& __rhs
)
986 noexcept(is_nothrow_copy_constructible_v
<_Err
>) // strengthened
987 requires(is_copy_constructible_v
<_Err
> && !is_trivially_copy_constructible_v
<_Err
>)
988 : __union_(__rhs
.__has_val_
, __rhs
.__union_
), __has_val_(__rhs
.__has_val_
) {}
990 _LIBCPP_HIDE_FROM_ABI
constexpr expected(expected
&&)
991 requires(is_move_constructible_v
<_Err
> && is_trivially_move_constructible_v
<_Err
>)
994 _LIBCPP_HIDE_FROM_ABI
constexpr expected(expected
&& __rhs
)
995 noexcept(is_nothrow_move_constructible_v
<_Err
>)
996 requires(is_move_constructible_v
<_Err
> && !is_trivially_move_constructible_v
<_Err
>)
997 : __union_(__rhs
.__has_val_
, std::move(__rhs
.__union_
)), __has_val_(__rhs
.__has_val_
) {}
999 template <class _Up
, class _OtherErr
>
1000 requires __can_convert
<_Up
, _OtherErr
, const _OtherErr
&>::value
1001 _LIBCPP_HIDE_FROM_ABI
constexpr explicit(!is_convertible_v
<const _OtherErr
&, _Err
>)
1002 expected(const expected
<_Up
, _OtherErr
>& __rhs
)
1003 noexcept(is_nothrow_constructible_v
<_Err
, const _OtherErr
&>) // strengthened
1004 : __union_(__rhs
.__has_val_
, __rhs
.__union_
), __has_val_(__rhs
.__has_val_
) {}
1006 template <class _Up
, class _OtherErr
>
1007 requires __can_convert
<_Up
, _OtherErr
, _OtherErr
>::value
1008 _LIBCPP_HIDE_FROM_ABI
constexpr explicit(!is_convertible_v
<_OtherErr
, _Err
>)
1009 expected(expected
<_Up
, _OtherErr
>&& __rhs
)
1010 noexcept(is_nothrow_constructible_v
<_Err
, _OtherErr
>) // strengthened
1011 : __union_(__rhs
.__has_val_
, std::move(__rhs
.__union_
)), __has_val_(__rhs
.__has_val_
) {}
1013 template <class _OtherErr
>
1014 requires is_constructible_v
<_Err
, const _OtherErr
&>
1015 _LIBCPP_HIDE_FROM_ABI
constexpr explicit(!is_convertible_v
<const _OtherErr
&, _Err
>)
1016 expected(const unexpected
<_OtherErr
>& __unex
)
1017 noexcept(is_nothrow_constructible_v
<_Err
, const _OtherErr
&>) // strengthened
1018 : __union_(std::unexpect
, __unex
.error()), __has_val_(false) {}
1020 template <class _OtherErr
>
1021 requires is_constructible_v
<_Err
, _OtherErr
>
1022 _LIBCPP_HIDE_FROM_ABI
constexpr explicit(!is_convertible_v
<_OtherErr
, _Err
>)
1023 expected(unexpected
<_OtherErr
>&& __unex
)
1024 noexcept(is_nothrow_constructible_v
<_Err
, _OtherErr
>) // strengthened
1025 : __union_(std::unexpect
, std::move(__unex
.error())), __has_val_(false) {}
1027 _LIBCPP_HIDE_FROM_ABI
constexpr explicit expected(in_place_t
) noexcept
: __has_val_(true) {}
1029 template <class... _Args
>
1030 requires is_constructible_v
<_Err
, _Args
...>
1031 _LIBCPP_HIDE_FROM_ABI
constexpr explicit expected(unexpect_t
, _Args
&&... __args
)
1032 noexcept(is_nothrow_constructible_v
<_Err
, _Args
...>) // strengthened
1033 : __union_(std::unexpect
, std::forward
<_Args
>(__args
)...), __has_val_(false) {}
1035 template <class _Up
, class... _Args
>
1036 requires is_constructible_v
< _Err
, initializer_list
<_Up
>&, _Args
... >
1037 _LIBCPP_HIDE_FROM_ABI
constexpr explicit expected(unexpect_t
, initializer_list
<_Up
> __il
, _Args
&&... __args
)
1038 noexcept(is_nothrow_constructible_v
<_Err
, initializer_list
<_Up
>&, _Args
...>) // strengthened
1039 : __union_(std::unexpect
, __il
, std::forward
<_Args
>(__args
)...), __has_val_(false) {}
1042 template <class _Func
>
1043 _LIBCPP_HIDE_FROM_ABI
constexpr explicit expected(__expected_construct_in_place_from_invoke_tag
, _Func
&& __f
)
1044 : __has_val_(true) {
1045 std::invoke(std::forward
<_Func
>(__f
));
1048 template <class _Func
, class... _Args
>
1049 _LIBCPP_HIDE_FROM_ABI
constexpr explicit expected(
1050 __expected_construct_unexpected_from_invoke_tag __tag
, _Func
&& __f
, _Args
&&... __args
)
1051 : __union_(__tag
, std::forward
<_Func
>(__f
), std::forward
<_Args
>(__args
)...), __has_val_(false) {}
1054 // [expected.void.dtor], destructor
1056 _LIBCPP_HIDE_FROM_ABI
constexpr ~expected()
1057 requires is_trivially_destructible_v
<_Err
>
1060 _LIBCPP_HIDE_FROM_ABI
constexpr ~expected()
1061 requires(!is_trivially_destructible_v
<_Err
>)
1064 std::destroy_at(std::addressof(__union_
.__unex_
));
1068 // [expected.void.assign], assignment
1070 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(const expected
&) = delete;
1072 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(const expected
& __rhs
)
1073 noexcept(is_nothrow_copy_assignable_v
<_Err
> && is_nothrow_copy_constructible_v
<_Err
>) // strengthened
1074 requires(is_copy_assignable_v
<_Err
> && is_copy_constructible_v
<_Err
>)
1077 if (!__rhs
.__has_val_
) {
1078 std::construct_at(std::addressof(__union_
.__unex_
), __rhs
.__union_
.__unex_
);
1082 if (__rhs
.__has_val_
) {
1083 std::destroy_at(std::addressof(__union_
.__unex_
));
1086 __union_
.__unex_
= __rhs
.__union_
.__unex_
;
1092 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(expected
&&) = delete;
1094 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(expected
&& __rhs
)
1095 noexcept(is_nothrow_move_assignable_v
<_Err
> &&
1096 is_nothrow_move_constructible_v
<_Err
>)
1097 requires(is_move_assignable_v
<_Err
> &&
1098 is_move_constructible_v
<_Err
>)
1101 if (!__rhs
.__has_val_
) {
1102 std::construct_at(std::addressof(__union_
.__unex_
), std::move(__rhs
.__union_
.__unex_
));
1106 if (__rhs
.__has_val_
) {
1107 std::destroy_at(std::addressof(__union_
.__unex_
));
1110 __union_
.__unex_
= std::move(__rhs
.__union_
.__unex_
);
1116 template <class _OtherErr
>
1117 requires(is_constructible_v
<_Err
, const _OtherErr
&> && is_assignable_v
<_Err
&, const _OtherErr
&>)
1118 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(const unexpected
<_OtherErr
>& __un
) {
1120 std::construct_at(std::addressof(__union_
.__unex_
), __un
.error());
1123 __union_
.__unex_
= __un
.error();
1128 template <class _OtherErr
>
1129 requires(is_constructible_v
<_Err
, _OtherErr
> && is_assignable_v
<_Err
&, _OtherErr
>)
1130 _LIBCPP_HIDE_FROM_ABI
constexpr expected
& operator=(unexpected
<_OtherErr
>&& __un
) {
1132 std::construct_at(std::addressof(__union_
.__unex_
), std::move(__un
.error()));
1135 __union_
.__unex_
= std::move(__un
.error());
1140 _LIBCPP_HIDE_FROM_ABI
constexpr void emplace() noexcept
{
1142 std::destroy_at(std::addressof(__union_
.__unex_
));
1147 // [expected.void.swap], swap
1148 _LIBCPP_HIDE_FROM_ABI
constexpr void swap(expected
& __rhs
)
1149 noexcept(is_nothrow_move_constructible_v
<_Err
> && is_nothrow_swappable_v
<_Err
>)
1150 requires(is_swappable_v
<_Err
> && is_move_constructible_v
<_Err
>)
1152 auto __swap_val_unex_impl
= [&](expected
& __with_val
, expected
& __with_err
) {
1153 std::construct_at(std::addressof(__with_val
.__union_
.__unex_
), std::move(__with_err
.__union_
.__unex_
));
1154 std::destroy_at(std::addressof(__with_err
.__union_
.__unex_
));
1155 __with_val
.__has_val_
= false;
1156 __with_err
.__has_val_
= true;
1160 if (!__rhs
.__has_val_
) {
1161 __swap_val_unex_impl(*this, __rhs
);
1164 if (__rhs
.__has_val_
) {
1165 __swap_val_unex_impl(__rhs
, *this);
1168 swap(__union_
.__unex_
, __rhs
.__union_
.__unex_
);
1173 _LIBCPP_HIDE_FROM_ABI
friend constexpr void swap(expected
& __x
, expected
& __y
)
1174 noexcept(noexcept(__x
.swap(__y
)))
1175 requires requires
{ __x
.swap(__y
); }
1180 // [expected.void.obs], observers
1181 _LIBCPP_HIDE_FROM_ABI
constexpr explicit operator bool() const noexcept
{ return __has_val_
; }
1183 _LIBCPP_HIDE_FROM_ABI
constexpr bool has_value() const noexcept
{ return __has_val_
; }
1185 _LIBCPP_HIDE_FROM_ABI
constexpr void operator*() const noexcept
{
1186 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_
, "expected::operator* requires the expected to contain a value");
1189 _LIBCPP_HIDE_FROM_ABI
constexpr void value() const& {
1191 std::__throw_bad_expected_access
<_Err
>(__union_
.__unex_
);
1195 _LIBCPP_HIDE_FROM_ABI
constexpr void value() && {
1197 std::__throw_bad_expected_access
<_Err
>(std::move(__union_
.__unex_
));
1201 _LIBCPP_HIDE_FROM_ABI
constexpr const _Err
& error() const& noexcept
{
1202 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_
, "expected::error requires the expected to contain an error");
1203 return __union_
.__unex_
;
1206 _LIBCPP_HIDE_FROM_ABI
constexpr _Err
& error() & noexcept
{
1207 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_
, "expected::error requires the expected to contain an error");
1208 return __union_
.__unex_
;
1211 _LIBCPP_HIDE_FROM_ABI
constexpr const _Err
&& error() const&& noexcept
{
1212 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_
, "expected::error requires the expected to contain an error");
1213 return std::move(__union_
.__unex_
);
1216 _LIBCPP_HIDE_FROM_ABI
constexpr _Err
&& error() && noexcept
{
1217 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_
, "expected::error requires the expected to contain an error");
1218 return std::move(__union_
.__unex_
);
1221 template <class _Up
= _Err
>
1222 _LIBCPP_HIDE_FROM_ABI
constexpr _Err
error_or(_Up
&& __error
) const& {
1223 static_assert(is_copy_constructible_v
<_Err
>, "error_type has to be copy constructible");
1224 static_assert(is_convertible_v
<_Up
, _Err
>, "argument has to be convertible to error_type");
1226 return std::forward
<_Up
>(__error
);
1231 template <class _Up
= _Err
>
1232 _LIBCPP_HIDE_FROM_ABI
constexpr _Err
error_or(_Up
&& __error
) && {
1233 static_assert(is_move_constructible_v
<_Err
>, "error_type has to be move constructible");
1234 static_assert(is_convertible_v
<_Up
, _Err
>, "argument has to be convertible to error_type");
1236 return std::forward
<_Up
>(__error
);
1238 return std::move(error());
1241 // [expected.void.monadic], monadic
1242 template <class _Func
>
1243 requires is_constructible_v
<_Err
, _Err
&>
1244 _LIBCPP_HIDE_FROM_ABI
constexpr auto and_then(_Func
&& __f
) & {
1245 using _Up
= remove_cvref_t
<invoke_result_t
<_Func
>>;
1246 static_assert(__is_std_expected
<_Up
>::value
, "The result of f() must be a specialization of std::expected");
1248 is_same_v
<typename
_Up::error_type
, _Err
>, "The result of f() must have the same error_type as this expected");
1250 return std::invoke(std::forward
<_Func
>(__f
));
1252 return _Up(unexpect
, error());
1255 template <class _Func
>
1256 requires is_constructible_v
<_Err
, const _Err
&>
1257 _LIBCPP_HIDE_FROM_ABI
constexpr auto and_then(_Func
&& __f
) const& {
1258 using _Up
= remove_cvref_t
<invoke_result_t
<_Func
>>;
1259 static_assert(__is_std_expected
<_Up
>::value
, "The result of f() must be a specialization of std::expected");
1261 is_same_v
<typename
_Up::error_type
, _Err
>, "The result of f() must have the same error_type as this expected");
1263 return std::invoke(std::forward
<_Func
>(__f
));
1265 return _Up(unexpect
, error());
1268 template <class _Func
>
1269 requires is_constructible_v
<_Err
, _Err
&&>
1270 _LIBCPP_HIDE_FROM_ABI
constexpr auto and_then(_Func
&& __f
) && {
1271 using _Up
= remove_cvref_t
<invoke_result_t
<_Func
>>;
1272 static_assert(__is_std_expected
<_Up
>::value
, "The result of f() must be a specialization of std::expected");
1274 is_same_v
<typename
_Up::error_type
, _Err
>, "The result of f() must have the same error_type as this expected");
1276 return std::invoke(std::forward
<_Func
>(__f
));
1278 return _Up(unexpect
, std::move(error()));
1281 template <class _Func
>
1282 requires is_constructible_v
<_Err
, const _Err
&&>
1283 _LIBCPP_HIDE_FROM_ABI
constexpr auto and_then(_Func
&& __f
) const&& {
1284 using _Up
= remove_cvref_t
<invoke_result_t
<_Func
>>;
1285 static_assert(__is_std_expected
<_Up
>::value
, "The result of f() must be a specialization of std::expected");
1287 is_same_v
<typename
_Up::error_type
, _Err
>, "The result of f() must have the same error_type as this expected");
1289 return std::invoke(std::forward
<_Func
>(__f
));
1291 return _Up(unexpect
, std::move(error()));
1294 template <class _Func
>
1295 _LIBCPP_HIDE_FROM_ABI
constexpr auto or_else(_Func
&& __f
) & {
1296 using _Gp
= remove_cvref_t
<invoke_result_t
<_Func
, _Err
&>>;
1297 static_assert(__is_std_expected
<_Gp
>::value
, "The result of f(error()) must be a specialization of std::expected");
1298 static_assert(is_same_v
<typename
_Gp::value_type
, _Tp
>,
1299 "The result of f(error()) must have the same value_type as this expected");
1303 return std::invoke(std::forward
<_Func
>(__f
), error());
1306 template <class _Func
>
1307 _LIBCPP_HIDE_FROM_ABI
constexpr auto or_else(_Func
&& __f
) const& {
1308 using _Gp
= remove_cvref_t
<invoke_result_t
<_Func
, const _Err
&>>;
1309 static_assert(__is_std_expected
<_Gp
>::value
, "The result of f(error()) must be a specialization of std::expected");
1310 static_assert(is_same_v
<typename
_Gp::value_type
, _Tp
>,
1311 "The result of f(error()) must have the same value_type as this expected");
1315 return std::invoke(std::forward
<_Func
>(__f
), error());
1318 template <class _Func
>
1319 _LIBCPP_HIDE_FROM_ABI
constexpr auto or_else(_Func
&& __f
) && {
1320 using _Gp
= remove_cvref_t
<invoke_result_t
<_Func
, _Err
&&>>;
1321 static_assert(__is_std_expected
<_Gp
>::value
,
1322 "The result of f(std::move(error())) must be a specialization of std::expected");
1323 static_assert(is_same_v
<typename
_Gp::value_type
, _Tp
>,
1324 "The result of f(std::move(error())) must have the same value_type as this expected");
1328 return std::invoke(std::forward
<_Func
>(__f
), std::move(error()));
1331 template <class _Func
>
1332 _LIBCPP_HIDE_FROM_ABI
constexpr auto or_else(_Func
&& __f
) const&& {
1333 using _Gp
= remove_cvref_t
<invoke_result_t
<_Func
, const _Err
&&>>;
1334 static_assert(__is_std_expected
<_Gp
>::value
,
1335 "The result of f(std::move(error())) must be a specialization of std::expected");
1336 static_assert(is_same_v
<typename
_Gp::value_type
, _Tp
>,
1337 "The result of f(std::move(error())) must have the same value_type as this expected");
1341 return std::invoke(std::forward
<_Func
>(__f
), std::move(error()));
1344 template <class _Func
>
1345 requires is_constructible_v
<_Err
, _Err
&>
1346 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform(_Func
&& __f
) & {
1347 using _Up
= remove_cv_t
<invoke_result_t
<_Func
>>;
1349 return expected
<_Up
, _Err
>(unexpect
, error());
1351 if constexpr (!is_void_v
<_Up
>) {
1352 return expected
<_Up
, _Err
>(__expected_construct_in_place_from_invoke_tag
{}, std::forward
<_Func
>(__f
));
1354 std::invoke(std::forward
<_Func
>(__f
));
1355 return expected
<_Up
, _Err
>();
1359 template <class _Func
>
1360 requires is_constructible_v
<_Err
, const _Err
&>
1361 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform(_Func
&& __f
) const& {
1362 using _Up
= remove_cv_t
<invoke_result_t
<_Func
>>;
1364 return expected
<_Up
, _Err
>(unexpect
, error());
1366 if constexpr (!is_void_v
<_Up
>) {
1367 return expected
<_Up
, _Err
>(__expected_construct_in_place_from_invoke_tag
{}, std::forward
<_Func
>(__f
));
1369 std::invoke(std::forward
<_Func
>(__f
));
1370 return expected
<_Up
, _Err
>();
1374 template <class _Func
>
1375 requires is_constructible_v
<_Err
, _Err
&&>
1376 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform(_Func
&& __f
) && {
1377 using _Up
= remove_cv_t
<invoke_result_t
<_Func
>>;
1379 return expected
<_Up
, _Err
>(unexpect
, std::move(error()));
1381 if constexpr (!is_void_v
<_Up
>) {
1382 return expected
<_Up
, _Err
>(__expected_construct_in_place_from_invoke_tag
{}, std::forward
<_Func
>(__f
));
1384 std::invoke(std::forward
<_Func
>(__f
));
1385 return expected
<_Up
, _Err
>();
1389 template <class _Func
>
1390 requires is_constructible_v
<_Err
, const _Err
&&>
1391 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform(_Func
&& __f
) const&& {
1392 using _Up
= remove_cv_t
<invoke_result_t
<_Func
>>;
1394 return expected
<_Up
, _Err
>(unexpect
, std::move(error()));
1396 if constexpr (!is_void_v
<_Up
>) {
1397 return expected
<_Up
, _Err
>(__expected_construct_in_place_from_invoke_tag
{}, std::forward
<_Func
>(__f
));
1399 std::invoke(std::forward
<_Func
>(__f
));
1400 return expected
<_Up
, _Err
>();
1404 template <class _Func
>
1405 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform_error(_Func
&& __f
) & {
1406 using _Gp
= remove_cv_t
<invoke_result_t
<_Func
, _Err
&>>;
1407 static_assert(__valid_std_unexpected
<_Gp
>::value
,
1408 "The result of f(error()) must be a valid template argument for unexpected");
1410 return expected
<_Tp
, _Gp
>();
1412 return expected
<_Tp
, _Gp
>(__expected_construct_unexpected_from_invoke_tag
{}, std::forward
<_Func
>(__f
), error());
1415 template <class _Func
>
1416 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform_error(_Func
&& __f
) const& {
1417 using _Gp
= remove_cv_t
<invoke_result_t
<_Func
, const _Err
&>>;
1418 static_assert(__valid_std_unexpected
<_Gp
>::value
,
1419 "The result of f(error()) must be a valid template argument for unexpected");
1421 return expected
<_Tp
, _Gp
>();
1423 return expected
<_Tp
, _Gp
>(__expected_construct_unexpected_from_invoke_tag
{}, std::forward
<_Func
>(__f
), error());
1426 template <class _Func
>
1427 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform_error(_Func
&& __f
) && {
1428 using _Gp
= remove_cv_t
<invoke_result_t
<_Func
, _Err
&&>>;
1429 static_assert(__valid_std_unexpected
<_Gp
>::value
,
1430 "The result of f(std::move(error())) must be a valid template argument for unexpected");
1432 return expected
<_Tp
, _Gp
>();
1434 return expected
<_Tp
, _Gp
>(
1435 __expected_construct_unexpected_from_invoke_tag
{}, std::forward
<_Func
>(__f
), std::move(error()));
1438 template <class _Func
>
1439 _LIBCPP_HIDE_FROM_ABI
constexpr auto transform_error(_Func
&& __f
) const&& {
1440 using _Gp
= remove_cv_t
<invoke_result_t
<_Func
, const _Err
&&>>;
1441 static_assert(__valid_std_unexpected
<_Gp
>::value
,
1442 "The result of f(std::move(error())) must be a valid template argument for unexpected");
1444 return expected
<_Tp
, _Gp
>();
1446 return expected
<_Tp
, _Gp
>(
1447 __expected_construct_unexpected_from_invoke_tag
{}, std::forward
<_Func
>(__f
), std::move(error()));
1450 // [expected.void.eq], equality operators
1451 template <class _T2
, class _E2
>
1452 requires is_void_v
<_T2
>
1453 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const expected
& __x
, const expected
<_T2
, _E2
>& __y
) {
1454 if (__x
.__has_val_
!= __y
.__has_val_
) {
1457 return __x
.__has_val_
|| static_cast<bool>(__x
.__union_
.__unex_
== __y
.__union_
.__unex_
);
1461 template <class _E2
>
1462 _LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const expected
& __x
, const unexpected
<_E2
>& __y
) {
1463 return !__x
.__has_val_
&& static_cast<bool>(__x
.__union_
.__unex_
== __y
.error());
1467 struct __empty_t
{};
1469 template <class _ErrorType
>
1471 _LIBCPP_HIDE_FROM_ABI
constexpr __union_t() : __empty_() {}
1473 template <class... _Args
>
1474 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(std::unexpect_t
, _Args
&&... __args
)
1475 : __unex_(std::forward
<_Args
>(__args
)...) {}
1477 template <class _Func
, class... _Args
>
1478 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(
1479 __expected_construct_unexpected_from_invoke_tag
, _Func
&& __f
, _Args
&&... __args
)
1480 : __unex_(std::invoke(std::forward
<_Func
>(__f
), std::forward
<_Args
>(__args
)...)) {}
1482 template <class _Union
>
1483 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(bool __has_val
, _Union
&& __other
) {
1485 std::construct_at(std::addressof(__empty_
));
1487 std::construct_at(std::addressof(__unex_
), std::forward
<_Union
>(__other
).__unex_
);
1490 _LIBCPP_HIDE_FROM_ABI
constexpr ~__union_t()
1491 requires(is_trivially_destructible_v
<_ErrorType
>)
1494 // the expected's destructor handles this
1495 _LIBCPP_HIDE_FROM_ABI
constexpr ~__union_t() {}
1501 // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
1502 // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
1503 // it's not clear that it's implementable, given that the function is allowed to clobber
1504 // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
1505 template <class _ErrorType
>
1506 requires is_trivially_move_constructible_v
<_ErrorType
>
1507 union __union_t
<_ErrorType
> {
1508 _LIBCPP_HIDE_FROM_ABI
constexpr __union_t() : __empty_() {}
1509 _LIBCPP_HIDE_FROM_ABI
constexpr __union_t(const __union_t
&) = default;
1510 _LIBCPP_HIDE_FROM_ABI
constexpr __union_t
& operator=(const __union_t
&) = default;
1512 template <class... _Args
>
1513 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(std::unexpect_t
, _Args
&&... __args
)
1514 : __unex_(std::forward
<_Args
>(__args
)...) {}
1516 template <class _Func
, class... _Args
>
1517 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(
1518 __expected_construct_unexpected_from_invoke_tag
, _Func
&& __f
, _Args
&&... __args
)
1519 : __unex_(std::invoke(std::forward
<_Func
>(__f
), std::forward
<_Args
>(__args
)...)) {}
1521 template <class _Union
>
1522 _LIBCPP_HIDE_FROM_ABI
constexpr explicit __union_t(bool __has_val
, _Union
&& __other
) {
1524 std::construct_at(std::addressof(__empty_
));
1526 std::construct_at(std::addressof(__unex_
), std::forward
<_Union
>(__other
).__unex_
);
1529 _LIBCPP_HIDE_FROM_ABI
constexpr ~__union_t()
1530 requires(is_trivially_destructible_v
<_ErrorType
>)
1533 // the expected's destructor handles this
1534 _LIBCPP_HIDE_FROM_ABI
constexpr ~__union_t()
1535 requires(!is_trivially_destructible_v
<_ErrorType
>)
1538 _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_
;
1539 _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_
;
1542 _LIBCPP_NO_UNIQUE_ADDRESS __union_t
<_Err
> __union_
;
1546 _LIBCPP_END_NAMESPACE_STD
1548 #endif // _LIBCPP_STD_VER >= 23
1552 #endif // _LIBCPP___EXPECTED_EXPECTED_H