xref: /freebsd-src/contrib/llvm-project/libcxx/include/__expected/expected.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1*bdd1243dSDimitry Andric // -*- C++ -*-
2*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
3*bdd1243dSDimitry Andric //
4*bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6*bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*bdd1243dSDimitry Andric //
8*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
9*bdd1243dSDimitry Andric #ifndef _LIBCPP___EXPECTED_EXPECTED_H
10*bdd1243dSDimitry Andric #define _LIBCPP___EXPECTED_EXPECTED_H
11*bdd1243dSDimitry Andric 
12*bdd1243dSDimitry Andric #include <__assert>
13*bdd1243dSDimitry Andric #include <__config>
14*bdd1243dSDimitry Andric #include <__expected/bad_expected_access.h>
15*bdd1243dSDimitry Andric #include <__expected/unexpect.h>
16*bdd1243dSDimitry Andric #include <__expected/unexpected.h>
17*bdd1243dSDimitry Andric #include <__memory/addressof.h>
18*bdd1243dSDimitry Andric #include <__memory/construct_at.h>
19*bdd1243dSDimitry Andric #include <__type_traits/conjunction.h>
20*bdd1243dSDimitry Andric #include <__type_traits/disjunction.h>
21*bdd1243dSDimitry Andric #include <__type_traits/is_assignable.h>
22*bdd1243dSDimitry Andric #include <__type_traits/is_constructible.h>
23*bdd1243dSDimitry Andric #include <__type_traits/is_convertible.h>
24*bdd1243dSDimitry Andric #include <__type_traits/is_copy_assignable.h>
25*bdd1243dSDimitry Andric #include <__type_traits/is_copy_constructible.h>
26*bdd1243dSDimitry Andric #include <__type_traits/is_default_constructible.h>
27*bdd1243dSDimitry Andric #include <__type_traits/is_function.h>
28*bdd1243dSDimitry Andric #include <__type_traits/is_move_assignable.h>
29*bdd1243dSDimitry Andric #include <__type_traits/is_move_constructible.h>
30*bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_constructible.h>
31*bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_copy_assignable.h>
32*bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_copy_constructible.h>
33*bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_default_constructible.h>
34*bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_move_assignable.h>
35*bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_move_constructible.h>
36*bdd1243dSDimitry Andric #include <__type_traits/is_reference.h>
37*bdd1243dSDimitry Andric #include <__type_traits/is_same.h>
38*bdd1243dSDimitry Andric #include <__type_traits/is_swappable.h>
39*bdd1243dSDimitry Andric #include <__type_traits/is_trivially_copy_constructible.h>
40*bdd1243dSDimitry Andric #include <__type_traits/is_trivially_destructible.h>
41*bdd1243dSDimitry Andric #include <__type_traits/is_trivially_move_constructible.h>
42*bdd1243dSDimitry Andric #include <__type_traits/is_void.h>
43*bdd1243dSDimitry Andric #include <__type_traits/lazy.h>
44*bdd1243dSDimitry Andric #include <__type_traits/negation.h>
45*bdd1243dSDimitry Andric #include <__type_traits/remove_cv.h>
46*bdd1243dSDimitry Andric #include <__type_traits/remove_cvref.h>
47*bdd1243dSDimitry Andric #include <__utility/exception_guard.h>
48*bdd1243dSDimitry Andric #include <__utility/forward.h>
49*bdd1243dSDimitry Andric #include <__utility/in_place.h>
50*bdd1243dSDimitry Andric #include <__utility/move.h>
51*bdd1243dSDimitry Andric #include <__utility/swap.h>
52*bdd1243dSDimitry Andric #include <cstdlib> // for std::abort
53*bdd1243dSDimitry Andric #include <initializer_list>
54*bdd1243dSDimitry Andric 
55*bdd1243dSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
56*bdd1243dSDimitry Andric #  pragma GCC system_header
57*bdd1243dSDimitry Andric #endif
58*bdd1243dSDimitry Andric 
59*bdd1243dSDimitry Andric #if _LIBCPP_STD_VER >= 23
60*bdd1243dSDimitry Andric 
61*bdd1243dSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
62*bdd1243dSDimitry Andric 
63*bdd1243dSDimitry Andric namespace __expected {
64*bdd1243dSDimitry Andric 
65*bdd1243dSDimitry Andric template <class _Err, class _Arg>
66*bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) {
67*bdd1243dSDimitry Andric #  ifndef _LIBCPP_NO_EXCEPTIONS
68*bdd1243dSDimitry Andric   throw bad_expected_access<_Err>(std::forward<_Arg>(__arg));
69*bdd1243dSDimitry Andric #  else
70*bdd1243dSDimitry Andric   (void)__arg;
71*bdd1243dSDimitry Andric   std::abort();
72*bdd1243dSDimitry Andric #  endif
73*bdd1243dSDimitry Andric }
74*bdd1243dSDimitry Andric 
75*bdd1243dSDimitry Andric } // namespace __expected
76*bdd1243dSDimitry Andric 
77*bdd1243dSDimitry Andric template <class _Tp, class _Err>
78*bdd1243dSDimitry Andric class expected {
79*bdd1243dSDimitry Andric   static_assert(
80*bdd1243dSDimitry Andric       !is_reference_v<_Tp> &&
81*bdd1243dSDimitry Andric           !is_function_v<_Tp> &&
82*bdd1243dSDimitry Andric           !is_same_v<remove_cv_t<_Tp>, in_place_t> &&
83*bdd1243dSDimitry Andric           !is_same_v<remove_cv_t<_Tp>, unexpect_t> &&
84*bdd1243dSDimitry Andric           !__is_std_unexpected<remove_cv_t<_Tp>>::value &&
85*bdd1243dSDimitry Andric           __valid_std_unexpected<_Err>::value
86*bdd1243dSDimitry Andric       ,
87*bdd1243dSDimitry Andric       "[expected.object.general] A program that instantiates the definition of template expected<T, E> for a "
88*bdd1243dSDimitry Andric       "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a "
89*bdd1243dSDimitry Andric       "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the "
90*bdd1243dSDimitry Andric       "definition of the template expected<T, E> with a type for the E parameter that is not a valid "
91*bdd1243dSDimitry Andric       "template argument for unexpected is ill-formed.");
92*bdd1243dSDimitry Andric 
93*bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
94*bdd1243dSDimitry Andric   friend class expected;
95*bdd1243dSDimitry Andric 
96*bdd1243dSDimitry Andric public:
97*bdd1243dSDimitry Andric   using value_type      = _Tp;
98*bdd1243dSDimitry Andric   using error_type      = _Err;
99*bdd1243dSDimitry Andric   using unexpected_type = unexpected<_Err>;
100*bdd1243dSDimitry Andric 
101*bdd1243dSDimitry Andric   template <class _Up>
102*bdd1243dSDimitry Andric   using rebind = expected<_Up, error_type>;
103*bdd1243dSDimitry Andric 
104*bdd1243dSDimitry Andric   // [expected.object.ctor], constructors
105*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected()
106*bdd1243dSDimitry Andric     noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened
107*bdd1243dSDimitry Andric     requires is_default_constructible_v<_Tp>
108*bdd1243dSDimitry Andric       : __has_val_(true) {
109*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__val_));
110*bdd1243dSDimitry Andric   }
111*bdd1243dSDimitry Andric 
112*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
113*bdd1243dSDimitry Andric 
114*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
115*bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Tp> &&
116*bdd1243dSDimitry Andric              is_copy_constructible_v<_Err> &&
117*bdd1243dSDimitry Andric              is_trivially_copy_constructible_v<_Tp> &&
118*bdd1243dSDimitry Andric              is_trivially_copy_constructible_v<_Err>)
119*bdd1243dSDimitry Andric   = default;
120*bdd1243dSDimitry Andric 
121*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other)
122*bdd1243dSDimitry Andric     noexcept(is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened
123*bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
124*bdd1243dSDimitry Andric              !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>))
125*bdd1243dSDimitry Andric       : __has_val_(__other.__has_val_) {
126*bdd1243dSDimitry Andric     if (__has_val_) {
127*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_);
128*bdd1243dSDimitry Andric     } else {
129*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_);
130*bdd1243dSDimitry Andric     }
131*bdd1243dSDimitry Andric   }
132*bdd1243dSDimitry Andric 
133*bdd1243dSDimitry Andric 
134*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
135*bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err>
136*bdd1243dSDimitry Andric               && is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)
137*bdd1243dSDimitry Andric   = default;
138*bdd1243dSDimitry Andric 
139*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other)
140*bdd1243dSDimitry Andric     noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>)
141*bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
142*bdd1243dSDimitry Andric              !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>))
143*bdd1243dSDimitry Andric       : __has_val_(__other.__has_val_) {
144*bdd1243dSDimitry Andric     if (__has_val_) {
145*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_));
146*bdd1243dSDimitry Andric     } else {
147*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_));
148*bdd1243dSDimitry Andric     }
149*bdd1243dSDimitry Andric   }
150*bdd1243dSDimitry Andric 
151*bdd1243dSDimitry Andric private:
152*bdd1243dSDimitry Andric   template <class _Up, class _OtherErr, class _UfQual, class _OtherErrQual>
153*bdd1243dSDimitry Andric   using __can_convert =
154*bdd1243dSDimitry Andric       _And< is_constructible<_Tp, _UfQual>,
155*bdd1243dSDimitry Andric             is_constructible<_Err, _OtherErrQual>,
156*bdd1243dSDimitry Andric             _Not<is_constructible<_Tp, expected<_Up, _OtherErr>&>>,
157*bdd1243dSDimitry Andric             _Not<is_constructible<_Tp, expected<_Up, _OtherErr>>>,
158*bdd1243dSDimitry Andric             _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>&>>,
159*bdd1243dSDimitry Andric             _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>>>,
160*bdd1243dSDimitry Andric             _Not<is_convertible<expected<_Up, _OtherErr>&, _Tp>>,
161*bdd1243dSDimitry Andric             _Not<is_convertible<expected<_Up, _OtherErr>&&, _Tp>>,
162*bdd1243dSDimitry Andric             _Not<is_convertible<const expected<_Up, _OtherErr>&, _Tp>>,
163*bdd1243dSDimitry Andric             _Not<is_convertible<const expected<_Up, _OtherErr>&&, _Tp>>,
164*bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
165*bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
166*bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
167*bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >;
168*bdd1243dSDimitry Andric 
169*bdd1243dSDimitry Andric 
170*bdd1243dSDimitry Andric public:
171*bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
172*bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value
173*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _Up&, _Tp> ||
174*bdd1243dSDimitry Andric                                            !is_convertible_v<const _OtherErr&, _Err>)
175*bdd1243dSDimitry Andric   expected(const expected<_Up, _OtherErr>& __other)
176*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Tp, const _Up&> &&
177*bdd1243dSDimitry Andric              is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
178*bdd1243dSDimitry Andric       : __has_val_(__other.__has_val_) {
179*bdd1243dSDimitry Andric     if (__has_val_) {
180*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_);
181*bdd1243dSDimitry Andric     } else {
182*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_);
183*bdd1243dSDimitry Andric     }
184*bdd1243dSDimitry Andric   }
185*bdd1243dSDimitry Andric 
186*bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
187*bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value
188*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>)
189*bdd1243dSDimitry Andric   expected(expected<_Up, _OtherErr>&& __other)
190*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
191*bdd1243dSDimitry Andric       : __has_val_(__other.__has_val_) {
192*bdd1243dSDimitry Andric     if (__has_val_) {
193*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_));
194*bdd1243dSDimitry Andric     } else {
195*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_));
196*bdd1243dSDimitry Andric     }
197*bdd1243dSDimitry Andric   }
198*bdd1243dSDimitry Andric 
199*bdd1243dSDimitry Andric   template <class _Up = _Tp>
200*bdd1243dSDimitry Andric     requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> &&
201*bdd1243dSDimitry Andric              !__is_std_unexpected<remove_cvref_t<_Up>>::value && is_constructible_v<_Tp, _Up>)
202*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>)
203*bdd1243dSDimitry Andric   expected(_Up&& __u)
204*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened
205*bdd1243dSDimitry Andric       : __has_val_(true) {
206*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__val_), std::forward<_Up>(__u));
207*bdd1243dSDimitry Andric   }
208*bdd1243dSDimitry Andric 
209*bdd1243dSDimitry Andric 
210*bdd1243dSDimitry Andric   template <class _OtherErr>
211*bdd1243dSDimitry Andric     requires is_constructible_v<_Err, const _OtherErr&>
212*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
213*bdd1243dSDimitry Andric   expected(const unexpected<_OtherErr>& __unex)
214*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
215*bdd1243dSDimitry Andric       : __has_val_(false) {
216*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__unex_), __unex.error());
217*bdd1243dSDimitry Andric   }
218*bdd1243dSDimitry Andric 
219*bdd1243dSDimitry Andric   template <class _OtherErr>
220*bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _OtherErr>
221*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
222*bdd1243dSDimitry Andric   expected(unexpected<_OtherErr>&& __unex)
223*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
224*bdd1243dSDimitry Andric       : __has_val_(false) {
225*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error()));
226*bdd1243dSDimitry Andric   }
227*bdd1243dSDimitry Andric 
228*bdd1243dSDimitry Andric   template <class... _Args>
229*bdd1243dSDimitry Andric     requires is_constructible_v<_Tp, _Args...>
230*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args)
231*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Tp, _Args...>) // strengthened
232*bdd1243dSDimitry Andric       : __has_val_(true) {
233*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...);
234*bdd1243dSDimitry Andric   }
235*bdd1243dSDimitry Andric 
236*bdd1243dSDimitry Andric   template <class _Up, class... _Args>
237*bdd1243dSDimitry Andric     requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... >
238*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit
239*bdd1243dSDimitry Andric   expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
240*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened
241*bdd1243dSDimitry Andric       : __has_val_(true) {
242*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...);
243*bdd1243dSDimitry Andric   }
244*bdd1243dSDimitry Andric 
245*bdd1243dSDimitry Andric   template <class... _Args>
246*bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _Args...>
247*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args)
248*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, _Args...>)  // strengthened
249*bdd1243dSDimitry Andric       : __has_val_(false) {
250*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...);
251*bdd1243dSDimitry Andric   }
252*bdd1243dSDimitry Andric 
253*bdd1243dSDimitry Andric   template <class _Up, class... _Args>
254*bdd1243dSDimitry Andric     requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
255*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit
256*bdd1243dSDimitry Andric   expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
257*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
258*bdd1243dSDimitry Andric       : __has_val_(false) {
259*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...);
260*bdd1243dSDimitry Andric   }
261*bdd1243dSDimitry Andric 
262*bdd1243dSDimitry Andric   // [expected.object.dtor], destructor
263*bdd1243dSDimitry Andric 
264*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
265*bdd1243dSDimitry Andric     requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
266*bdd1243dSDimitry Andric   = default;
267*bdd1243dSDimitry Andric 
268*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
269*bdd1243dSDimitry Andric     requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
270*bdd1243dSDimitry Andric   {
271*bdd1243dSDimitry Andric     if (__has_val_) {
272*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__val_));
273*bdd1243dSDimitry Andric     } else {
274*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__unex_));
275*bdd1243dSDimitry Andric     }
276*bdd1243dSDimitry Andric   }
277*bdd1243dSDimitry Andric 
278*bdd1243dSDimitry Andric private:
279*bdd1243dSDimitry Andric   template <class _T1, class _T2, class... _Args>
280*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr void __reinit_expected(_T1& __newval, _T2& __oldval, _Args&&... __args) {
281*bdd1243dSDimitry Andric     if constexpr (is_nothrow_constructible_v<_T1, _Args...>) {
282*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__oldval));
283*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...);
284*bdd1243dSDimitry Andric     } else if constexpr (is_nothrow_move_constructible_v<_T1>) {
285*bdd1243dSDimitry Andric       _T1 __tmp(std::forward<_Args>(__args)...);
286*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__oldval));
287*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__newval), std::move(__tmp));
288*bdd1243dSDimitry Andric     } else {
289*bdd1243dSDimitry Andric       static_assert(
290*bdd1243dSDimitry Andric           is_nothrow_move_constructible_v<_T2>,
291*bdd1243dSDimitry Andric           "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can "
292*bdd1243dSDimitry Andric           "be reverted to the previous state in case an exception is thrown during the assignment.");
293*bdd1243dSDimitry Andric       _T2 __tmp(std::move(__oldval));
294*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__oldval));
295*bdd1243dSDimitry Andric       __exception_guard __trans([&] { std::construct_at(std::addressof(__oldval), std::move(__tmp)); });
296*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...);
297*bdd1243dSDimitry Andric       __trans.__complete();
298*bdd1243dSDimitry Andric     }
299*bdd1243dSDimitry Andric   }
300*bdd1243dSDimitry Andric 
301*bdd1243dSDimitry Andric public:
302*bdd1243dSDimitry Andric   // [expected.object.assign], assignment
303*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
304*bdd1243dSDimitry Andric 
305*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs)
306*bdd1243dSDimitry Andric     noexcept(is_nothrow_copy_assignable_v<_Tp> &&
307*bdd1243dSDimitry Andric              is_nothrow_copy_constructible_v<_Tp> &&
308*bdd1243dSDimitry Andric              is_nothrow_copy_assignable_v<_Err> &&
309*bdd1243dSDimitry Andric              is_nothrow_copy_constructible_v<_Err>) // strengthened
310*bdd1243dSDimitry Andric     requires(is_copy_assignable_v<_Tp> &&
311*bdd1243dSDimitry Andric              is_copy_constructible_v<_Tp> &&
312*bdd1243dSDimitry Andric              is_copy_assignable_v<_Err> &&
313*bdd1243dSDimitry Andric              is_copy_constructible_v<_Err> &&
314*bdd1243dSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> ||
315*bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Err>))
316*bdd1243dSDimitry Andric   {
317*bdd1243dSDimitry Andric     if (__has_val_ && __rhs.__has_val_) {
318*bdd1243dSDimitry Andric       __union_.__val_ = __rhs.__union_.__val_;
319*bdd1243dSDimitry Andric     } else if (__has_val_) {
320*bdd1243dSDimitry Andric       __reinit_expected(__union_.__unex_, __union_.__val_, __rhs.__union_.__unex_);
321*bdd1243dSDimitry Andric     } else if (__rhs.__has_val_) {
322*bdd1243dSDimitry Andric       __reinit_expected(__union_.__val_, __union_.__unex_, __rhs.__union_.__val_);
323*bdd1243dSDimitry Andric     } else {
324*bdd1243dSDimitry Andric       __union_.__unex_ = __rhs.__union_.__unex_;
325*bdd1243dSDimitry Andric     }
326*bdd1243dSDimitry Andric     // note: only reached if no exception+rollback was done inside __reinit_expected
327*bdd1243dSDimitry Andric     __has_val_ = __rhs.__has_val_;
328*bdd1243dSDimitry Andric     return *this;
329*bdd1243dSDimitry Andric   }
330*bdd1243dSDimitry Andric 
331*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs)
332*bdd1243dSDimitry Andric     noexcept(is_nothrow_move_assignable_v<_Tp> &&
333*bdd1243dSDimitry Andric              is_nothrow_move_constructible_v<_Tp> &&
334*bdd1243dSDimitry Andric              is_nothrow_move_assignable_v<_Err> &&
335*bdd1243dSDimitry Andric              is_nothrow_move_constructible_v<_Err>)
336*bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Tp> &&
337*bdd1243dSDimitry Andric              is_move_assignable_v<_Tp> &&
338*bdd1243dSDimitry Andric              is_move_constructible_v<_Err> &&
339*bdd1243dSDimitry Andric              is_move_assignable_v<_Err> &&
340*bdd1243dSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> ||
341*bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Err>))
342*bdd1243dSDimitry Andric   {
343*bdd1243dSDimitry Andric     if (__has_val_ && __rhs.__has_val_) {
344*bdd1243dSDimitry Andric       __union_.__val_ = std::move(__rhs.__union_.__val_);
345*bdd1243dSDimitry Andric     } else if (__has_val_) {
346*bdd1243dSDimitry Andric       __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__rhs.__union_.__unex_));
347*bdd1243dSDimitry Andric     } else if (__rhs.__has_val_) {
348*bdd1243dSDimitry Andric       __reinit_expected(__union_.__val_, __union_.__unex_, std::move(__rhs.__union_.__val_));
349*bdd1243dSDimitry Andric     } else {
350*bdd1243dSDimitry Andric       __union_.__unex_ = std::move(__rhs.__union_.__unex_);
351*bdd1243dSDimitry Andric     }
352*bdd1243dSDimitry Andric     // note: only reached if no exception+rollback was done inside __reinit_expected
353*bdd1243dSDimitry Andric     __has_val_ = __rhs.__has_val_;
354*bdd1243dSDimitry Andric     return *this;
355*bdd1243dSDimitry Andric   }
356*bdd1243dSDimitry Andric 
357*bdd1243dSDimitry Andric   template <class _Up = _Tp>
358*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v)
359*bdd1243dSDimitry Andric     requires(!is_same_v<expected, remove_cvref_t<_Up>> &&
360*bdd1243dSDimitry Andric              !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
361*bdd1243dSDimitry Andric              is_constructible_v<_Tp, _Up> &&
362*bdd1243dSDimitry Andric              is_assignable_v<_Tp&, _Up> &&
363*bdd1243dSDimitry Andric              (is_nothrow_constructible_v<_Tp, _Up> ||
364*bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Tp> ||
365*bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Err>))
366*bdd1243dSDimitry Andric   {
367*bdd1243dSDimitry Andric     if (__has_val_) {
368*bdd1243dSDimitry Andric       __union_.__val_ = std::forward<_Up>(__v);
369*bdd1243dSDimitry Andric     } else {
370*bdd1243dSDimitry Andric       __reinit_expected(__union_.__val_, __union_.__unex_, std::forward<_Up>(__v));
371*bdd1243dSDimitry Andric       __has_val_ = true;
372*bdd1243dSDimitry Andric     }
373*bdd1243dSDimitry Andric     return *this;
374*bdd1243dSDimitry Andric   }
375*bdd1243dSDimitry Andric 
376*bdd1243dSDimitry Andric private:
377*bdd1243dSDimitry Andric   template <class _OtherErrQual>
378*bdd1243dSDimitry Andric   static constexpr bool __can_assign_from_unexpected =
379*bdd1243dSDimitry Andric       _And< is_constructible<_Err, _OtherErrQual>,
380*bdd1243dSDimitry Andric             is_assignable<_Err&, _OtherErrQual>,
381*bdd1243dSDimitry Andric             _Lazy<_Or,
382*bdd1243dSDimitry Andric                   is_nothrow_constructible<_Err, _OtherErrQual>,
383*bdd1243dSDimitry Andric                   is_nothrow_move_constructible<_Tp>,
384*bdd1243dSDimitry Andric                   is_nothrow_move_constructible<_Err>> >::value;
385*bdd1243dSDimitry Andric 
386*bdd1243dSDimitry Andric public:
387*bdd1243dSDimitry Andric   template <class _OtherErr>
388*bdd1243dSDimitry Andric     requires(__can_assign_from_unexpected<const _OtherErr&>)
389*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
390*bdd1243dSDimitry Andric     if (__has_val_) {
391*bdd1243dSDimitry Andric       __reinit_expected(__union_.__unex_, __union_.__val_, __un.error());
392*bdd1243dSDimitry Andric       __has_val_ = false;
393*bdd1243dSDimitry Andric     } else {
394*bdd1243dSDimitry Andric       __union_.__unex_ = __un.error();
395*bdd1243dSDimitry Andric     }
396*bdd1243dSDimitry Andric     return *this;
397*bdd1243dSDimitry Andric   }
398*bdd1243dSDimitry Andric 
399*bdd1243dSDimitry Andric   template <class _OtherErr>
400*bdd1243dSDimitry Andric     requires(__can_assign_from_unexpected<_OtherErr>)
401*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
402*bdd1243dSDimitry Andric     if (__has_val_) {
403*bdd1243dSDimitry Andric       __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__un.error()));
404*bdd1243dSDimitry Andric       __has_val_ = false;
405*bdd1243dSDimitry Andric     } else {
406*bdd1243dSDimitry Andric       __union_.__unex_ = std::move(__un.error());
407*bdd1243dSDimitry Andric     }
408*bdd1243dSDimitry Andric     return *this;
409*bdd1243dSDimitry Andric   }
410*bdd1243dSDimitry Andric 
411*bdd1243dSDimitry Andric   template <class... _Args>
412*bdd1243dSDimitry Andric     requires is_nothrow_constructible_v<_Tp, _Args...>
413*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept {
414*bdd1243dSDimitry Andric     if (__has_val_) {
415*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__val_));
416*bdd1243dSDimitry Andric     } else {
417*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__unex_));
418*bdd1243dSDimitry Andric       __has_val_ = true;
419*bdd1243dSDimitry Andric     }
420*bdd1243dSDimitry Andric     return *std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...);
421*bdd1243dSDimitry Andric   }
422*bdd1243dSDimitry Andric 
423*bdd1243dSDimitry Andric   template <class _Up, class... _Args>
424*bdd1243dSDimitry Andric     requires is_nothrow_constructible_v< _Tp, initializer_list<_Up>&, _Args... >
425*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept {
426*bdd1243dSDimitry Andric     if (__has_val_) {
427*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__val_));
428*bdd1243dSDimitry Andric     } else {
429*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__unex_));
430*bdd1243dSDimitry Andric       __has_val_ = true;
431*bdd1243dSDimitry Andric     }
432*bdd1243dSDimitry Andric     return *std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...);
433*bdd1243dSDimitry Andric   }
434*bdd1243dSDimitry Andric 
435*bdd1243dSDimitry Andric 
436*bdd1243dSDimitry Andric public:
437*bdd1243dSDimitry Andric   // [expected.object.swap], swap
438*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs)
439*bdd1243dSDimitry Andric     noexcept(is_nothrow_move_constructible_v<_Tp> &&
440*bdd1243dSDimitry Andric              is_nothrow_swappable_v<_Tp> &&
441*bdd1243dSDimitry Andric              is_nothrow_move_constructible_v<_Err> &&
442*bdd1243dSDimitry Andric              is_nothrow_swappable_v<_Err>)
443*bdd1243dSDimitry Andric     requires(is_swappable_v<_Tp> &&
444*bdd1243dSDimitry Andric              is_swappable_v<_Err> &&
445*bdd1243dSDimitry Andric              is_move_constructible_v<_Tp> &&
446*bdd1243dSDimitry Andric              is_move_constructible_v<_Err> &&
447*bdd1243dSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> ||
448*bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Err>))
449*bdd1243dSDimitry Andric   {
450*bdd1243dSDimitry Andric     auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) {
451*bdd1243dSDimitry Andric       if constexpr (is_nothrow_move_constructible_v<_Err>) {
452*bdd1243dSDimitry Andric         _Err __tmp(std::move(__with_err.__union_.__unex_));
453*bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__with_err.__union_.__unex_));
454*bdd1243dSDimitry Andric         __exception_guard __trans([&] {
455*bdd1243dSDimitry Andric           std::construct_at(std::addressof(__with_err.__union_.__unex_), std::move(__tmp));
456*bdd1243dSDimitry Andric         });
457*bdd1243dSDimitry Andric         std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__with_val.__union_.__val_));
458*bdd1243dSDimitry Andric         __trans.__complete();
459*bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__with_val.__union_.__val_));
460*bdd1243dSDimitry Andric         std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__tmp));
461*bdd1243dSDimitry Andric       } else {
462*bdd1243dSDimitry Andric         static_assert(is_nothrow_move_constructible_v<_Tp>,
463*bdd1243dSDimitry Andric                       "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so "
464*bdd1243dSDimitry Andric                       "that it can be reverted to the previous state in case an exception is thrown during swap.");
465*bdd1243dSDimitry Andric         _Tp __tmp(std::move(__with_val.__union_.__val_));
466*bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__with_val.__union_.__val_));
467*bdd1243dSDimitry Andric         __exception_guard __trans([&] {
468*bdd1243dSDimitry Andric           std::construct_at(std::addressof(__with_val.__union_.__val_), std::move(__tmp));
469*bdd1243dSDimitry Andric         });
470*bdd1243dSDimitry Andric         std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_));
471*bdd1243dSDimitry Andric         __trans.__complete();
472*bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__with_err.__union_.__unex_));
473*bdd1243dSDimitry Andric         std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__tmp));
474*bdd1243dSDimitry Andric       }
475*bdd1243dSDimitry Andric       __with_val.__has_val_ = false;
476*bdd1243dSDimitry Andric       __with_err.__has_val_ = true;
477*bdd1243dSDimitry Andric     };
478*bdd1243dSDimitry Andric 
479*bdd1243dSDimitry Andric     if (__has_val_) {
480*bdd1243dSDimitry Andric       if (__rhs.__has_val_) {
481*bdd1243dSDimitry Andric         using std::swap;
482*bdd1243dSDimitry Andric         swap(__union_.__val_, __rhs.__union_.__val_);
483*bdd1243dSDimitry Andric       } else {
484*bdd1243dSDimitry Andric         __swap_val_unex_impl(*this, __rhs);
485*bdd1243dSDimitry Andric       }
486*bdd1243dSDimitry Andric     } else {
487*bdd1243dSDimitry Andric       if (__rhs.__has_val_) {
488*bdd1243dSDimitry Andric         __swap_val_unex_impl(__rhs, *this);
489*bdd1243dSDimitry Andric       } else {
490*bdd1243dSDimitry Andric         using std::swap;
491*bdd1243dSDimitry Andric         swap(__union_.__unex_, __rhs.__union_.__unex_);
492*bdd1243dSDimitry Andric       }
493*bdd1243dSDimitry Andric     }
494*bdd1243dSDimitry Andric   }
495*bdd1243dSDimitry Andric 
496*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y)
497*bdd1243dSDimitry Andric     noexcept(noexcept(__x.swap(__y)))
498*bdd1243dSDimitry Andric     requires requires { __x.swap(__y); }
499*bdd1243dSDimitry Andric   {
500*bdd1243dSDimitry Andric     __x.swap(__y);
501*bdd1243dSDimitry Andric   }
502*bdd1243dSDimitry Andric 
503*bdd1243dSDimitry Andric   // [expected.object.obs], observers
504*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept {
505*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value");
506*bdd1243dSDimitry Andric     return std::addressof(__union_.__val_);
507*bdd1243dSDimitry Andric   }
508*bdd1243dSDimitry Andric 
509*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept {
510*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value");
511*bdd1243dSDimitry Andric     return std::addressof(__union_.__val_);
512*bdd1243dSDimitry Andric   }
513*bdd1243dSDimitry Andric 
514*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
515*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
516*bdd1243dSDimitry Andric     return __union_.__val_;
517*bdd1243dSDimitry Andric   }
518*bdd1243dSDimitry Andric 
519*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
520*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
521*bdd1243dSDimitry Andric     return __union_.__val_;
522*bdd1243dSDimitry Andric   }
523*bdd1243dSDimitry Andric 
524*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
525*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
526*bdd1243dSDimitry Andric     return std::move(__union_.__val_);
527*bdd1243dSDimitry Andric   }
528*bdd1243dSDimitry Andric 
529*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
530*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
531*bdd1243dSDimitry Andric     return std::move(__union_.__val_);
532*bdd1243dSDimitry Andric   }
533*bdd1243dSDimitry Andric 
534*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; }
535*bdd1243dSDimitry Andric 
536*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
537*bdd1243dSDimitry Andric 
538*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& {
539*bdd1243dSDimitry Andric     if (!__has_val_) {
540*bdd1243dSDimitry Andric       __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
541*bdd1243dSDimitry Andric     }
542*bdd1243dSDimitry Andric     return __union_.__val_;
543*bdd1243dSDimitry Andric   }
544*bdd1243dSDimitry Andric 
545*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
546*bdd1243dSDimitry Andric     if (!__has_val_) {
547*bdd1243dSDimitry Andric       __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
548*bdd1243dSDimitry Andric     }
549*bdd1243dSDimitry Andric     return __union_.__val_;
550*bdd1243dSDimitry Andric   }
551*bdd1243dSDimitry Andric 
552*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& {
553*bdd1243dSDimitry Andric     if (!__has_val_) {
554*bdd1243dSDimitry Andric       __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
555*bdd1243dSDimitry Andric     }
556*bdd1243dSDimitry Andric     return std::move(__union_.__val_);
557*bdd1243dSDimitry Andric   }
558*bdd1243dSDimitry Andric 
559*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
560*bdd1243dSDimitry Andric     if (!__has_val_) {
561*bdd1243dSDimitry Andric       __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
562*bdd1243dSDimitry Andric     }
563*bdd1243dSDimitry Andric     return std::move(__union_.__val_);
564*bdd1243dSDimitry Andric   }
565*bdd1243dSDimitry Andric 
566*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
567*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
568*bdd1243dSDimitry Andric     return __union_.__unex_;
569*bdd1243dSDimitry Andric   }
570*bdd1243dSDimitry Andric 
571*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
572*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
573*bdd1243dSDimitry Andric     return __union_.__unex_;
574*bdd1243dSDimitry Andric   }
575*bdd1243dSDimitry Andric 
576*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
577*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
578*bdd1243dSDimitry Andric     return std::move(__union_.__unex_);
579*bdd1243dSDimitry Andric   }
580*bdd1243dSDimitry Andric 
581*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
582*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
583*bdd1243dSDimitry Andric     return std::move(__union_.__unex_);
584*bdd1243dSDimitry Andric   }
585*bdd1243dSDimitry Andric 
586*bdd1243dSDimitry Andric   template <class _Up>
587*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
588*bdd1243dSDimitry Andric     static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible");
589*bdd1243dSDimitry Andric     static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
590*bdd1243dSDimitry Andric     return __has_val_ ? __union_.__val_ : static_cast<_Tp>(std::forward<_Up>(__v));
591*bdd1243dSDimitry Andric   }
592*bdd1243dSDimitry Andric 
593*bdd1243dSDimitry Andric   template <class _Up>
594*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
595*bdd1243dSDimitry Andric     static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible");
596*bdd1243dSDimitry Andric     static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
597*bdd1243dSDimitry Andric     return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v));
598*bdd1243dSDimitry Andric   }
599*bdd1243dSDimitry Andric 
600*bdd1243dSDimitry Andric   // [expected.object.eq], equality operators
601*bdd1243dSDimitry Andric   template <class _T2, class _E2>
602*bdd1243dSDimitry Andric     requires(!is_void_v<_T2>)
603*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
604*bdd1243dSDimitry Andric     if (__x.__has_val_ != __y.__has_val_) {
605*bdd1243dSDimitry Andric       return false;
606*bdd1243dSDimitry Andric     } else {
607*bdd1243dSDimitry Andric       if (__x.__has_val_) {
608*bdd1243dSDimitry Andric         return __x.__union_.__val_ == __y.__union_.__val_;
609*bdd1243dSDimitry Andric       } else {
610*bdd1243dSDimitry Andric         return __x.__union_.__unex_ == __y.__union_.__unex_;
611*bdd1243dSDimitry Andric       }
612*bdd1243dSDimitry Andric     }
613*bdd1243dSDimitry Andric   }
614*bdd1243dSDimitry Andric 
615*bdd1243dSDimitry Andric   template <class _T2>
616*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) {
617*bdd1243dSDimitry Andric     return __x.__has_val_ && static_cast<bool>(__x.__union_.__val_ == __v);
618*bdd1243dSDimitry Andric   }
619*bdd1243dSDimitry Andric 
620*bdd1243dSDimitry Andric   template <class _E2>
621*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) {
622*bdd1243dSDimitry Andric     return !__x.__has_val_ && static_cast<bool>(__x.__union_.__unex_ == __e.error());
623*bdd1243dSDimitry Andric   }
624*bdd1243dSDimitry Andric 
625*bdd1243dSDimitry Andric private:
626*bdd1243dSDimitry Andric   struct __empty_t {};
627*bdd1243dSDimitry Andric   // use named union because [[no_unique_address]] cannot be applied to an unnamed union
628*bdd1243dSDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS union __union_t {
629*bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
630*bdd1243dSDimitry Andric 
631*bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
632*bdd1243dSDimitry Andric       requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
633*bdd1243dSDimitry Andric     = default;
634*bdd1243dSDimitry Andric 
635*bdd1243dSDimitry Andric     // the expected's destructor handles this
636*bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
637*bdd1243dSDimitry Andric       requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
638*bdd1243dSDimitry Andric     {}
639*bdd1243dSDimitry Andric 
640*bdd1243dSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
641*bdd1243dSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
642*bdd1243dSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
643*bdd1243dSDimitry Andric   } __union_;
644*bdd1243dSDimitry Andric 
645*bdd1243dSDimitry Andric   bool __has_val_;
646*bdd1243dSDimitry Andric };
647*bdd1243dSDimitry Andric 
648*bdd1243dSDimitry Andric template <class _Tp, class _Err>
649*bdd1243dSDimitry Andric   requires is_void_v<_Tp>
650*bdd1243dSDimitry Andric class expected<_Tp, _Err> {
651*bdd1243dSDimitry Andric   static_assert(__valid_std_unexpected<_Err>::value,
652*bdd1243dSDimitry Andric                 "[expected.void.general] A program that instantiates expected<T, E> with a E that is not a "
653*bdd1243dSDimitry Andric                 "valid argument for unexpected<E> is ill-formed");
654*bdd1243dSDimitry Andric 
655*bdd1243dSDimitry Andric   template <class, class>
656*bdd1243dSDimitry Andric   friend class expected;
657*bdd1243dSDimitry Andric 
658*bdd1243dSDimitry Andric   template <class _Up, class _OtherErr, class _OtherErrQual>
659*bdd1243dSDimitry Andric   using __can_convert =
660*bdd1243dSDimitry Andric       _And< is_void<_Up>,
661*bdd1243dSDimitry Andric             is_constructible<_Err, _OtherErrQual>,
662*bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
663*bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
664*bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
665*bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>>>;
666*bdd1243dSDimitry Andric 
667*bdd1243dSDimitry Andric public:
668*bdd1243dSDimitry Andric   using value_type      = _Tp;
669*bdd1243dSDimitry Andric   using error_type      = _Err;
670*bdd1243dSDimitry Andric   using unexpected_type = unexpected<_Err>;
671*bdd1243dSDimitry Andric 
672*bdd1243dSDimitry Andric   template <class _Up>
673*bdd1243dSDimitry Andric   using rebind = expected<_Up, error_type>;
674*bdd1243dSDimitry Andric 
675*bdd1243dSDimitry Andric   // [expected.void.ctor], constructors
676*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __has_val_(true) {}
677*bdd1243dSDimitry Andric 
678*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
679*bdd1243dSDimitry Andric 
680*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
681*bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>)
682*bdd1243dSDimitry Andric   = default;
683*bdd1243dSDimitry Andric 
684*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs)
685*bdd1243dSDimitry Andric     noexcept(is_nothrow_copy_constructible_v<_Err>) // strengthened
686*bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>)
687*bdd1243dSDimitry Andric       : __has_val_(__rhs.__has_val_) {
688*bdd1243dSDimitry Andric     if (!__rhs.__has_val_) {
689*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_);
690*bdd1243dSDimitry Andric     }
691*bdd1243dSDimitry Andric   }
692*bdd1243dSDimitry Andric 
693*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
694*bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
695*bdd1243dSDimitry Andric   = default;
696*bdd1243dSDimitry Andric 
697*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs)
698*bdd1243dSDimitry Andric     noexcept(is_nothrow_move_constructible_v<_Err>)
699*bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>)
700*bdd1243dSDimitry Andric       : __has_val_(__rhs.__has_val_) {
701*bdd1243dSDimitry Andric     if (!__rhs.__has_val_) {
702*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_));
703*bdd1243dSDimitry Andric     }
704*bdd1243dSDimitry Andric   }
705*bdd1243dSDimitry Andric 
706*bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
707*bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value
708*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
709*bdd1243dSDimitry Andric   expected(const expected<_Up, _OtherErr>& __rhs)
710*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
711*bdd1243dSDimitry Andric       : __has_val_(__rhs.__has_val_) {
712*bdd1243dSDimitry Andric     if (!__rhs.__has_val_) {
713*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_);
714*bdd1243dSDimitry Andric     }
715*bdd1243dSDimitry Andric   }
716*bdd1243dSDimitry Andric 
717*bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
718*bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, _OtherErr>::value
719*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
720*bdd1243dSDimitry Andric   expected(expected<_Up, _OtherErr>&& __rhs)
721*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
722*bdd1243dSDimitry Andric       : __has_val_(__rhs.__has_val_) {
723*bdd1243dSDimitry Andric     if (!__rhs.__has_val_) {
724*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_));
725*bdd1243dSDimitry Andric     }
726*bdd1243dSDimitry Andric   }
727*bdd1243dSDimitry Andric 
728*bdd1243dSDimitry Andric   template <class _OtherErr>
729*bdd1243dSDimitry Andric     requires is_constructible_v<_Err, const _OtherErr&>
730*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
731*bdd1243dSDimitry Andric   expected(const unexpected<_OtherErr>& __unex)
732*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
733*bdd1243dSDimitry Andric       : __has_val_(false) {
734*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__unex_), __unex.error());
735*bdd1243dSDimitry Andric   }
736*bdd1243dSDimitry Andric 
737*bdd1243dSDimitry Andric   template <class _OtherErr>
738*bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _OtherErr>
739*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
740*bdd1243dSDimitry Andric   expected(unexpected<_OtherErr>&& __unex)
741*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
742*bdd1243dSDimitry Andric       : __has_val_(false) {
743*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error()));
744*bdd1243dSDimitry Andric   }
745*bdd1243dSDimitry Andric 
746*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {}
747*bdd1243dSDimitry Andric 
748*bdd1243dSDimitry Andric   template <class... _Args>
749*bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _Args...>
750*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args)
751*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened
752*bdd1243dSDimitry Andric       : __has_val_(false) {
753*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...);
754*bdd1243dSDimitry Andric   }
755*bdd1243dSDimitry Andric 
756*bdd1243dSDimitry Andric   template <class _Up, class... _Args>
757*bdd1243dSDimitry Andric     requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
758*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
759*bdd1243dSDimitry Andric     noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
760*bdd1243dSDimitry Andric       : __has_val_(false) {
761*bdd1243dSDimitry Andric     std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...);
762*bdd1243dSDimitry Andric   }
763*bdd1243dSDimitry Andric 
764*bdd1243dSDimitry Andric   // [expected.void.dtor], destructor
765*bdd1243dSDimitry Andric 
766*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
767*bdd1243dSDimitry Andric     requires is_trivially_destructible_v<_Err>
768*bdd1243dSDimitry Andric   = default;
769*bdd1243dSDimitry Andric 
770*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected()
771*bdd1243dSDimitry Andric     requires(!is_trivially_destructible_v<_Err>)
772*bdd1243dSDimitry Andric   {
773*bdd1243dSDimitry Andric     if (!__has_val_) {
774*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__unex_));
775*bdd1243dSDimitry Andric     }
776*bdd1243dSDimitry Andric   }
777*bdd1243dSDimitry Andric 
778*bdd1243dSDimitry Andric   // [expected.void.assign], assignment
779*bdd1243dSDimitry Andric 
780*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
781*bdd1243dSDimitry Andric 
782*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs)
783*bdd1243dSDimitry Andric     noexcept(is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened
784*bdd1243dSDimitry Andric     requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>)
785*bdd1243dSDimitry Andric   {
786*bdd1243dSDimitry Andric     if (__has_val_) {
787*bdd1243dSDimitry Andric       if (!__rhs.__has_val_) {
788*bdd1243dSDimitry Andric         std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_);
789*bdd1243dSDimitry Andric         __has_val_ = false;
790*bdd1243dSDimitry Andric       }
791*bdd1243dSDimitry Andric     } else {
792*bdd1243dSDimitry Andric       if (__rhs.__has_val_) {
793*bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__union_.__unex_));
794*bdd1243dSDimitry Andric         __has_val_ = true;
795*bdd1243dSDimitry Andric       } else {
796*bdd1243dSDimitry Andric         __union_.__unex_ = __rhs.__union_.__unex_;
797*bdd1243dSDimitry Andric       }
798*bdd1243dSDimitry Andric     }
799*bdd1243dSDimitry Andric     return *this;
800*bdd1243dSDimitry Andric   }
801*bdd1243dSDimitry Andric 
802*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&&) = delete;
803*bdd1243dSDimitry Andric 
804*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs)
805*bdd1243dSDimitry Andric     noexcept(is_nothrow_move_assignable_v<_Err> &&
806*bdd1243dSDimitry Andric              is_nothrow_move_constructible_v<_Err>)
807*bdd1243dSDimitry Andric     requires(is_move_assignable_v<_Err> &&
808*bdd1243dSDimitry Andric              is_move_constructible_v<_Err>)
809*bdd1243dSDimitry Andric   {
810*bdd1243dSDimitry Andric     if (__has_val_) {
811*bdd1243dSDimitry Andric       if (!__rhs.__has_val_) {
812*bdd1243dSDimitry Andric         std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_));
813*bdd1243dSDimitry Andric         __has_val_ = false;
814*bdd1243dSDimitry Andric       }
815*bdd1243dSDimitry Andric     } else {
816*bdd1243dSDimitry Andric       if (__rhs.__has_val_) {
817*bdd1243dSDimitry Andric         std::destroy_at(std::addressof(__union_.__unex_));
818*bdd1243dSDimitry Andric         __has_val_ = true;
819*bdd1243dSDimitry Andric       } else {
820*bdd1243dSDimitry Andric         __union_.__unex_ = std::move(__rhs.__union_.__unex_);
821*bdd1243dSDimitry Andric       }
822*bdd1243dSDimitry Andric     }
823*bdd1243dSDimitry Andric     return *this;
824*bdd1243dSDimitry Andric   }
825*bdd1243dSDimitry Andric 
826*bdd1243dSDimitry Andric   template <class _OtherErr>
827*bdd1243dSDimitry Andric     requires(is_constructible_v<_Err, const _OtherErr&> && is_assignable_v<_Err&, const _OtherErr&>)
828*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
829*bdd1243dSDimitry Andric     if (__has_val_) {
830*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), __un.error());
831*bdd1243dSDimitry Andric       __has_val_ = false;
832*bdd1243dSDimitry Andric     } else {
833*bdd1243dSDimitry Andric       __union_.__unex_ = __un.error();
834*bdd1243dSDimitry Andric     }
835*bdd1243dSDimitry Andric     return *this;
836*bdd1243dSDimitry Andric   }
837*bdd1243dSDimitry Andric 
838*bdd1243dSDimitry Andric   template <class _OtherErr>
839*bdd1243dSDimitry Andric     requires(is_constructible_v<_Err, _OtherErr> && is_assignable_v<_Err&, _OtherErr>)
840*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
841*bdd1243dSDimitry Andric     if (__has_val_) {
842*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__union_.__unex_), std::move(__un.error()));
843*bdd1243dSDimitry Andric       __has_val_ = false;
844*bdd1243dSDimitry Andric     } else {
845*bdd1243dSDimitry Andric       __union_.__unex_ = std::move(__un.error());
846*bdd1243dSDimitry Andric     }
847*bdd1243dSDimitry Andric     return *this;
848*bdd1243dSDimitry Andric   }
849*bdd1243dSDimitry Andric 
850*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept {
851*bdd1243dSDimitry Andric     if (!__has_val_) {
852*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__union_.__unex_));
853*bdd1243dSDimitry Andric       __has_val_ = true;
854*bdd1243dSDimitry Andric     }
855*bdd1243dSDimitry Andric   }
856*bdd1243dSDimitry Andric 
857*bdd1243dSDimitry Andric   // [expected.void.swap], swap
858*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs)
859*bdd1243dSDimitry Andric     noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
860*bdd1243dSDimitry Andric     requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>)
861*bdd1243dSDimitry Andric   {
862*bdd1243dSDimitry Andric     auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) {
863*bdd1243dSDimitry Andric       std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_));
864*bdd1243dSDimitry Andric       std::destroy_at(std::addressof(__with_err.__union_.__unex_));
865*bdd1243dSDimitry Andric       __with_val.__has_val_ = false;
866*bdd1243dSDimitry Andric       __with_err.__has_val_ = true;
867*bdd1243dSDimitry Andric     };
868*bdd1243dSDimitry Andric 
869*bdd1243dSDimitry Andric     if (__has_val_) {
870*bdd1243dSDimitry Andric       if (!__rhs.__has_val_) {
871*bdd1243dSDimitry Andric         __swap_val_unex_impl(*this, __rhs);
872*bdd1243dSDimitry Andric       }
873*bdd1243dSDimitry Andric     } else {
874*bdd1243dSDimitry Andric       if (__rhs.__has_val_) {
875*bdd1243dSDimitry Andric         __swap_val_unex_impl(__rhs, *this);
876*bdd1243dSDimitry Andric       } else {
877*bdd1243dSDimitry Andric         using std::swap;
878*bdd1243dSDimitry Andric         swap(__union_.__unex_, __rhs.__union_.__unex_);
879*bdd1243dSDimitry Andric       }
880*bdd1243dSDimitry Andric     }
881*bdd1243dSDimitry Andric   }
882*bdd1243dSDimitry Andric 
883*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y)
884*bdd1243dSDimitry Andric     noexcept(noexcept(__x.swap(__y)))
885*bdd1243dSDimitry Andric     requires requires { __x.swap(__y); }
886*bdd1243dSDimitry Andric   {
887*bdd1243dSDimitry Andric     __x.swap(__y);
888*bdd1243dSDimitry Andric   }
889*bdd1243dSDimitry Andric 
890*bdd1243dSDimitry Andric   // [expected.void.obs], observers
891*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; }
892*bdd1243dSDimitry Andric 
893*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; }
894*bdd1243dSDimitry Andric 
895*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept {
896*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value");
897*bdd1243dSDimitry Andric   }
898*bdd1243dSDimitry Andric 
899*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void value() const& {
900*bdd1243dSDimitry Andric     if (!__has_val_) {
901*bdd1243dSDimitry Andric       __expected::__throw_bad_expected_access<_Err>(__union_.__unex_);
902*bdd1243dSDimitry Andric     }
903*bdd1243dSDimitry Andric   }
904*bdd1243dSDimitry Andric 
905*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void value() && {
906*bdd1243dSDimitry Andric     if (!__has_val_) {
907*bdd1243dSDimitry Andric       __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_));
908*bdd1243dSDimitry Andric     }
909*bdd1243dSDimitry Andric   }
910*bdd1243dSDimitry Andric 
911*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
912*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
913*bdd1243dSDimitry Andric     return __union_.__unex_;
914*bdd1243dSDimitry Andric   }
915*bdd1243dSDimitry Andric 
916*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
917*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
918*bdd1243dSDimitry Andric     return __union_.__unex_;
919*bdd1243dSDimitry Andric   }
920*bdd1243dSDimitry Andric 
921*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
922*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
923*bdd1243dSDimitry Andric     return std::move(__union_.__unex_);
924*bdd1243dSDimitry Andric   }
925*bdd1243dSDimitry Andric 
926*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
927*bdd1243dSDimitry Andric     _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error");
928*bdd1243dSDimitry Andric     return std::move(__union_.__unex_);
929*bdd1243dSDimitry Andric   }
930*bdd1243dSDimitry Andric 
931*bdd1243dSDimitry Andric   // [expected.void.eq], equality operators
932*bdd1243dSDimitry Andric   template <class _T2, class _E2>
933*bdd1243dSDimitry Andric     requires is_void_v<_T2>
934*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
935*bdd1243dSDimitry Andric     if (__x.__has_val_ != __y.__has_val_) {
936*bdd1243dSDimitry Andric       return false;
937*bdd1243dSDimitry Andric     } else {
938*bdd1243dSDimitry Andric       return __x.__has_val_ || static_cast<bool>(__x.__union_.__unex_ == __y.__union_.__unex_);
939*bdd1243dSDimitry Andric     }
940*bdd1243dSDimitry Andric   }
941*bdd1243dSDimitry Andric 
942*bdd1243dSDimitry Andric   template <class _E2>
943*bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) {
944*bdd1243dSDimitry Andric     return !__x.__has_val_ && static_cast<bool>(__x.__union_.__unex_ == __y.error());
945*bdd1243dSDimitry Andric   }
946*bdd1243dSDimitry Andric 
947*bdd1243dSDimitry Andric private:
948*bdd1243dSDimitry Andric   struct __empty_t {};
949*bdd1243dSDimitry Andric   // use named union because [[no_unique_address]] cannot be applied to an unnamed union
950*bdd1243dSDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS union __union_t {
951*bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {}
952*bdd1243dSDimitry Andric 
953*bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
954*bdd1243dSDimitry Andric       requires(is_trivially_destructible_v<_Err>)
955*bdd1243dSDimitry Andric     = default;
956*bdd1243dSDimitry Andric 
957*bdd1243dSDimitry Andric     // the expected's destructor handles this
958*bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
959*bdd1243dSDimitry Andric       requires(!is_trivially_destructible_v<_Err>)
960*bdd1243dSDimitry Andric     {}
961*bdd1243dSDimitry Andric 
962*bdd1243dSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
963*bdd1243dSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
964*bdd1243dSDimitry Andric   } __union_;
965*bdd1243dSDimitry Andric 
966*bdd1243dSDimitry Andric   bool __has_val_;
967*bdd1243dSDimitry Andric };
968*bdd1243dSDimitry Andric 
969*bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
970*bdd1243dSDimitry Andric 
971*bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER >= 23
972*bdd1243dSDimitry Andric 
973*bdd1243dSDimitry Andric #endif // _LIBCPP___EXPECTED_EXPECTED_H
974