xref: /freebsd-src/contrib/llvm-project/libcxx/include/__expected/expected.h (revision b121cb0095c8c1a060f66a8c4b118a54ebaa2551)
1bdd1243dSDimitry Andric // -*- C++ -*-
2bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
3bdd1243dSDimitry Andric //
4bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7bdd1243dSDimitry Andric //
8bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
9bdd1243dSDimitry Andric #ifndef _LIBCPP___EXPECTED_EXPECTED_H
10bdd1243dSDimitry Andric #define _LIBCPP___EXPECTED_EXPECTED_H
11bdd1243dSDimitry Andric 
12bdd1243dSDimitry Andric #include <__assert>
13bdd1243dSDimitry Andric #include <__config>
14bdd1243dSDimitry Andric #include <__expected/bad_expected_access.h>
15bdd1243dSDimitry Andric #include <__expected/unexpect.h>
16bdd1243dSDimitry Andric #include <__expected/unexpected.h>
1706c3fb27SDimitry Andric #include <__functional/invoke.h>
18bdd1243dSDimitry Andric #include <__memory/addressof.h>
19bdd1243dSDimitry Andric #include <__memory/construct_at.h>
20bdd1243dSDimitry Andric #include <__type_traits/conjunction.h>
21bdd1243dSDimitry Andric #include <__type_traits/disjunction.h>
2206c3fb27SDimitry Andric #include <__type_traits/integral_constant.h>
23bdd1243dSDimitry Andric #include <__type_traits/is_assignable.h>
24bdd1243dSDimitry Andric #include <__type_traits/is_constructible.h>
25bdd1243dSDimitry Andric #include <__type_traits/is_convertible.h>
26bdd1243dSDimitry Andric #include <__type_traits/is_copy_assignable.h>
27bdd1243dSDimitry Andric #include <__type_traits/is_copy_constructible.h>
28bdd1243dSDimitry Andric #include <__type_traits/is_default_constructible.h>
29bdd1243dSDimitry Andric #include <__type_traits/is_function.h>
30bdd1243dSDimitry Andric #include <__type_traits/is_move_assignable.h>
31bdd1243dSDimitry Andric #include <__type_traits/is_move_constructible.h>
32bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_constructible.h>
33bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_copy_assignable.h>
34bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_copy_constructible.h>
35bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_default_constructible.h>
36bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_move_assignable.h>
37bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_move_constructible.h>
38bdd1243dSDimitry Andric #include <__type_traits/is_reference.h>
39bdd1243dSDimitry Andric #include <__type_traits/is_same.h>
40bdd1243dSDimitry Andric #include <__type_traits/is_swappable.h>
41bdd1243dSDimitry Andric #include <__type_traits/is_trivially_copy_constructible.h>
42bdd1243dSDimitry Andric #include <__type_traits/is_trivially_destructible.h>
43bdd1243dSDimitry Andric #include <__type_traits/is_trivially_move_constructible.h>
44bdd1243dSDimitry Andric #include <__type_traits/is_void.h>
45bdd1243dSDimitry Andric #include <__type_traits/lazy.h>
46bdd1243dSDimitry Andric #include <__type_traits/negation.h>
47bdd1243dSDimitry Andric #include <__type_traits/remove_cv.h>
48bdd1243dSDimitry Andric #include <__type_traits/remove_cvref.h>
4906c3fb27SDimitry Andric #include <__utility/as_const.h>
50bdd1243dSDimitry Andric #include <__utility/exception_guard.h>
51bdd1243dSDimitry Andric #include <__utility/forward.h>
52bdd1243dSDimitry Andric #include <__utility/in_place.h>
53bdd1243dSDimitry Andric #include <__utility/move.h>
54bdd1243dSDimitry Andric #include <__utility/swap.h>
5506c3fb27SDimitry Andric #include <__verbose_abort>
56bdd1243dSDimitry Andric #include <initializer_list>
57bdd1243dSDimitry Andric 
58bdd1243dSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
59bdd1243dSDimitry Andric #  pragma GCC system_header
60bdd1243dSDimitry Andric #endif
61bdd1243dSDimitry Andric 
6206c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS
6306c3fb27SDimitry Andric #include <__undef_macros>
6406c3fb27SDimitry Andric 
65bdd1243dSDimitry Andric #if _LIBCPP_STD_VER >= 23
66bdd1243dSDimitry Andric 
67bdd1243dSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
68bdd1243dSDimitry Andric 
6906c3fb27SDimitry Andric template <class _Tp, class _Err>
7006c3fb27SDimitry Andric class expected;
7106c3fb27SDimitry Andric 
7206c3fb27SDimitry Andric template <class _Tp>
7306c3fb27SDimitry Andric struct __is_std_expected : false_type {};
7406c3fb27SDimitry Andric 
7506c3fb27SDimitry Andric template <class _Tp, class _Err>
7606c3fb27SDimitry Andric struct __is_std_expected<expected<_Tp, _Err>> : true_type {};
7706c3fb27SDimitry Andric 
7806c3fb27SDimitry Andric struct __expected_construct_in_place_from_invoke_tag {};
7906c3fb27SDimitry Andric struct __expected_construct_unexpected_from_invoke_tag {};
80bdd1243dSDimitry Andric 
81bdd1243dSDimitry Andric template <class _Err, class _Arg>
82bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) {
8306c3fb27SDimitry Andric #  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
84bdd1243dSDimitry Andric   throw bad_expected_access<_Err>(std::forward<_Arg>(__arg));
85bdd1243dSDimitry Andric #  else
86bdd1243dSDimitry Andric   (void)__arg;
8706c3fb27SDimitry Andric   _LIBCPP_VERBOSE_ABORT("bad_expected_access was thrown in -fno-exceptions mode");
88bdd1243dSDimitry Andric #  endif
89bdd1243dSDimitry Andric }
90bdd1243dSDimitry Andric 
91bdd1243dSDimitry Andric template <class _Tp, class _Err>
92bdd1243dSDimitry Andric class expected {
93bdd1243dSDimitry Andric   static_assert(
94bdd1243dSDimitry Andric       !is_reference_v<_Tp> &&
95bdd1243dSDimitry Andric           !is_function_v<_Tp> &&
96bdd1243dSDimitry Andric           !is_same_v<remove_cv_t<_Tp>, in_place_t> &&
97bdd1243dSDimitry Andric           !is_same_v<remove_cv_t<_Tp>, unexpect_t> &&
98bdd1243dSDimitry Andric           !__is_std_unexpected<remove_cv_t<_Tp>>::value &&
99bdd1243dSDimitry Andric           __valid_std_unexpected<_Err>::value
100bdd1243dSDimitry Andric       ,
101bdd1243dSDimitry Andric       "[expected.object.general] A program that instantiates the definition of template expected<T, E> for a "
102bdd1243dSDimitry Andric       "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a "
103bdd1243dSDimitry Andric       "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the "
104bdd1243dSDimitry Andric       "definition of the template expected<T, E> with a type for the E parameter that is not a valid "
105bdd1243dSDimitry Andric       "template argument for unexpected is ill-formed.");
106bdd1243dSDimitry Andric 
107bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
108bdd1243dSDimitry Andric   friend class expected;
109bdd1243dSDimitry Andric 
110bdd1243dSDimitry Andric public:
111bdd1243dSDimitry Andric   using value_type      = _Tp;
112bdd1243dSDimitry Andric   using error_type      = _Err;
113bdd1243dSDimitry Andric   using unexpected_type = unexpected<_Err>;
114bdd1243dSDimitry Andric 
115bdd1243dSDimitry Andric   template <class _Up>
116bdd1243dSDimitry Andric   using rebind = expected<_Up, error_type>;
117bdd1243dSDimitry Andric 
118bdd1243dSDimitry Andric   // [expected.object.ctor], constructors
119bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected()
120bdd1243dSDimitry Andric     noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened
121bdd1243dSDimitry Andric     requires is_default_constructible_v<_Tp>
122*b121cb00SDimitry Andric       : __union_(std::in_place), __has_val_(true) {}
123bdd1243dSDimitry Andric 
124bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
125bdd1243dSDimitry Andric 
126bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
127bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Tp> &&
128bdd1243dSDimitry Andric              is_copy_constructible_v<_Err> &&
129bdd1243dSDimitry Andric              is_trivially_copy_constructible_v<_Tp> &&
130bdd1243dSDimitry Andric              is_trivially_copy_constructible_v<_Err>)
131bdd1243dSDimitry Andric   = default;
132bdd1243dSDimitry Andric 
133bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other)
134bdd1243dSDimitry Andric     noexcept(is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened
135bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
136bdd1243dSDimitry Andric              !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>))
137*b121cb00SDimitry Andric       : __union_(__other.__has_val_, __other.__union_), __has_val_(__other.__has_val_) { }
138bdd1243dSDimitry Andric 
139bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
140bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err>
141bdd1243dSDimitry Andric               && is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)
142bdd1243dSDimitry Andric   = default;
143bdd1243dSDimitry Andric 
144bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other)
145bdd1243dSDimitry Andric     noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>)
146bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
147bdd1243dSDimitry Andric              !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>))
148*b121cb00SDimitry Andric       : __union_(__other.__has_val_, std::move(__other.__union_)), __has_val_(__other.__has_val_) { }
149bdd1243dSDimitry Andric 
150bdd1243dSDimitry Andric private:
151bdd1243dSDimitry Andric   template <class _Up, class _OtherErr, class _UfQual, class _OtherErrQual>
152bdd1243dSDimitry Andric   using __can_convert =
153bdd1243dSDimitry Andric       _And< is_constructible<_Tp, _UfQual>,
154bdd1243dSDimitry Andric             is_constructible<_Err, _OtherErrQual>,
155bdd1243dSDimitry Andric             _Not<is_constructible<_Tp, expected<_Up, _OtherErr>&>>,
156bdd1243dSDimitry Andric             _Not<is_constructible<_Tp, expected<_Up, _OtherErr>>>,
157bdd1243dSDimitry Andric             _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>&>>,
158bdd1243dSDimitry Andric             _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>>>,
159bdd1243dSDimitry Andric             _Not<is_convertible<expected<_Up, _OtherErr>&, _Tp>>,
160bdd1243dSDimitry Andric             _Not<is_convertible<expected<_Up, _OtherErr>&&, _Tp>>,
161bdd1243dSDimitry Andric             _Not<is_convertible<const expected<_Up, _OtherErr>&, _Tp>>,
162bdd1243dSDimitry Andric             _Not<is_convertible<const expected<_Up, _OtherErr>&&, _Tp>>,
163bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
164bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
165bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
166bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >;
167bdd1243dSDimitry Andric 
16806c3fb27SDimitry Andric   template <class _Func, class... _Args>
16906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
17006c3fb27SDimitry Andric       std::__expected_construct_in_place_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
17106c3fb27SDimitry Andric       : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(true) {}
17206c3fb27SDimitry Andric 
17306c3fb27SDimitry Andric   template <class _Func, class... _Args>
17406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
17506c3fb27SDimitry Andric       std::__expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
17606c3fb27SDimitry Andric       : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {}
177bdd1243dSDimitry Andric 
178bdd1243dSDimitry Andric public:
179bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
180bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value
181bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _Up&, _Tp> ||
182bdd1243dSDimitry Andric                                            !is_convertible_v<const _OtherErr&, _Err>)
183bdd1243dSDimitry Andric   expected(const expected<_Up, _OtherErr>& __other)
184bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Tp, const _Up&> &&
185bdd1243dSDimitry Andric              is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
186*b121cb00SDimitry Andric       : __union_(__other.__has_val_, __other.__union_), __has_val_(__other.__has_val_) {}
187bdd1243dSDimitry Andric 
188bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
189bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value
190bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>)
191bdd1243dSDimitry Andric   expected(expected<_Up, _OtherErr>&& __other)
192bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
193*b121cb00SDimitry Andric       : __union_(__other.__has_val_, std::move(__other.__union_)), __has_val_(__other.__has_val_) {}
194bdd1243dSDimitry Andric 
195bdd1243dSDimitry Andric   template <class _Up = _Tp>
196bdd1243dSDimitry Andric     requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> &&
197bdd1243dSDimitry Andric              !__is_std_unexpected<remove_cvref_t<_Up>>::value && is_constructible_v<_Tp, _Up>)
198bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>)
199*b121cb00SDimitry Andric       expected(_Up&& __u) noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened
200*b121cb00SDimitry Andric       : __union_(std::in_place, std::forward<_Up>(__u)), __has_val_(true) {}
201bdd1243dSDimitry Andric 
202bdd1243dSDimitry Andric 
203bdd1243dSDimitry Andric   template <class _OtherErr>
204bdd1243dSDimitry Andric     requires is_constructible_v<_Err, const _OtherErr&>
205bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
206bdd1243dSDimitry Andric   expected(const unexpected<_OtherErr>& __unex)
207bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
208*b121cb00SDimitry Andric       : __union_(std::unexpect, __unex.error()), __has_val_(false) {}
209bdd1243dSDimitry Andric 
210bdd1243dSDimitry Andric   template <class _OtherErr>
211bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _OtherErr>
212bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
213bdd1243dSDimitry Andric   expected(unexpected<_OtherErr>&& __unex)
214bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
215*b121cb00SDimitry Andric       : __union_(std::unexpect, std::move(__unex.error())), __has_val_(false) {}
216bdd1243dSDimitry Andric 
217bdd1243dSDimitry Andric   template <class... _Args>
218bdd1243dSDimitry Andric     requires is_constructible_v<_Tp, _Args...>
219bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args)
220bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Tp, _Args...>) // strengthened
221*b121cb00SDimitry Andric       : __union_(std::in_place, std::forward<_Args>(__args)...), __has_val_(true) {}
222bdd1243dSDimitry Andric 
223bdd1243dSDimitry Andric   template <class _Up, class... _Args>
224bdd1243dSDimitry Andric     requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... >
225bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit
226bdd1243dSDimitry Andric   expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
227bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened
228*b121cb00SDimitry Andric       : __union_(std::in_place, __il, std::forward<_Args>(__args)...), __has_val_(true) {}
229bdd1243dSDimitry Andric 
230bdd1243dSDimitry Andric   template <class... _Args>
231bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _Args...>
232bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args)
233bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened
234*b121cb00SDimitry Andric       : __union_(std::unexpect, std::forward<_Args>(__args)...), __has_val_(false) {}
235bdd1243dSDimitry Andric 
236bdd1243dSDimitry Andric   template <class _Up, class... _Args>
237bdd1243dSDimitry Andric     requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
238bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit
239bdd1243dSDimitry Andric   expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
240bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
241*b121cb00SDimitry Andric       : __union_(std::unexpect, __il, std::forward<_Args>(__args)...), __has_val_(false) {}
242bdd1243dSDimitry Andric 
243bdd1243dSDimitry Andric   // [expected.object.dtor], destructor
244bdd1243dSDimitry Andric 
245bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
246bdd1243dSDimitry Andric     requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
247bdd1243dSDimitry Andric   = default;
248bdd1243dSDimitry Andric 
249bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
250bdd1243dSDimitry Andric     requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
251bdd1243dSDimitry Andric   {
252bdd1243dSDimitry Andric     if (__has_val_) {
253bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__val_));
254bdd1243dSDimitry Andric     } else {
255bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__unex_));
256bdd1243dSDimitry Andric     }
257bdd1243dSDimitry Andric   }
258bdd1243dSDimitry Andric 
259bdd1243dSDimitry Andric private:
260bdd1243dSDimitry Andric   template <class _T1, class _T2, class... _Args>
261bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr void __reinit_expected(_T1& __newval, _T2& __oldval, _Args&&... __args) {
262bdd1243dSDimitry Andric     if constexpr (is_nothrow_constructible_v<_T1, _Args...>) {
263bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__oldval));
264bdd1243dSDimitry Andric       std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...);
265bdd1243dSDimitry Andric     } else if constexpr (is_nothrow_move_constructible_v<_T1>) {
266bdd1243dSDimitry Andric       _T1 __tmp(std::forward<_Args>(__args)...);
267bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__oldval));
268bdd1243dSDimitry Andric       std::construct_at(std::addressof(__newval), std::move(__tmp));
269bdd1243dSDimitry Andric     } else {
270bdd1243dSDimitry Andric       static_assert(
271bdd1243dSDimitry Andric           is_nothrow_move_constructible_v<_T2>,
272bdd1243dSDimitry Andric           "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can "
273bdd1243dSDimitry Andric           "be reverted to the previous state in case an exception is thrown during the assignment.");
274bdd1243dSDimitry Andric       _T2 __tmp(std::move(__oldval));
275bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__oldval));
2761ac55f4cSDimitry Andric       auto __trans =
2771ac55f4cSDimitry Andric           std::__make_exception_guard([&] { std::construct_at(std::addressof(__oldval), std::move(__tmp)); });
278bdd1243dSDimitry Andric       std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...);
279bdd1243dSDimitry Andric       __trans.__complete();
280bdd1243dSDimitry Andric     }
281bdd1243dSDimitry Andric   }
282bdd1243dSDimitry Andric 
283bdd1243dSDimitry Andric public:
284bdd1243dSDimitry Andric   // [expected.object.assign], assignment
285bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
286bdd1243dSDimitry Andric 
287bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs)
288bdd1243dSDimitry Andric     noexcept(is_nothrow_copy_assignable_v<_Tp> &&
289bdd1243dSDimitry Andric              is_nothrow_copy_constructible_v<_Tp> &&
290bdd1243dSDimitry Andric              is_nothrow_copy_assignable_v<_Err> &&
291bdd1243dSDimitry Andric              is_nothrow_copy_constructible_v<_Err>) // strengthened
292bdd1243dSDimitry Andric     requires(is_copy_assignable_v<_Tp> &&
293bdd1243dSDimitry Andric              is_copy_constructible_v<_Tp> &&
294bdd1243dSDimitry Andric              is_copy_assignable_v<_Err> &&
295bdd1243dSDimitry Andric              is_copy_constructible_v<_Err> &&
296bdd1243dSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> ||
297bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Err>))
298bdd1243dSDimitry Andric   {
299bdd1243dSDimitry Andric     if (__has_val_ && __rhs.__has_val_) {
300bdd1243dSDimitry Andric       __union_.__val_ = __rhs.__union_.__val_;
301bdd1243dSDimitry Andric     } else if (__has_val_) {
302bdd1243dSDimitry Andric       __reinit_expected(__union_.__unex_, __union_.__val_, __rhs.__union_.__unex_);
303bdd1243dSDimitry Andric     } else if (__rhs.__has_val_) {
304bdd1243dSDimitry Andric       __reinit_expected(__union_.__val_, __union_.__unex_, __rhs.__union_.__val_);
305bdd1243dSDimitry Andric     } else {
306bdd1243dSDimitry Andric       __union_.__unex_ = __rhs.__union_.__unex_;
307bdd1243dSDimitry Andric     }
308bdd1243dSDimitry Andric     // note: only reached if no exception+rollback was done inside __reinit_expected
309bdd1243dSDimitry Andric     __has_val_ = __rhs.__has_val_;
310bdd1243dSDimitry Andric     return *this;
311bdd1243dSDimitry Andric   }
312bdd1243dSDimitry Andric 
313bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs)
314bdd1243dSDimitry Andric     noexcept(is_nothrow_move_assignable_v<_Tp> &&
315bdd1243dSDimitry Andric              is_nothrow_move_constructible_v<_Tp> &&
316bdd1243dSDimitry Andric              is_nothrow_move_assignable_v<_Err> &&
317bdd1243dSDimitry Andric              is_nothrow_move_constructible_v<_Err>)
318bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Tp> &&
319bdd1243dSDimitry Andric              is_move_assignable_v<_Tp> &&
320bdd1243dSDimitry Andric              is_move_constructible_v<_Err> &&
321bdd1243dSDimitry Andric              is_move_assignable_v<_Err> &&
322bdd1243dSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> ||
323bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Err>))
324bdd1243dSDimitry Andric   {
325bdd1243dSDimitry Andric     if (__has_val_ && __rhs.__has_val_) {
326bdd1243dSDimitry Andric       __union_.__val_ = std::move(__rhs.__union_.__val_);
327bdd1243dSDimitry Andric     } else if (__has_val_) {
328bdd1243dSDimitry Andric       __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__rhs.__union_.__unex_));
329bdd1243dSDimitry Andric     } else if (__rhs.__has_val_) {
330bdd1243dSDimitry Andric       __reinit_expected(__union_.__val_, __union_.__unex_, std::move(__rhs.__union_.__val_));
331bdd1243dSDimitry Andric     } else {
332bdd1243dSDimitry Andric       __union_.__unex_ = std::move(__rhs.__union_.__unex_);
333bdd1243dSDimitry Andric     }
334bdd1243dSDimitry Andric     // note: only reached if no exception+rollback was done inside __reinit_expected
335bdd1243dSDimitry Andric     __has_val_ = __rhs.__has_val_;
336bdd1243dSDimitry Andric     return *this;
337bdd1243dSDimitry Andric   }
338bdd1243dSDimitry Andric 
339bdd1243dSDimitry Andric   template <class _Up = _Tp>
340bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v)
341bdd1243dSDimitry Andric     requires(!is_same_v<expected, remove_cvref_t<_Up>> &&
342bdd1243dSDimitry Andric              !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
343bdd1243dSDimitry Andric              is_constructible_v<_Tp, _Up> &&
344bdd1243dSDimitry Andric              is_assignable_v<_Tp&, _Up> &&
345bdd1243dSDimitry Andric              (is_nothrow_constructible_v<_Tp, _Up> ||
346bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Tp> ||
347bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Err>))
348bdd1243dSDimitry Andric   {
349bdd1243dSDimitry Andric     if (__has_val_) {
350bdd1243dSDimitry Andric       __union_.__val_ = std::forward<_Up>(__v);
351bdd1243dSDimitry Andric     } else {
352bdd1243dSDimitry Andric       __reinit_expected(__union_.__val_, __union_.__unex_, std::forward<_Up>(__v));
353bdd1243dSDimitry Andric       __has_val_ = true;
354bdd1243dSDimitry Andric     }
355bdd1243dSDimitry Andric     return *this;
356bdd1243dSDimitry Andric   }
357bdd1243dSDimitry Andric 
358bdd1243dSDimitry Andric private:
359bdd1243dSDimitry Andric   template <class _OtherErrQual>
360bdd1243dSDimitry Andric   static constexpr bool __can_assign_from_unexpected =
361bdd1243dSDimitry Andric       _And< is_constructible<_Err, _OtherErrQual>,
362bdd1243dSDimitry Andric             is_assignable<_Err&, _OtherErrQual>,
363bdd1243dSDimitry Andric             _Lazy<_Or,
364bdd1243dSDimitry Andric                   is_nothrow_constructible<_Err, _OtherErrQual>,
365bdd1243dSDimitry Andric                   is_nothrow_move_constructible<_Tp>,
366bdd1243dSDimitry Andric                   is_nothrow_move_constructible<_Err>> >::value;
367bdd1243dSDimitry Andric 
368bdd1243dSDimitry Andric public:
369bdd1243dSDimitry Andric   template <class _OtherErr>
370bdd1243dSDimitry Andric     requires(__can_assign_from_unexpected<const _OtherErr&>)
371bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
372bdd1243dSDimitry Andric     if (__has_val_) {
373bdd1243dSDimitry Andric       __reinit_expected(__union_.__unex_, __union_.__val_, __un.error());
374bdd1243dSDimitry Andric       __has_val_ = false;
375bdd1243dSDimitry Andric     } else {
376bdd1243dSDimitry Andric       __union_.__unex_ = __un.error();
377bdd1243dSDimitry Andric     }
378bdd1243dSDimitry Andric     return *this;
379bdd1243dSDimitry Andric   }
380bdd1243dSDimitry Andric 
381bdd1243dSDimitry Andric   template <class _OtherErr>
382bdd1243dSDimitry Andric     requires(__can_assign_from_unexpected<_OtherErr>)
383bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
384bdd1243dSDimitry Andric     if (__has_val_) {
385bdd1243dSDimitry Andric       __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__un.error()));
386bdd1243dSDimitry Andric       __has_val_ = false;
387bdd1243dSDimitry Andric     } else {
388bdd1243dSDimitry Andric       __union_.__unex_ = std::move(__un.error());
389bdd1243dSDimitry Andric     }
390bdd1243dSDimitry Andric     return *this;
391bdd1243dSDimitry Andric   }
392bdd1243dSDimitry Andric 
393bdd1243dSDimitry Andric   template <class... _Args>
394bdd1243dSDimitry Andric     requires is_nothrow_constructible_v<_Tp, _Args...>
395bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept {
396bdd1243dSDimitry Andric     if (__has_val_) {
397bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__val_));
398bdd1243dSDimitry Andric     } else {
399bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__unex_));
400bdd1243dSDimitry Andric     }
401*b121cb00SDimitry Andric     std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...);
402*b121cb00SDimitry Andric     __has_val_ = true;
403*b121cb00SDimitry Andric     return __union_.__val_;
404bdd1243dSDimitry Andric   }
405bdd1243dSDimitry Andric 
406bdd1243dSDimitry Andric   template <class _Up, class... _Args>
407bdd1243dSDimitry Andric     requires is_nothrow_constructible_v< _Tp, initializer_list<_Up>&, _Args... >
408bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept {
409bdd1243dSDimitry Andric     if (__has_val_) {
410bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__val_));
411bdd1243dSDimitry Andric     } else {
412bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__unex_));
413bdd1243dSDimitry Andric     }
414*b121cb00SDimitry Andric     std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...);
415*b121cb00SDimitry Andric     __has_val_ = true;
416*b121cb00SDimitry Andric     return __union_.__val_;
417bdd1243dSDimitry Andric   }
418bdd1243dSDimitry Andric 
419bdd1243dSDimitry Andric 
420bdd1243dSDimitry Andric public:
421bdd1243dSDimitry Andric   // [expected.object.swap], swap
422bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs)
423bdd1243dSDimitry Andric     noexcept(is_nothrow_move_constructible_v<_Tp> &&
424bdd1243dSDimitry Andric              is_nothrow_swappable_v<_Tp> &&
425bdd1243dSDimitry Andric              is_nothrow_move_constructible_v<_Err> &&
426bdd1243dSDimitry Andric              is_nothrow_swappable_v<_Err>)
427bdd1243dSDimitry Andric     requires(is_swappable_v<_Tp> &&
428bdd1243dSDimitry Andric              is_swappable_v<_Err> &&
429bdd1243dSDimitry Andric              is_move_constructible_v<_Tp> &&
430bdd1243dSDimitry Andric              is_move_constructible_v<_Err> &&
431bdd1243dSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> ||
432bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Err>))
433bdd1243dSDimitry Andric   {
434bdd1243dSDimitry Andric     auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) {
435bdd1243dSDimitry Andric       if constexpr (is_nothrow_move_constructible_v<_Err>) {
436bdd1243dSDimitry Andric         _Err __tmp(std::move(__with_err.__union_.__unex_));
437bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__with_err.__union_.__unex_));
4381ac55f4cSDimitry Andric         auto __trans = std::__make_exception_guard([&] {
439bdd1243dSDimitry Andric           std::construct_at(std::addressof(__with_err.__union_.__unex_), std::move(__tmp));
440bdd1243dSDimitry Andric         });
441bdd1243dSDimitry Andric         std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__with_val.__union_.__val_));
442bdd1243dSDimitry Andric         __trans.__complete();
443bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__with_val.__union_.__val_));
444bdd1243dSDimitry Andric         std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__tmp));
445bdd1243dSDimitry Andric       } else {
446bdd1243dSDimitry Andric         static_assert(is_nothrow_move_constructible_v<_Tp>,
447bdd1243dSDimitry Andric                       "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so "
448bdd1243dSDimitry Andric                       "that it can be reverted to the previous state in case an exception is thrown during swap.");
449bdd1243dSDimitry Andric         _Tp __tmp(std::move(__with_val.__union_.__val_));
450bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__with_val.__union_.__val_));
4511ac55f4cSDimitry Andric         auto __trans = std::__make_exception_guard([&] {
452bdd1243dSDimitry Andric           std::construct_at(std::addressof(__with_val.__union_.__val_), std::move(__tmp));
453bdd1243dSDimitry Andric         });
454bdd1243dSDimitry Andric         std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_));
455bdd1243dSDimitry Andric         __trans.__complete();
456bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__with_err.__union_.__unex_));
457bdd1243dSDimitry Andric         std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__tmp));
458bdd1243dSDimitry Andric       }
459bdd1243dSDimitry Andric       __with_val.__has_val_ = false;
460bdd1243dSDimitry Andric       __with_err.__has_val_ = true;
461bdd1243dSDimitry Andric     };
462bdd1243dSDimitry Andric 
463bdd1243dSDimitry Andric     if (__has_val_) {
464bdd1243dSDimitry Andric       if (__rhs.__has_val_) {
465bdd1243dSDimitry Andric         using std::swap;
466bdd1243dSDimitry Andric         swap(__union_.__val_, __rhs.__union_.__val_);
467bdd1243dSDimitry Andric       } else {
468bdd1243dSDimitry Andric         __swap_val_unex_impl(*this, __rhs);
469bdd1243dSDimitry Andric       }
470bdd1243dSDimitry Andric     } else {
471bdd1243dSDimitry Andric       if (__rhs.__has_val_) {
472bdd1243dSDimitry Andric         __swap_val_unex_impl(__rhs, *this);
473bdd1243dSDimitry Andric       } else {
474bdd1243dSDimitry Andric         using std::swap;
475bdd1243dSDimitry Andric         swap(__union_.__unex_, __rhs.__union_.__unex_);
476bdd1243dSDimitry Andric       }
477bdd1243dSDimitry Andric     }
478bdd1243dSDimitry Andric   }
479bdd1243dSDimitry Andric 
480bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y)
481bdd1243dSDimitry Andric     noexcept(noexcept(__x.swap(__y)))
482bdd1243dSDimitry Andric     requires requires { __x.swap(__y); }
483bdd1243dSDimitry Andric   {
484bdd1243dSDimitry Andric     __x.swap(__y);
485bdd1243dSDimitry Andric   }
486bdd1243dSDimitry Andric 
487bdd1243dSDimitry Andric   // [expected.object.obs], observers
488bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept {
48906c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator-> requires the expected to contain a value");
490bdd1243dSDimitry Andric     return std::addressof(__union_.__val_);
491bdd1243dSDimitry Andric   }
492bdd1243dSDimitry Andric 
493bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept {
49406c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator-> requires the expected to contain a value");
495bdd1243dSDimitry Andric     return std::addressof(__union_.__val_);
496bdd1243dSDimitry Andric   }
497bdd1243dSDimitry Andric 
498bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
49906c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
500bdd1243dSDimitry Andric     return __union_.__val_;
501bdd1243dSDimitry Andric   }
502bdd1243dSDimitry Andric 
503bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
50406c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
505bdd1243dSDimitry Andric     return __union_.__val_;
506bdd1243dSDimitry Andric   }
507bdd1243dSDimitry Andric 
508bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
50906c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
510bdd1243dSDimitry Andric     return std::move(__union_.__val_);
511bdd1243dSDimitry Andric   }
512bdd1243dSDimitry Andric 
513bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
51406c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
515bdd1243dSDimitry Andric     return std::move(__union_.__val_);
516bdd1243dSDimitry Andric   }
517bdd1243dSDimitry Andric 
518bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; }
519bdd1243dSDimitry Andric 
520bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
521bdd1243dSDimitry Andric 
522bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& {
52306c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
524bdd1243dSDimitry Andric     if (!__has_val_) {
52506c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::as_const(error()));
526bdd1243dSDimitry Andric     }
527bdd1243dSDimitry Andric     return __union_.__val_;
528bdd1243dSDimitry Andric   }
529bdd1243dSDimitry Andric 
530bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
53106c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
532bdd1243dSDimitry Andric     if (!__has_val_) {
53306c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::as_const(error()));
534bdd1243dSDimitry Andric     }
535bdd1243dSDimitry Andric     return __union_.__val_;
536bdd1243dSDimitry Andric   }
537bdd1243dSDimitry Andric 
538bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& {
53906c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
54006c3fb27SDimitry Andric                   "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
541bdd1243dSDimitry Andric     if (!__has_val_) {
54206c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::move(error()));
543bdd1243dSDimitry Andric     }
544bdd1243dSDimitry Andric     return std::move(__union_.__val_);
545bdd1243dSDimitry Andric   }
546bdd1243dSDimitry Andric 
547bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
54806c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
54906c3fb27SDimitry Andric                   "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
550bdd1243dSDimitry Andric     if (!__has_val_) {
55106c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::move(error()));
552bdd1243dSDimitry Andric     }
553bdd1243dSDimitry Andric     return std::move(__union_.__val_);
554bdd1243dSDimitry Andric   }
555bdd1243dSDimitry Andric 
556bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
55706c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
558bdd1243dSDimitry Andric     return __union_.__unex_;
559bdd1243dSDimitry Andric   }
560bdd1243dSDimitry Andric 
561bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
56206c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
563bdd1243dSDimitry Andric     return __union_.__unex_;
564bdd1243dSDimitry Andric   }
565bdd1243dSDimitry Andric 
566bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
56706c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
568bdd1243dSDimitry Andric     return std::move(__union_.__unex_);
569bdd1243dSDimitry Andric   }
570bdd1243dSDimitry Andric 
571bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
57206c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
573bdd1243dSDimitry Andric     return std::move(__union_.__unex_);
574bdd1243dSDimitry Andric   }
575bdd1243dSDimitry Andric 
576bdd1243dSDimitry Andric   template <class _Up>
577bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
578bdd1243dSDimitry Andric     static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible");
579bdd1243dSDimitry Andric     static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
580bdd1243dSDimitry Andric     return __has_val_ ? __union_.__val_ : static_cast<_Tp>(std::forward<_Up>(__v));
581bdd1243dSDimitry Andric   }
582bdd1243dSDimitry Andric 
583bdd1243dSDimitry Andric   template <class _Up>
584bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
585bdd1243dSDimitry Andric     static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible");
586bdd1243dSDimitry Andric     static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
587bdd1243dSDimitry Andric     return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v));
588bdd1243dSDimitry Andric   }
589bdd1243dSDimitry Andric 
59006c3fb27SDimitry Andric   template <class _Up = _Err>
59106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
59206c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
59306c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
59406c3fb27SDimitry Andric     if (has_value())
59506c3fb27SDimitry Andric       return std::forward<_Up>(__error);
59606c3fb27SDimitry Andric     return error();
59706c3fb27SDimitry Andric   }
59806c3fb27SDimitry Andric 
59906c3fb27SDimitry Andric   template <class _Up = _Err>
60006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
60106c3fb27SDimitry Andric     static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
60206c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
60306c3fb27SDimitry Andric     if (has_value())
60406c3fb27SDimitry Andric       return std::forward<_Up>(__error);
60506c3fb27SDimitry Andric     return std::move(error());
60606c3fb27SDimitry Andric   }
60706c3fb27SDimitry Andric 
60806c3fb27SDimitry Andric   // [expected.void.monadic], monadic
60906c3fb27SDimitry Andric   template <class _Func>
61006c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
61106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
61206c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>;
61306c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
61406c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
61506c3fb27SDimitry Andric                   "The result of f(value()) must have the same error_type as this expected");
61606c3fb27SDimitry Andric     if (has_value()) {
61706c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f), value());
61806c3fb27SDimitry Andric     }
61906c3fb27SDimitry Andric     return _Up(unexpect, error());
62006c3fb27SDimitry Andric   }
62106c3fb27SDimitry Andric 
62206c3fb27SDimitry Andric   template <class _Func>
62306c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
62406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
62506c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&>>;
62606c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
62706c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
62806c3fb27SDimitry Andric                   "The result of f(value()) must have the same error_type as this expected");
62906c3fb27SDimitry Andric     if (has_value()) {
63006c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f), value());
63106c3fb27SDimitry Andric     }
63206c3fb27SDimitry Andric     return _Up(unexpect, error());
63306c3fb27SDimitry Andric   }
63406c3fb27SDimitry Andric 
63506c3fb27SDimitry Andric   template <class _Func>
63606c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
63706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
63806c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&&>>;
63906c3fb27SDimitry Andric     static_assert(
64006c3fb27SDimitry Andric         __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
64106c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
64206c3fb27SDimitry Andric                   "The result of f(std::move(value())) must have the same error_type as this expected");
64306c3fb27SDimitry Andric     if (has_value()) {
64406c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f), std::move(value()));
64506c3fb27SDimitry Andric     }
64606c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
64706c3fb27SDimitry Andric   }
64806c3fb27SDimitry Andric 
64906c3fb27SDimitry Andric   template <class _Func>
65006c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
65106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
65206c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>;
65306c3fb27SDimitry Andric     static_assert(
65406c3fb27SDimitry Andric         __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
65506c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
65606c3fb27SDimitry Andric                   "The result of f(std::move(value())) must have the same error_type as this expected");
65706c3fb27SDimitry Andric     if (has_value()) {
65806c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f), std::move(value()));
65906c3fb27SDimitry Andric     }
66006c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
66106c3fb27SDimitry Andric   }
66206c3fb27SDimitry Andric 
66306c3fb27SDimitry Andric   template <class _Func>
66406c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&>
66506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
66606c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
66706c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
66806c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
66906c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
67006c3fb27SDimitry Andric     if (has_value()) {
67106c3fb27SDimitry Andric       return _Gp(in_place, value());
67206c3fb27SDimitry Andric     }
67306c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
67406c3fb27SDimitry Andric   }
67506c3fb27SDimitry Andric 
67606c3fb27SDimitry Andric   template <class _Func>
67706c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&>
67806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
67906c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
68006c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
68106c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
68206c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
68306c3fb27SDimitry Andric     if (has_value()) {
68406c3fb27SDimitry Andric       return _Gp(in_place, value());
68506c3fb27SDimitry Andric     }
68606c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
68706c3fb27SDimitry Andric   }
68806c3fb27SDimitry Andric 
68906c3fb27SDimitry Andric   template <class _Func>
69006c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&&>
69106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
69206c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
69306c3fb27SDimitry Andric     static_assert(
69406c3fb27SDimitry Andric         __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
69506c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
69606c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
69706c3fb27SDimitry Andric     if (has_value()) {
69806c3fb27SDimitry Andric       return _Gp(in_place, std::move(value()));
69906c3fb27SDimitry Andric     }
70006c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
70106c3fb27SDimitry Andric   }
70206c3fb27SDimitry Andric 
70306c3fb27SDimitry Andric   template <class _Func>
70406c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&&>
70506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
70606c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
70706c3fb27SDimitry Andric     static_assert(
70806c3fb27SDimitry Andric         __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
70906c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
71006c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
71106c3fb27SDimitry Andric     if (has_value()) {
71206c3fb27SDimitry Andric       return _Gp(in_place, std::move(value()));
71306c3fb27SDimitry Andric     }
71406c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
71506c3fb27SDimitry Andric   }
71606c3fb27SDimitry Andric 
71706c3fb27SDimitry Andric   template <class _Func>
71806c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
71906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
72006c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>;
72106c3fb27SDimitry Andric     if (!has_value()) {
72206c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
72306c3fb27SDimitry Andric     }
72406c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
72506c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value());
72606c3fb27SDimitry Andric     } else {
72706c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f), value());
72806c3fb27SDimitry Andric       return expected<_Up, _Err>();
72906c3fb27SDimitry Andric     }
73006c3fb27SDimitry Andric   }
73106c3fb27SDimitry Andric 
73206c3fb27SDimitry Andric   template <class _Func>
73306c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
73406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
73506c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>;
73606c3fb27SDimitry Andric     if (!has_value()) {
73706c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
73806c3fb27SDimitry Andric     }
73906c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
74006c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value());
74106c3fb27SDimitry Andric     } else {
74206c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f), value());
74306c3fb27SDimitry Andric       return expected<_Up, _Err>();
74406c3fb27SDimitry Andric     }
74506c3fb27SDimitry Andric   }
74606c3fb27SDimitry Andric 
74706c3fb27SDimitry Andric   template <class _Func>
74806c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
74906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
75006c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>;
75106c3fb27SDimitry Andric     if (!has_value()) {
75206c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
75306c3fb27SDimitry Andric     }
75406c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
75506c3fb27SDimitry Andric       return expected<_Up, _Err>(
75606c3fb27SDimitry Andric           __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
75706c3fb27SDimitry Andric     } else {
75806c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f), std::move(value()));
75906c3fb27SDimitry Andric       return expected<_Up, _Err>();
76006c3fb27SDimitry Andric     }
76106c3fb27SDimitry Andric   }
76206c3fb27SDimitry Andric 
76306c3fb27SDimitry Andric   template <class _Func>
76406c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
76506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
76606c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&&>>;
76706c3fb27SDimitry Andric     if (!has_value()) {
76806c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
76906c3fb27SDimitry Andric     }
77006c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
77106c3fb27SDimitry Andric       return expected<_Up, _Err>(
77206c3fb27SDimitry Andric           __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
77306c3fb27SDimitry Andric     } else {
77406c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f), std::move(value()));
77506c3fb27SDimitry Andric       return expected<_Up, _Err>();
77606c3fb27SDimitry Andric     }
77706c3fb27SDimitry Andric   }
77806c3fb27SDimitry Andric 
77906c3fb27SDimitry Andric   template <class _Func>
78006c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&>
78106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
78206c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
78306c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
78406c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
78506c3fb27SDimitry Andric     if (has_value()) {
78606c3fb27SDimitry Andric       return expected<_Tp, _Gp>(in_place, value());
78706c3fb27SDimitry Andric     }
78806c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
78906c3fb27SDimitry Andric   }
79006c3fb27SDimitry Andric 
79106c3fb27SDimitry Andric   template <class _Func>
79206c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&>
79306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
79406c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
79506c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
79606c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
79706c3fb27SDimitry Andric     if (has_value()) {
79806c3fb27SDimitry Andric       return expected<_Tp, _Gp>(in_place, value());
79906c3fb27SDimitry Andric     }
80006c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
80106c3fb27SDimitry Andric   }
80206c3fb27SDimitry Andric 
80306c3fb27SDimitry Andric   template <class _Func>
80406c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&&>
80506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
80606c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
80706c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
80806c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
80906c3fb27SDimitry Andric     if (has_value()) {
81006c3fb27SDimitry Andric       return expected<_Tp, _Gp>(in_place, std::move(value()));
81106c3fb27SDimitry Andric     }
81206c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
81306c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
81406c3fb27SDimitry Andric   }
81506c3fb27SDimitry Andric 
81606c3fb27SDimitry Andric   template <class _Func>
81706c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&&>
81806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
81906c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
82006c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
82106c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
82206c3fb27SDimitry Andric     if (has_value()) {
82306c3fb27SDimitry Andric       return expected<_Tp, _Gp>(in_place, std::move(value()));
82406c3fb27SDimitry Andric     }
82506c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
82606c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
82706c3fb27SDimitry Andric   }
82806c3fb27SDimitry Andric 
829bdd1243dSDimitry Andric   // [expected.object.eq], equality operators
830bdd1243dSDimitry Andric   template <class _T2, class _E2>
831bdd1243dSDimitry Andric     requires(!is_void_v<_T2>)
832bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
833bdd1243dSDimitry Andric     if (__x.__has_val_ != __y.__has_val_) {
834bdd1243dSDimitry Andric       return false;
835bdd1243dSDimitry Andric     } else {
836bdd1243dSDimitry Andric       if (__x.__has_val_) {
837bdd1243dSDimitry Andric         return __x.__union_.__val_ == __y.__union_.__val_;
838bdd1243dSDimitry Andric       } else {
839bdd1243dSDimitry Andric         return __x.__union_.__unex_ == __y.__union_.__unex_;
840bdd1243dSDimitry Andric       }
841bdd1243dSDimitry Andric     }
842bdd1243dSDimitry Andric   }
843bdd1243dSDimitry Andric 
844bdd1243dSDimitry Andric   template <class _T2>
845bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) {
846bdd1243dSDimitry Andric     return __x.__has_val_ && static_cast<bool>(__x.__union_.__val_ == __v);
847bdd1243dSDimitry Andric   }
848bdd1243dSDimitry Andric 
849bdd1243dSDimitry Andric   template <class _E2>
850bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) {
851bdd1243dSDimitry Andric     return !__x.__has_val_ && static_cast<bool>(__x.__union_.__unex_ == __e.error());
852bdd1243dSDimitry Andric   }
853bdd1243dSDimitry Andric 
854bdd1243dSDimitry Andric private:
85506c3fb27SDimitry Andric   template <class _ValueType, class _ErrorType>
85606c3fb27SDimitry Andric   union __union_t {
857*b121cb00SDimitry Andric     template <class... _Args>
858*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(std::in_place_t, _Args&&... __args)
859*b121cb00SDimitry Andric         : __val_(std::forward<_Args>(__args)...) {}
860*b121cb00SDimitry Andric 
861*b121cb00SDimitry Andric     template <class... _Args>
862*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(std::unexpect_t, _Args&&... __args)
863*b121cb00SDimitry Andric         : __unex_(std::forward<_Args>(__args)...) {}
86406c3fb27SDimitry Andric 
86506c3fb27SDimitry Andric     template <class _Func, class... _Args>
86606c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
86706c3fb27SDimitry Andric         std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args)
86806c3fb27SDimitry Andric         : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
86906c3fb27SDimitry Andric 
87006c3fb27SDimitry Andric     template <class _Func, class... _Args>
87106c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
87206c3fb27SDimitry Andric         std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
87306c3fb27SDimitry Andric         : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
874bdd1243dSDimitry Andric 
875*b121cb00SDimitry Andric     template <class _Union>
876*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(bool __has_val, _Union&& __other) {
877*b121cb00SDimitry Andric       if (__has_val)
878*b121cb00SDimitry Andric         std::construct_at(std::addressof(__val_), std::forward<_Union>(__other).__val_);
879*b121cb00SDimitry Andric       else
880*b121cb00SDimitry Andric         std::construct_at(std::addressof(__unex_), std::forward<_Union>(__other).__unex_);
881*b121cb00SDimitry Andric     }
882*b121cb00SDimitry Andric 
883bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
88406c3fb27SDimitry Andric       requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>)
88506c3fb27SDimitry Andric     = default;
88606c3fb27SDimitry Andric 
88706c3fb27SDimitry Andric     // the expected's destructor handles this
88806c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {}
88906c3fb27SDimitry Andric 
89006c3fb27SDimitry Andric     _ValueType __val_;
89106c3fb27SDimitry Andric     _ErrorType __unex_;
89206c3fb27SDimitry Andric   };
89306c3fb27SDimitry Andric 
89406c3fb27SDimitry Andric   // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
89506c3fb27SDimitry Andric   // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
89606c3fb27SDimitry Andric   // it's not clear that it's implementable, given that the function is allowed to clobber
89706c3fb27SDimitry Andric   // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
89806c3fb27SDimitry Andric   template <class _ValueType, class _ErrorType>
89906c3fb27SDimitry Andric     requires(is_trivially_move_constructible_v<_ValueType> && is_trivially_move_constructible_v<_ErrorType>)
90006c3fb27SDimitry Andric   union __union_t<_ValueType, _ErrorType> {
901*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = default;
902*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(const __union_t&) = default;
903*b121cb00SDimitry Andric 
904*b121cb00SDimitry Andric     template <class... _Args>
905*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(std::in_place_t, _Args&&... __args)
906*b121cb00SDimitry Andric         : __val_(std::forward<_Args>(__args)...) {}
907*b121cb00SDimitry Andric 
908*b121cb00SDimitry Andric     template <class... _Args>
909*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(std::unexpect_t, _Args&&... __args)
910*b121cb00SDimitry Andric         : __unex_(std::forward<_Args>(__args)...) {}
91106c3fb27SDimitry Andric 
91206c3fb27SDimitry Andric     template <class _Func, class... _Args>
91306c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
91406c3fb27SDimitry Andric         std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args)
91506c3fb27SDimitry Andric         : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
91606c3fb27SDimitry Andric 
91706c3fb27SDimitry Andric     template <class _Func, class... _Args>
91806c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
91906c3fb27SDimitry Andric         std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
92006c3fb27SDimitry Andric         : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
92106c3fb27SDimitry Andric 
922*b121cb00SDimitry Andric     template <class _Union>
923*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(bool __has_val, _Union&& __other) {
924*b121cb00SDimitry Andric       if (__has_val)
925*b121cb00SDimitry Andric         std::construct_at(std::addressof(__val_), std::forward<_Union>(__other).__val_);
926*b121cb00SDimitry Andric       else
927*b121cb00SDimitry Andric         std::construct_at(std::addressof(__unex_), std::forward<_Union>(__other).__unex_);
928*b121cb00SDimitry Andric     }
929*b121cb00SDimitry Andric 
93006c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
93106c3fb27SDimitry Andric       requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>)
932bdd1243dSDimitry Andric     = default;
933bdd1243dSDimitry Andric 
934bdd1243dSDimitry Andric     // the expected's destructor handles this
935bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
93606c3fb27SDimitry Andric       requires(!is_trivially_destructible_v<_ValueType> || !is_trivially_destructible_v<_ErrorType>)
937bdd1243dSDimitry Andric     {}
938bdd1243dSDimitry Andric 
93906c3fb27SDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _ValueType __val_;
94006c3fb27SDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_;
94106c3fb27SDimitry Andric   };
942bdd1243dSDimitry Andric 
94306c3fb27SDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Tp, _Err> __union_;
944bdd1243dSDimitry Andric   bool __has_val_;
945bdd1243dSDimitry Andric };
946bdd1243dSDimitry Andric 
947bdd1243dSDimitry Andric template <class _Tp, class _Err>
948bdd1243dSDimitry Andric   requires is_void_v<_Tp>
949bdd1243dSDimitry Andric class expected<_Tp, _Err> {
950bdd1243dSDimitry Andric   static_assert(__valid_std_unexpected<_Err>::value,
951bdd1243dSDimitry Andric                 "[expected.void.general] A program that instantiates expected<T, E> with a E that is not a "
952bdd1243dSDimitry Andric                 "valid argument for unexpected<E> is ill-formed");
953bdd1243dSDimitry Andric 
954bdd1243dSDimitry Andric   template <class, class>
955bdd1243dSDimitry Andric   friend class expected;
956bdd1243dSDimitry Andric 
957bdd1243dSDimitry Andric   template <class _Up, class _OtherErr, class _OtherErrQual>
958bdd1243dSDimitry Andric   using __can_convert =
959bdd1243dSDimitry Andric       _And< is_void<_Up>,
960bdd1243dSDimitry Andric             is_constructible<_Err, _OtherErrQual>,
961bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
962bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
963bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
964bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>>>;
965bdd1243dSDimitry Andric 
966bdd1243dSDimitry Andric public:
967bdd1243dSDimitry Andric   using value_type      = _Tp;
968bdd1243dSDimitry Andric   using error_type      = _Err;
969bdd1243dSDimitry Andric   using unexpected_type = unexpected<_Err>;
970bdd1243dSDimitry Andric 
971bdd1243dSDimitry Andric   template <class _Up>
972bdd1243dSDimitry Andric   using rebind = expected<_Up, error_type>;
973bdd1243dSDimitry Andric 
974bdd1243dSDimitry Andric   // [expected.void.ctor], constructors
975bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __has_val_(true) {}
976bdd1243dSDimitry Andric 
977bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
978bdd1243dSDimitry Andric 
979bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
980bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>)
981bdd1243dSDimitry Andric   = default;
982bdd1243dSDimitry Andric 
983bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs)
984bdd1243dSDimitry Andric     noexcept(is_nothrow_copy_constructible_v<_Err>) // strengthened
985bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>)
986*b121cb00SDimitry Andric       : __union_(__rhs.__has_val_, __rhs.__union_), __has_val_(__rhs.__has_val_) {}
987bdd1243dSDimitry Andric 
988bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
989bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
990bdd1243dSDimitry Andric   = default;
991bdd1243dSDimitry Andric 
992bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs)
993bdd1243dSDimitry Andric     noexcept(is_nothrow_move_constructible_v<_Err>)
994bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>)
995*b121cb00SDimitry Andric       : __union_(__rhs.__has_val_, std::move(__rhs.__union_)), __has_val_(__rhs.__has_val_) {}
996bdd1243dSDimitry Andric 
997bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
998bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value
999bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
1000bdd1243dSDimitry Andric   expected(const expected<_Up, _OtherErr>& __rhs)
1001bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
1002*b121cb00SDimitry Andric       : __union_(__rhs.__has_val_, __rhs.__union_), __has_val_(__rhs.__has_val_) {}
1003bdd1243dSDimitry Andric 
1004bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
1005bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, _OtherErr>::value
1006bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
1007bdd1243dSDimitry Andric   expected(expected<_Up, _OtherErr>&& __rhs)
1008bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
1009*b121cb00SDimitry Andric       : __union_(__rhs.__has_val_, std::move(__rhs.__union_)), __has_val_(__rhs.__has_val_) {}
1010bdd1243dSDimitry Andric 
1011bdd1243dSDimitry Andric   template <class _OtherErr>
1012bdd1243dSDimitry Andric     requires is_constructible_v<_Err, const _OtherErr&>
1013bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
1014bdd1243dSDimitry Andric   expected(const unexpected<_OtherErr>& __unex)
1015bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
1016*b121cb00SDimitry Andric       : __union_(std::unexpect, __unex.error()), __has_val_(false) {}
1017bdd1243dSDimitry Andric 
1018bdd1243dSDimitry Andric   template <class _OtherErr>
1019bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _OtherErr>
1020bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
1021bdd1243dSDimitry Andric   expected(unexpected<_OtherErr>&& __unex)
1022bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
1023*b121cb00SDimitry Andric       : __union_(std::unexpect, std::move(__unex.error())), __has_val_(false) {}
1024bdd1243dSDimitry Andric 
1025bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {}
1026bdd1243dSDimitry Andric 
1027bdd1243dSDimitry Andric   template <class... _Args>
1028bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _Args...>
1029bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args)
1030bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened
1031*b121cb00SDimitry Andric       : __union_(std::unexpect, std::forward<_Args>(__args)...), __has_val_(false) {}
1032bdd1243dSDimitry Andric 
1033bdd1243dSDimitry Andric   template <class _Up, class... _Args>
1034bdd1243dSDimitry Andric     requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
1035bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
1036bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
1037*b121cb00SDimitry Andric       : __union_(std::unexpect, __il, std::forward<_Args>(__args)...), __has_val_(false) {}
1038bdd1243dSDimitry Andric 
103906c3fb27SDimitry Andric private:
104006c3fb27SDimitry Andric   template <class _Func>
104106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(__expected_construct_in_place_from_invoke_tag, _Func&& __f)
104206c3fb27SDimitry Andric       : __has_val_(true) {
104306c3fb27SDimitry Andric     std::invoke(std::forward<_Func>(__f));
104406c3fb27SDimitry Andric   }
104506c3fb27SDimitry Andric 
104606c3fb27SDimitry Andric   template <class _Func, class... _Args>
104706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
104806c3fb27SDimitry Andric       __expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
104906c3fb27SDimitry Andric       : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {}
105006c3fb27SDimitry Andric 
105106c3fb27SDimitry Andric public:
1052bdd1243dSDimitry Andric   // [expected.void.dtor], destructor
1053bdd1243dSDimitry Andric 
1054bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
1055bdd1243dSDimitry Andric     requires is_trivially_destructible_v<_Err>
1056bdd1243dSDimitry Andric   = default;
1057bdd1243dSDimitry Andric 
1058bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
1059bdd1243dSDimitry Andric     requires(!is_trivially_destructible_v<_Err>)
1060bdd1243dSDimitry Andric   {
1061bdd1243dSDimitry Andric     if (!__has_val_) {
1062bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__unex_));
1063bdd1243dSDimitry Andric     }
1064bdd1243dSDimitry Andric   }
1065bdd1243dSDimitry Andric 
1066bdd1243dSDimitry Andric   // [expected.void.assign], assignment
1067bdd1243dSDimitry Andric 
1068bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
1069bdd1243dSDimitry Andric 
1070bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs)
1071bdd1243dSDimitry Andric     noexcept(is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened
1072bdd1243dSDimitry Andric     requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>)
1073bdd1243dSDimitry Andric   {
1074bdd1243dSDimitry Andric     if (__has_val_) {
1075bdd1243dSDimitry Andric       if (!__rhs.__has_val_) {
1076bdd1243dSDimitry Andric         std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_);
1077bdd1243dSDimitry Andric         __has_val_ = false;
1078bdd1243dSDimitry Andric       }
1079bdd1243dSDimitry Andric     } else {
1080bdd1243dSDimitry Andric       if (__rhs.__has_val_) {
1081bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__union_.__unex_));
1082bdd1243dSDimitry Andric         __has_val_ = true;
1083bdd1243dSDimitry Andric       } else {
1084bdd1243dSDimitry Andric         __union_.__unex_ = __rhs.__union_.__unex_;
1085bdd1243dSDimitry Andric       }
1086bdd1243dSDimitry Andric     }
1087bdd1243dSDimitry Andric     return *this;
1088bdd1243dSDimitry Andric   }
1089bdd1243dSDimitry Andric 
1090bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&&) = delete;
1091bdd1243dSDimitry Andric 
1092bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs)
1093bdd1243dSDimitry Andric     noexcept(is_nothrow_move_assignable_v<_Err> &&
1094bdd1243dSDimitry Andric              is_nothrow_move_constructible_v<_Err>)
1095bdd1243dSDimitry Andric     requires(is_move_assignable_v<_Err> &&
1096bdd1243dSDimitry Andric              is_move_constructible_v<_Err>)
1097bdd1243dSDimitry Andric   {
1098bdd1243dSDimitry Andric     if (__has_val_) {
1099bdd1243dSDimitry Andric       if (!__rhs.__has_val_) {
1100bdd1243dSDimitry Andric         std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_));
1101bdd1243dSDimitry Andric         __has_val_ = false;
1102bdd1243dSDimitry Andric       }
1103bdd1243dSDimitry Andric     } else {
1104bdd1243dSDimitry Andric       if (__rhs.__has_val_) {
1105bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__union_.__unex_));
1106bdd1243dSDimitry Andric         __has_val_ = true;
1107bdd1243dSDimitry Andric       } else {
1108bdd1243dSDimitry Andric         __union_.__unex_ = std::move(__rhs.__union_.__unex_);
1109bdd1243dSDimitry Andric       }
1110bdd1243dSDimitry Andric     }
1111bdd1243dSDimitry Andric     return *this;
1112bdd1243dSDimitry Andric   }
1113bdd1243dSDimitry Andric 
1114bdd1243dSDimitry Andric   template <class _OtherErr>
1115bdd1243dSDimitry Andric     requires(is_constructible_v<_Err, const _OtherErr&> && is_assignable_v<_Err&, const _OtherErr&>)
1116bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
1117bdd1243dSDimitry Andric     if (__has_val_) {
1118bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), __un.error());
1119bdd1243dSDimitry Andric       __has_val_ = false;
1120bdd1243dSDimitry Andric     } else {
1121bdd1243dSDimitry Andric       __union_.__unex_ = __un.error();
1122bdd1243dSDimitry Andric     }
1123bdd1243dSDimitry Andric     return *this;
1124bdd1243dSDimitry Andric   }
1125bdd1243dSDimitry Andric 
1126bdd1243dSDimitry Andric   template <class _OtherErr>
1127bdd1243dSDimitry Andric     requires(is_constructible_v<_Err, _OtherErr> && is_assignable_v<_Err&, _OtherErr>)
1128bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
1129bdd1243dSDimitry Andric     if (__has_val_) {
1130bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), std::move(__un.error()));
1131bdd1243dSDimitry Andric       __has_val_ = false;
1132bdd1243dSDimitry Andric     } else {
1133bdd1243dSDimitry Andric       __union_.__unex_ = std::move(__un.error());
1134bdd1243dSDimitry Andric     }
1135bdd1243dSDimitry Andric     return *this;
1136bdd1243dSDimitry Andric   }
1137bdd1243dSDimitry Andric 
1138bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept {
1139bdd1243dSDimitry Andric     if (!__has_val_) {
1140bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__unex_));
1141bdd1243dSDimitry Andric       __has_val_ = true;
1142bdd1243dSDimitry Andric     }
1143bdd1243dSDimitry Andric   }
1144bdd1243dSDimitry Andric 
1145bdd1243dSDimitry Andric   // [expected.void.swap], swap
1146bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs)
1147bdd1243dSDimitry Andric     noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
1148bdd1243dSDimitry Andric     requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>)
1149bdd1243dSDimitry Andric   {
1150bdd1243dSDimitry Andric     auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) {
1151bdd1243dSDimitry Andric       std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_));
1152bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__with_err.__union_.__unex_));
1153bdd1243dSDimitry Andric       __with_val.__has_val_ = false;
1154bdd1243dSDimitry Andric       __with_err.__has_val_ = true;
1155bdd1243dSDimitry Andric     };
1156bdd1243dSDimitry Andric 
1157bdd1243dSDimitry Andric     if (__has_val_) {
1158bdd1243dSDimitry Andric       if (!__rhs.__has_val_) {
1159bdd1243dSDimitry Andric         __swap_val_unex_impl(*this, __rhs);
1160bdd1243dSDimitry Andric       }
1161bdd1243dSDimitry Andric     } else {
1162bdd1243dSDimitry Andric       if (__rhs.__has_val_) {
1163bdd1243dSDimitry Andric         __swap_val_unex_impl(__rhs, *this);
1164bdd1243dSDimitry Andric       } else {
1165bdd1243dSDimitry Andric         using std::swap;
1166bdd1243dSDimitry Andric         swap(__union_.__unex_, __rhs.__union_.__unex_);
1167bdd1243dSDimitry Andric       }
1168bdd1243dSDimitry Andric     }
1169bdd1243dSDimitry Andric   }
1170bdd1243dSDimitry Andric 
1171bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y)
1172bdd1243dSDimitry Andric     noexcept(noexcept(__x.swap(__y)))
1173bdd1243dSDimitry Andric     requires requires { __x.swap(__y); }
1174bdd1243dSDimitry Andric   {
1175bdd1243dSDimitry Andric     __x.swap(__y);
1176bdd1243dSDimitry Andric   }
1177bdd1243dSDimitry Andric 
1178bdd1243dSDimitry Andric   // [expected.void.obs], observers
1179bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; }
1180bdd1243dSDimitry Andric 
1181bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
1182bdd1243dSDimitry Andric 
1183bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept {
118406c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value");
1185bdd1243dSDimitry Andric   }
1186bdd1243dSDimitry Andric 
1187bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void value() const& {
1188bdd1243dSDimitry Andric     if (!__has_val_) {
118906c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(__union_.__unex_);
1190bdd1243dSDimitry Andric     }
1191bdd1243dSDimitry Andric   }
1192bdd1243dSDimitry Andric 
1193bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void value() && {
1194bdd1243dSDimitry Andric     if (!__has_val_) {
119506c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
1196bdd1243dSDimitry Andric     }
1197bdd1243dSDimitry Andric   }
1198bdd1243dSDimitry Andric 
1199bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
120006c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
1201bdd1243dSDimitry Andric     return __union_.__unex_;
1202bdd1243dSDimitry Andric   }
1203bdd1243dSDimitry Andric 
1204bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
120506c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
1206bdd1243dSDimitry Andric     return __union_.__unex_;
1207bdd1243dSDimitry Andric   }
1208bdd1243dSDimitry Andric 
1209bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
121006c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
1211bdd1243dSDimitry Andric     return std::move(__union_.__unex_);
1212bdd1243dSDimitry Andric   }
1213bdd1243dSDimitry Andric 
1214bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
121506c3fb27SDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error");
1216bdd1243dSDimitry Andric     return std::move(__union_.__unex_);
1217bdd1243dSDimitry Andric   }
1218bdd1243dSDimitry Andric 
121906c3fb27SDimitry Andric   template <class _Up = _Err>
122006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
122106c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
122206c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
122306c3fb27SDimitry Andric     if (has_value()) {
122406c3fb27SDimitry Andric       return std::forward<_Up>(__error);
122506c3fb27SDimitry Andric     }
122606c3fb27SDimitry Andric     return error();
122706c3fb27SDimitry Andric   }
122806c3fb27SDimitry Andric 
122906c3fb27SDimitry Andric   template <class _Up = _Err>
123006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
123106c3fb27SDimitry Andric     static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
123206c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
123306c3fb27SDimitry Andric     if (has_value()) {
123406c3fb27SDimitry Andric       return std::forward<_Up>(__error);
123506c3fb27SDimitry Andric     }
123606c3fb27SDimitry Andric     return std::move(error());
123706c3fb27SDimitry Andric   }
123806c3fb27SDimitry Andric 
123906c3fb27SDimitry Andric   // [expected.void.monadic], monadic
124006c3fb27SDimitry Andric   template <class _Func>
124106c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
124206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
124306c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
124406c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
124506c3fb27SDimitry Andric     static_assert(
124606c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
124706c3fb27SDimitry Andric     if (has_value()) {
124806c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
124906c3fb27SDimitry Andric     }
125006c3fb27SDimitry Andric     return _Up(unexpect, error());
125106c3fb27SDimitry Andric   }
125206c3fb27SDimitry Andric 
125306c3fb27SDimitry Andric   template <class _Func>
125406c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
125506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
125606c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
125706c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
125806c3fb27SDimitry Andric     static_assert(
125906c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
126006c3fb27SDimitry Andric     if (has_value()) {
126106c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
126206c3fb27SDimitry Andric     }
126306c3fb27SDimitry Andric     return _Up(unexpect, error());
126406c3fb27SDimitry Andric   }
126506c3fb27SDimitry Andric 
126606c3fb27SDimitry Andric   template <class _Func>
126706c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
126806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
126906c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
127006c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
127106c3fb27SDimitry Andric     static_assert(
127206c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
127306c3fb27SDimitry Andric     if (has_value()) {
127406c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
127506c3fb27SDimitry Andric     }
127606c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
127706c3fb27SDimitry Andric   }
127806c3fb27SDimitry Andric 
127906c3fb27SDimitry Andric   template <class _Func>
128006c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
128106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
128206c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
128306c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
128406c3fb27SDimitry Andric     static_assert(
128506c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
128606c3fb27SDimitry Andric     if (has_value()) {
128706c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
128806c3fb27SDimitry Andric     }
128906c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
129006c3fb27SDimitry Andric   }
129106c3fb27SDimitry Andric 
129206c3fb27SDimitry Andric   template <class _Func>
129306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
129406c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
129506c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
129606c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
129706c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
129806c3fb27SDimitry Andric     if (has_value()) {
129906c3fb27SDimitry Andric       return _Gp();
130006c3fb27SDimitry Andric     }
130106c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
130206c3fb27SDimitry Andric   }
130306c3fb27SDimitry Andric 
130406c3fb27SDimitry Andric   template <class _Func>
130506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
130606c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
130706c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
130806c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
130906c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
131006c3fb27SDimitry Andric     if (has_value()) {
131106c3fb27SDimitry Andric       return _Gp();
131206c3fb27SDimitry Andric     }
131306c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
131406c3fb27SDimitry Andric   }
131506c3fb27SDimitry Andric 
131606c3fb27SDimitry Andric   template <class _Func>
131706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
131806c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
131906c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value,
132006c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a specialization of std::expected");
132106c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
132206c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
132306c3fb27SDimitry Andric     if (has_value()) {
132406c3fb27SDimitry Andric       return _Gp();
132506c3fb27SDimitry Andric     }
132606c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
132706c3fb27SDimitry Andric   }
132806c3fb27SDimitry Andric 
132906c3fb27SDimitry Andric   template <class _Func>
133006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
133106c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
133206c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value,
133306c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a specialization of std::expected");
133406c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
133506c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
133606c3fb27SDimitry Andric     if (has_value()) {
133706c3fb27SDimitry Andric       return _Gp();
133806c3fb27SDimitry Andric     }
133906c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
134006c3fb27SDimitry Andric   }
134106c3fb27SDimitry Andric 
134206c3fb27SDimitry Andric   template <class _Func>
134306c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
134406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
134506c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
134606c3fb27SDimitry Andric     if (!has_value()) {
134706c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
134806c3fb27SDimitry Andric     }
134906c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
135006c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
135106c3fb27SDimitry Andric     } else {
135206c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
135306c3fb27SDimitry Andric       return expected<_Up, _Err>();
135406c3fb27SDimitry Andric     }
135506c3fb27SDimitry Andric   }
135606c3fb27SDimitry Andric 
135706c3fb27SDimitry Andric   template <class _Func>
135806c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
135906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
136006c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
136106c3fb27SDimitry Andric     if (!has_value()) {
136206c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
136306c3fb27SDimitry Andric     }
136406c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
136506c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
136606c3fb27SDimitry Andric     } else {
136706c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
136806c3fb27SDimitry Andric       return expected<_Up, _Err>();
136906c3fb27SDimitry Andric     }
137006c3fb27SDimitry Andric   }
137106c3fb27SDimitry Andric 
137206c3fb27SDimitry Andric   template <class _Func>
137306c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
137406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
137506c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
137606c3fb27SDimitry Andric     if (!has_value()) {
137706c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
137806c3fb27SDimitry Andric     }
137906c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
138006c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
138106c3fb27SDimitry Andric     } else {
138206c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
138306c3fb27SDimitry Andric       return expected<_Up, _Err>();
138406c3fb27SDimitry Andric     }
138506c3fb27SDimitry Andric   }
138606c3fb27SDimitry Andric 
138706c3fb27SDimitry Andric   template <class _Func>
138806c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
138906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
139006c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
139106c3fb27SDimitry Andric     if (!has_value()) {
139206c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
139306c3fb27SDimitry Andric     }
139406c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
139506c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
139606c3fb27SDimitry Andric     } else {
139706c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
139806c3fb27SDimitry Andric       return expected<_Up, _Err>();
139906c3fb27SDimitry Andric     }
140006c3fb27SDimitry Andric   }
140106c3fb27SDimitry Andric 
140206c3fb27SDimitry Andric   template <class _Func>
140306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
140406c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
140506c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
140606c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
140706c3fb27SDimitry Andric     if (has_value()) {
140806c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
140906c3fb27SDimitry Andric     }
141006c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
141106c3fb27SDimitry Andric   }
141206c3fb27SDimitry Andric 
141306c3fb27SDimitry Andric   template <class _Func>
141406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
141506c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
141606c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
141706c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
141806c3fb27SDimitry Andric     if (has_value()) {
141906c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
142006c3fb27SDimitry Andric     }
142106c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
142206c3fb27SDimitry Andric   }
142306c3fb27SDimitry Andric 
142406c3fb27SDimitry Andric   template <class _Func>
142506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
142606c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
142706c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
142806c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
142906c3fb27SDimitry Andric     if (has_value()) {
143006c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
143106c3fb27SDimitry Andric     }
143206c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
143306c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
143406c3fb27SDimitry Andric   }
143506c3fb27SDimitry Andric 
143606c3fb27SDimitry Andric   template <class _Func>
143706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
143806c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
143906c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
144006c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
144106c3fb27SDimitry Andric     if (has_value()) {
144206c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
144306c3fb27SDimitry Andric     }
144406c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
144506c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
144606c3fb27SDimitry Andric   }
144706c3fb27SDimitry Andric 
1448bdd1243dSDimitry Andric   // [expected.void.eq], equality operators
1449bdd1243dSDimitry Andric   template <class _T2, class _E2>
1450bdd1243dSDimitry Andric     requires is_void_v<_T2>
1451bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
1452bdd1243dSDimitry Andric     if (__x.__has_val_ != __y.__has_val_) {
1453bdd1243dSDimitry Andric       return false;
1454bdd1243dSDimitry Andric     } else {
1455bdd1243dSDimitry Andric       return __x.__has_val_ || static_cast<bool>(__x.__union_.__unex_ == __y.__union_.__unex_);
1456bdd1243dSDimitry Andric     }
1457bdd1243dSDimitry Andric   }
1458bdd1243dSDimitry Andric 
1459bdd1243dSDimitry Andric   template <class _E2>
1460bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) {
1461bdd1243dSDimitry Andric     return !__x.__has_val_ && static_cast<bool>(__x.__union_.__unex_ == __y.error());
1462bdd1243dSDimitry Andric   }
1463bdd1243dSDimitry Andric 
1464bdd1243dSDimitry Andric private:
1465bdd1243dSDimitry Andric   struct __empty_t {};
146606c3fb27SDimitry Andric 
146706c3fb27SDimitry Andric   template <class _ErrorType>
146806c3fb27SDimitry Andric   union __union_t {
1469bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
1470bdd1243dSDimitry Andric 
1471*b121cb00SDimitry Andric     template <class... _Args>
1472*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(std::unexpect_t, _Args&&... __args)
1473*b121cb00SDimitry Andric         : __unex_(std::forward<_Args>(__args)...) {}
1474*b121cb00SDimitry Andric 
147506c3fb27SDimitry Andric     template <class _Func, class... _Args>
147606c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
147706c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
147806c3fb27SDimitry Andric         : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
147906c3fb27SDimitry Andric 
1480*b121cb00SDimitry Andric     template <class _Union>
1481*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(bool __has_val, _Union&& __other) {
1482*b121cb00SDimitry Andric       if (__has_val)
1483*b121cb00SDimitry Andric         std::construct_at(std::addressof(__empty_));
1484*b121cb00SDimitry Andric       else
1485*b121cb00SDimitry Andric         std::construct_at(std::addressof(__unex_), std::forward<_Union>(__other).__unex_);
1486*b121cb00SDimitry Andric     }
1487*b121cb00SDimitry Andric 
1488bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
148906c3fb27SDimitry Andric       requires(is_trivially_destructible_v<_ErrorType>)
149006c3fb27SDimitry Andric     = default;
149106c3fb27SDimitry Andric 
149206c3fb27SDimitry Andric     // the expected's destructor handles this
149306c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {}
149406c3fb27SDimitry Andric 
149506c3fb27SDimitry Andric     __empty_t __empty_;
149606c3fb27SDimitry Andric     _ErrorType __unex_;
149706c3fb27SDimitry Andric   };
149806c3fb27SDimitry Andric 
149906c3fb27SDimitry Andric   // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
150006c3fb27SDimitry Andric   // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
150106c3fb27SDimitry Andric   // it's not clear that it's implementable, given that the function is allowed to clobber
150206c3fb27SDimitry Andric   // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
150306c3fb27SDimitry Andric   template <class _ErrorType>
150406c3fb27SDimitry Andric     requires is_trivially_move_constructible_v<_ErrorType>
150506c3fb27SDimitry Andric   union __union_t<_ErrorType> {
150606c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
150706c3fb27SDimitry Andric 
1508*b121cb00SDimitry Andric     template <class... _Args>
1509*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(std::unexpect_t, _Args&&... __args)
1510*b121cb00SDimitry Andric         : __unex_(std::forward<_Args>(__args)...) {}
1511*b121cb00SDimitry Andric 
151206c3fb27SDimitry Andric     template <class _Func, class... _Args>
151306c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
151406c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
151506c3fb27SDimitry Andric         : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
151606c3fb27SDimitry Andric 
1517*b121cb00SDimitry Andric     template <class _Union>
1518*b121cb00SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(bool __has_val, _Union&& __other) {
1519*b121cb00SDimitry Andric       if (__has_val)
1520*b121cb00SDimitry Andric         std::construct_at(std::addressof(__empty_));
1521*b121cb00SDimitry Andric       else
1522*b121cb00SDimitry Andric         std::construct_at(std::addressof(__unex_), std::forward<_Union>(__other).__unex_);
1523*b121cb00SDimitry Andric     }
1524*b121cb00SDimitry Andric 
152506c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
152606c3fb27SDimitry Andric       requires(is_trivially_destructible_v<_ErrorType>)
1527bdd1243dSDimitry Andric     = default;
1528bdd1243dSDimitry Andric 
1529bdd1243dSDimitry Andric     // the expected's destructor handles this
1530bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
153106c3fb27SDimitry Andric       requires(!is_trivially_destructible_v<_ErrorType>)
1532bdd1243dSDimitry Andric     {}
1533bdd1243dSDimitry Andric 
1534bdd1243dSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
153506c3fb27SDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_;
153606c3fb27SDimitry Andric   };
1537bdd1243dSDimitry Andric 
153806c3fb27SDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Err> __union_;
1539bdd1243dSDimitry Andric   bool __has_val_;
1540bdd1243dSDimitry Andric };
1541bdd1243dSDimitry Andric 
1542bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
1543bdd1243dSDimitry Andric 
1544bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER >= 23
1545bdd1243dSDimitry Andric 
154606c3fb27SDimitry Andric _LIBCPP_POP_MACROS
154706c3fb27SDimitry Andric 
1548bdd1243dSDimitry Andric #endif // _LIBCPP___EXPECTED_EXPECTED_H
1549