Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / include / __expected / expected.h
blobbf16c8f720d2681580e8a0da2ff3298c12fc36c8
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
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
7 //
8 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___EXPECTED_EXPECTED_H
10 #define _LIBCPP___EXPECTED_EXPECTED_H
12 #include <__assert>
13 #include <__config>
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
60 #endif
62 _LIBCPP_PUSH_MACROS
63 #include <__undef_macros>
65 #if _LIBCPP_STD_VER >= 23
67 _LIBCPP_BEGIN_NAMESPACE_STD
69 template <class _Tp, class _Err>
70 class expected;
72 template <class _Tp>
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));
85 # else
86 (void)__arg;
87 _LIBCPP_VERBOSE_ABORT("bad_expected_access was thrown in -fno-exceptions mode");
88 # endif
91 template <class _Tp, class _Err>
92 class expected {
93 static_assert(
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;
110 public:
111 using value_type = _Tp;
112 using error_type = _Err;
113 using unexpected_type = unexpected<_Err>;
115 template <class _Up>
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>)
131 = default;
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>)
142 = default;
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_) { }
150 private:
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>>>,
164 true_type>,
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) {}
180 public:
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>)
249 = default;
251 _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
252 requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
254 if (__has_val_) {
255 std::destroy_at(std::addressof(__union_.__val_));
256 } else {
257 std::destroy_at(std::addressof(__union_.__unex_));
261 private:
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));
271 } else {
272 static_assert(
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));
278 auto __trans =
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();
285 public:
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_);
307 } else {
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_;
312 return *this;
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_));
333 } else {
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_;
338 return *this;
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>))
351 if (__has_val_) {
352 __union_.__val_ = std::forward<_Up>(__v);
353 } else {
354 __reinit_expected(__union_.__val_, __union_.__unex_, std::forward<_Up>(__v));
355 __has_val_ = true;
357 return *this;
360 private:
361 template <class _OtherErrQual>
362 static constexpr bool __can_assign_from_unexpected =
363 _And< is_constructible<_Err, _OtherErrQual>,
364 is_assignable<_Err&, _OtherErrQual>,
365 _Lazy<_Or,
366 is_nothrow_constructible<_Err, _OtherErrQual>,
367 is_nothrow_move_constructible<_Tp>,
368 is_nothrow_move_constructible<_Err>> >::value;
370 public:
371 template <class _OtherErr>
372 requires(__can_assign_from_unexpected<const _OtherErr&>)
373 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
374 if (__has_val_) {
375 __reinit_expected(__union_.__unex_, __union_.__val_, __un.error());
376 __has_val_ = false;
377 } else {
378 __union_.__unex_ = __un.error();
380 return *this;
383 template <class _OtherErr>
384 requires(__can_assign_from_unexpected<_OtherErr>)
385 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
386 if (__has_val_) {
387 __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__un.error()));
388 __has_val_ = false;
389 } else {
390 __union_.__unex_ = std::move(__un.error());
392 return *this;
395 template <class... _Args>
396 requires is_nothrow_constructible_v<_Tp, _Args...>
397 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept {
398 if (__has_val_) {
399 std::destroy_at(std::addressof(__union_.__val_));
400 } else {
401 std::destroy_at(std::addressof(__union_.__unex_));
403 std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...);
404 __has_val_ = true;
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 {
411 if (__has_val_) {
412 std::destroy_at(std::addressof(__union_.__val_));
413 } else {
414 std::destroy_at(std::addressof(__union_.__unex_));
416 std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...);
417 __has_val_ = true;
418 return __union_.__val_;
422 public:
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));
447 } else {
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;
465 if (__has_val_) {
466 if (__rhs.__has_val_) {
467 using std::swap;
468 swap(__union_.__val_, __rhs.__union_.__val_);
469 } else {
470 __swap_val_unex_impl(*this, __rhs);
472 } else {
473 if (__rhs.__has_val_) {
474 __swap_val_unex_impl(__rhs, *this);
475 } else {
476 using std::swap;
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); }
486 __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");
526 if (!__has_val_) {
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");
534 if (!__has_val_) {
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()))");
543 if (!__has_val_) {
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()))");
552 if (!__has_val_) {
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_);
578 template <class _Up>
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));
585 template <class _Up>
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");
596 if (has_value())
597 return std::forward<_Up>(__error);
598 return 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");
605 if (has_value())
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");
618 if (has_value()) {
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");
631 if (has_value()) {
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&&>>;
641 static_assert(
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");
645 if (has_value()) {
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&&>>;
655 static_assert(
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");
659 if (has_value()) {
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");
672 if (has_value()) {
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");
685 if (has_value()) {
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&&>>;
695 static_assert(
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");
699 if (has_value()) {
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&&>>;
709 static_assert(
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");
713 if (has_value()) {
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&>>;
723 if (!has_value()) {
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_);
728 } else {
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&>>;
738 if (!has_value()) {
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_);
743 } else {
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&&>>;
753 if (!has_value()) {
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_));
759 } else {
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&&>>;
769 if (!has_value()) {
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_));
775 } else {
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");
787 if (has_value()) {
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");
799 if (has_value()) {
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");
811 if (has_value()) {
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");
824 if (has_value()) {
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_) {
836 return false;
837 } else {
838 if (__x.__has_val_) {
839 return __x.__union_.__val_ == __y.__union_.__val_;
840 } else {
841 return __x.__union_.__unex_ == __y.__union_.__unex_;
846 template <class _T2>
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);
851 template <class _E2>
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());
856 private:
857 template <class _ValueType, class _ErrorType>
858 union __union_t {
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) {
879 if (__has_val)
880 std::construct_at(std::addressof(__val_), std::forward<_Union>(__other).__val_);
881 else
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>)
887 = default;
889 // the expected's destructor handles this
890 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {}
892 _ValueType __val_;
893 _ErrorType __unex_;
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) {
926 if (__has_val)
927 std::construct_at(std::addressof(__val_), std::forward<_Union>(__other).__val_);
928 else
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>)
934 = default;
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_;
946 bool __has_val_;
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 =
961 _And< is_void<_Up>,
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>>>>;
968 public:
969 using value_type = _Tp;
970 using error_type = _Err;
971 using unexpected_type = unexpected<_Err>;
973 template <class _Up>
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>)
983 = default;
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>)
992 = default;
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) {}
1041 private:
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) {}
1053 public:
1054 // [expected.void.dtor], destructor
1056 _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
1057 requires is_trivially_destructible_v<_Err>
1058 = default;
1060 _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
1061 requires(!is_trivially_destructible_v<_Err>)
1063 if (!__has_val_) {
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>)
1076 if (__has_val_) {
1077 if (!__rhs.__has_val_) {
1078 std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_);
1079 __has_val_ = false;
1081 } else {
1082 if (__rhs.__has_val_) {
1083 std::destroy_at(std::addressof(__union_.__unex_));
1084 __has_val_ = true;
1085 } else {
1086 __union_.__unex_ = __rhs.__union_.__unex_;
1089 return *this;
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>)
1100 if (__has_val_) {
1101 if (!__rhs.__has_val_) {
1102 std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_));
1103 __has_val_ = false;
1105 } else {
1106 if (__rhs.__has_val_) {
1107 std::destroy_at(std::addressof(__union_.__unex_));
1108 __has_val_ = true;
1109 } else {
1110 __union_.__unex_ = std::move(__rhs.__union_.__unex_);
1113 return *this;
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) {
1119 if (__has_val_) {
1120 std::construct_at(std::addressof(__union_.__unex_), __un.error());
1121 __has_val_ = false;
1122 } else {
1123 __union_.__unex_ = __un.error();
1125 return *this;
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) {
1131 if (__has_val_) {
1132 std::construct_at(std::addressof(__union_.__unex_), std::move(__un.error()));
1133 __has_val_ = false;
1134 } else {
1135 __union_.__unex_ = std::move(__un.error());
1137 return *this;
1140 _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept {
1141 if (!__has_val_) {
1142 std::destroy_at(std::addressof(__union_.__unex_));
1143 __has_val_ = true;
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;
1159 if (__has_val_) {
1160 if (!__rhs.__has_val_) {
1161 __swap_val_unex_impl(*this, __rhs);
1163 } else {
1164 if (__rhs.__has_val_) {
1165 __swap_val_unex_impl(__rhs, *this);
1166 } else {
1167 using std::swap;
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); }
1177 __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& {
1190 if (!__has_val_) {
1191 std::__throw_bad_expected_access<_Err>(__union_.__unex_);
1195 _LIBCPP_HIDE_FROM_ABI constexpr void value() && {
1196 if (!__has_val_) {
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");
1225 if (has_value()) {
1226 return std::forward<_Up>(__error);
1228 return 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");
1235 if (has_value()) {
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");
1247 static_assert(
1248 is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
1249 if (has_value()) {
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");
1260 static_assert(
1261 is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
1262 if (has_value()) {
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");
1273 static_assert(
1274 is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
1275 if (has_value()) {
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");
1286 static_assert(
1287 is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
1288 if (has_value()) {
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");
1300 if (has_value()) {
1301 return _Gp();
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");
1312 if (has_value()) {
1313 return _Gp();
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");
1325 if (has_value()) {
1326 return _Gp();
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");
1338 if (has_value()) {
1339 return _Gp();
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>>;
1348 if (!has_value()) {
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));
1353 } else {
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>>;
1363 if (!has_value()) {
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));
1368 } else {
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>>;
1378 if (!has_value()) {
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));
1383 } else {
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>>;
1393 if (!has_value()) {
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));
1398 } else {
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");
1409 if (has_value()) {
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");
1420 if (has_value()) {
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");
1431 if (has_value()) {
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");
1443 if (has_value()) {
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_) {
1455 return false;
1456 } else {
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());
1466 private:
1467 struct __empty_t {};
1469 template <class _ErrorType>
1470 union __union_t {
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) {
1484 if (__has_val)
1485 std::construct_at(std::addressof(__empty_));
1486 else
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>)
1492 = default;
1494 // the expected's destructor handles this
1495 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {}
1497 __empty_t __empty_;
1498 _ErrorType __unex_;
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) {
1523 if (__has_val)
1524 std::construct_at(std::addressof(__empty_));
1525 else
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>)
1531 = default;
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_;
1543 bool __has_val_;
1546 _LIBCPP_END_NAMESPACE_STD
1548 #endif // _LIBCPP_STD_VER >= 23
1550 _LIBCPP_POP_MACROS
1552 #endif // _LIBCPP___EXPECTED_EXPECTED_H