xref: /freebsd-src/contrib/llvm-project/libcxx/include/__expected/expected.h (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
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 
91*7a6dacacSDimitry Andric // If parameter type `_Tp` of `__conditional_no_unique_address` is neither
92*7a6dacacSDimitry Andric // copyable nor movable, a constructor with this tag is provided. For that
93*7a6dacacSDimitry Andric // constructor, the user has to provide a function and arguments. The function
94*7a6dacacSDimitry Andric // must return an object of type `_Tp`. When the function is invoked by the
95*7a6dacacSDimitry Andric // constructor, guaranteed copy elision kicks in and the `_Tp` is constructed
96*7a6dacacSDimitry Andric // in place.
97*7a6dacacSDimitry Andric struct __conditional_no_unique_address_invoke_tag {};
98*7a6dacacSDimitry Andric 
99*7a6dacacSDimitry Andric // This class implements an object with `[[no_unique_address]]` conditionally applied to it,
100*7a6dacacSDimitry Andric // based on the value of `_NoUnique`.
101*7a6dacacSDimitry Andric //
102*7a6dacacSDimitry Andric // A member of this class must always have `[[no_unique_address]]` applied to
103*7a6dacacSDimitry Andric // it. Otherwise, the `[[no_unique_address]]` in the "`_NoUnique == true`" case
104*7a6dacacSDimitry Andric // would not have any effect. In the `false` case, the `__v` is not
105*7a6dacacSDimitry Andric // `[[no_unique_address]]`, so nullifies the effects of the "outer"
106*7a6dacacSDimitry Andric // `[[no_unique_address]]` regarding data layout.
107*7a6dacacSDimitry Andric //
108*7a6dacacSDimitry Andric // If we had a language feature, this class would basically be replaced by `[[no_unique_address(condition)]]`.
109*7a6dacacSDimitry Andric template <bool _NoUnique, class _Tp>
110*7a6dacacSDimitry Andric struct __conditional_no_unique_address;
111*7a6dacacSDimitry Andric 
112*7a6dacacSDimitry Andric template <class _Tp>
113*7a6dacacSDimitry Andric struct __conditional_no_unique_address<true, _Tp> {
114*7a6dacacSDimitry Andric   template <class... _Args>
115*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(in_place_t, _Args&&... __args)
116*7a6dacacSDimitry Andric       : __v(std::forward<_Args>(__args)...) {}
117*7a6dacacSDimitry Andric 
118*7a6dacacSDimitry Andric   template <class _Func, class... _Args>
119*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(
120*7a6dacacSDimitry Andric       __conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args)
121*7a6dacacSDimitry Andric       : __v(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
122*7a6dacacSDimitry Andric 
123*7a6dacacSDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS _Tp __v;
124*7a6dacacSDimitry Andric };
125*7a6dacacSDimitry Andric 
126*7a6dacacSDimitry Andric template <class _Tp>
127*7a6dacacSDimitry Andric struct __conditional_no_unique_address<false, _Tp> {
128*7a6dacacSDimitry Andric   template <class... _Args>
129*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(in_place_t, _Args&&... __args)
130*7a6dacacSDimitry Andric       : __v(std::forward<_Args>(__args)...) {}
131*7a6dacacSDimitry Andric 
132*7a6dacacSDimitry Andric   template <class _Func, class... _Args>
133*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(
134*7a6dacacSDimitry Andric       __conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args)
135*7a6dacacSDimitry Andric       : __v(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
136*7a6dacacSDimitry Andric 
137*7a6dacacSDimitry Andric   _Tp __v;
138*7a6dacacSDimitry Andric };
139*7a6dacacSDimitry Andric 
140*7a6dacacSDimitry Andric // This function returns whether the type `_Second` can be stuffed into the tail padding
141*7a6dacacSDimitry Andric // of the `_First` type if both of them are given `[[no_unique_address]]`.
142*7a6dacacSDimitry Andric template <class _First, class _Second>
143*7a6dacacSDimitry Andric inline constexpr bool __fits_in_tail_padding = []() {
144*7a6dacacSDimitry Andric   struct __x {
145*7a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _First __first;
146*7a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _Second __second;
147*7a6dacacSDimitry Andric   };
148*7a6dacacSDimitry Andric   return sizeof(__x) == sizeof(_First);
149*7a6dacacSDimitry Andric }();
150*7a6dacacSDimitry Andric 
151*7a6dacacSDimitry Andric // This class implements the storage used by `std::expected`. We have a few
152*7a6dacacSDimitry Andric // goals for this storage:
153*7a6dacacSDimitry Andric // 1. Whenever the underlying {_Tp | _Unex} combination has free bytes in its
154*7a6dacacSDimitry Andric //    tail padding, we should reuse it to store the bool discriminator of the
155*7a6dacacSDimitry Andric //    expected, so as to save space.
156*7a6dacacSDimitry Andric // 2. Whenever the `expected<_Tp, _Unex>` as a whole has free bytes in its tail
157*7a6dacacSDimitry Andric //    padding, we should allow an object following the expected to be stored in
158*7a6dacacSDimitry Andric //    its tail padding.
159*7a6dacacSDimitry Andric // 3. However, we never want a user object (say `X`) that would follow an
160*7a6dacacSDimitry Andric //    `expected<_Tp, _Unex>` to be stored in the padding bytes of the
161*7a6dacacSDimitry Andric //    underlying {_Tp | _Unex} union, if any. That is because we use
162*7a6dacacSDimitry Andric //    `construct_at` on that union, which would end up overwriting the `X`
163*7a6dacacSDimitry Andric //    member if it is stored in the tail padding of the union.
164*7a6dacacSDimitry Andric //
165*7a6dacacSDimitry Andric // To achieve this, `__expected_base`'s logic is implemented in an inner
166*7a6dacacSDimitry Andric // `__repr` class. `__expected_base` holds one `__repr` member which is
167*7a6dacacSDimitry Andric // conditionally `[[no_unique_address]]`. The `__repr` class holds the
168*7a6dacacSDimitry Andric // underlying {_Tp | _Unex} union and a boolean "has value" flag.
169*7a6dacacSDimitry Andric //
170*7a6dacacSDimitry Andric // Which one of the `__repr_`/`__union_` members is `[[no_unique_address]]`
171*7a6dacacSDimitry Andric // depends on whether the "has value" boolean fits into the tail padding of
172*7a6dacacSDimitry Andric // the underlying {_Tp | _Unex} union:
173*7a6dacacSDimitry Andric //
174*7a6dacacSDimitry Andric // - In case the "has value" bool fits into the tail padding of the union, the
175*7a6dacacSDimitry Andric //   whole `__repr_` member is _not_ `[[no_unique_address]]` as it needs to be
176*7a6dacacSDimitry Andric //   transparently replaced on `emplace()`/`swap()` etc.
177*7a6dacacSDimitry Andric // - In case the "has value" bool does not fit into the tail padding of the
178*7a6dacacSDimitry Andric //   union, only the union member must be transparently replaced (therefore is
179*7a6dacacSDimitry Andric //   _not_ `[[no_unique_address]]`) and the "has value" flag must be adjusted
180*7a6dacacSDimitry Andric //   manually.
181*7a6dacacSDimitry Andric //
182*7a6dacacSDimitry Andric // This way, the member that is transparently replaced on mutating operations
183*7a6dacacSDimitry Andric // is never `[[no_unique_address]]`, satisfying the requirements from
184*7a6dacacSDimitry Andric // "[basic.life]" in the standard.
185*7a6dacacSDimitry Andric //
186*7a6dacacSDimitry Andric // Stripped away of all superfluous elements, the layout of `__expected_base`
187*7a6dacacSDimitry Andric // then looks like this:
188*7a6dacacSDimitry Andric //
189*7a6dacacSDimitry Andric //     template <class Tp, class Err>
190*7a6dacacSDimitry Andric //     class expected_base {
191*7a6dacacSDimitry Andric //       union union_t {
192*7a6dacacSDimitry Andric //         [[no_unique_address]] Tp val;
193*7a6dacacSDimitry Andric //         [[no_unique_address]] Err unex;
194*7a6dacacSDimitry Andric //       };
195*7a6dacacSDimitry Andric //
196*7a6dacacSDimitry Andric //       static constexpr bool put_flag_in_tail                    = fits_in_tail_padding<union_t, bool>;
197*7a6dacacSDimitry Andric //       static constexpr bool allow_reusing_expected_tail_padding = !put_flag_in_tail;
198*7a6dacacSDimitry Andric //
199*7a6dacacSDimitry Andric //       struct repr {
200*7a6dacacSDimitry Andric //       private:
201*7a6dacacSDimitry Andric //         // If "has value" fits into the tail, this should be
202*7a6dacacSDimitry Andric //         // `[[no_unique_address]]`, otherwise not.
203*7a6dacacSDimitry Andric //         [[no_unique_address]] conditional_no_unique_address<
204*7a6dacacSDimitry Andric //             put_flag_in_tail,
205*7a6dacacSDimitry Andric //             union_t>::type union_;
206*7a6dacacSDimitry Andric //         [[no_unique_address]] bool has_val_;
207*7a6dacacSDimitry Andric //       };
208*7a6dacacSDimitry Andric //
209*7a6dacacSDimitry Andric //     protected:
210*7a6dacacSDimitry Andric //       // If "has value" fits into the tail, this must _not_ be
211*7a6dacacSDimitry Andric //       // `[[no_unique_address]]` so that we fill out the
212*7a6dacacSDimitry Andric //       // complete `expected` object.
213*7a6dacacSDimitry Andric //       [[no_unique_address]] conditional_no_unique_address<
214*7a6dacacSDimitry Andric //           allow_reusing_expected_tail_padding,
215*7a6dacacSDimitry Andric //           repr>::type repr_;
216*7a6dacacSDimitry Andric //     };
217*7a6dacacSDimitry Andric //
218bdd1243dSDimitry Andric template <class _Tp, class _Err>
219*7a6dacacSDimitry Andric class __expected_base {
220*7a6dacacSDimitry Andric   // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
221*7a6dacacSDimitry Andric   // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
222*7a6dacacSDimitry Andric   // it's not clear that it's implementable, given that the function is allowed to clobber
223*7a6dacacSDimitry Andric   // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
224*7a6dacacSDimitry Andric   union __union_t {
225*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = delete;
226*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&)
227*7a6dacacSDimitry Andric       requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
228*7a6dacacSDimitry Andric                is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>)
229*7a6dacacSDimitry Andric     = default;
230*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) = delete;
231*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&)
232*7a6dacacSDimitry Andric       requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
233*7a6dacacSDimitry Andric                is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)
234*7a6dacacSDimitry Andric     = default;
235*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(const __union_t&) = delete;
236*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(__union_t&&)      = delete;
237*7a6dacacSDimitry Andric 
238*7a6dacacSDimitry Andric     template <class... _Args>
239*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(in_place_t, _Args&&... __args)
240*7a6dacacSDimitry Andric         : __val_(std::forward<_Args>(__args)...) {}
241*7a6dacacSDimitry Andric 
242*7a6dacacSDimitry Andric     template <class... _Args>
243*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(unexpect_t, _Args&&... __args)
244*7a6dacacSDimitry Andric         : __unex_(std::forward<_Args>(__args)...) {}
245*7a6dacacSDimitry Andric 
246*7a6dacacSDimitry Andric     template <class _Func, class... _Args>
247*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
248*7a6dacacSDimitry Andric         std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args)
249*7a6dacacSDimitry Andric         : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
250*7a6dacacSDimitry Andric 
251*7a6dacacSDimitry Andric     template <class _Func, class... _Args>
252*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
253*7a6dacacSDimitry Andric         std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
254*7a6dacacSDimitry Andric         : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
255*7a6dacacSDimitry Andric 
256*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
257*7a6dacacSDimitry Andric       requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
258*7a6dacacSDimitry Andric     = default;
259*7a6dacacSDimitry Andric 
260*7a6dacacSDimitry Andric     // __repr's destructor handles this
261*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {}
262*7a6dacacSDimitry Andric 
263*7a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
264*7a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
265*7a6dacacSDimitry Andric   };
266*7a6dacacSDimitry Andric 
267*7a6dacacSDimitry Andric   static constexpr bool __put_flag_in_tail                    = __fits_in_tail_padding<__union_t, bool>;
268*7a6dacacSDimitry Andric   static constexpr bool __allow_reusing_expected_tail_padding = !__put_flag_in_tail;
269*7a6dacacSDimitry Andric 
270*7a6dacacSDimitry Andric   struct __repr {
271*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr() = delete;
272*7a6dacacSDimitry Andric 
273*7a6dacacSDimitry Andric     template <class... _Args>
274*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(in_place_t __tag, _Args&&... __args)
275*7a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(true) {}
276*7a6dacacSDimitry Andric 
277*7a6dacacSDimitry Andric     template <class... _Args>
278*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(unexpect_t __tag, _Args&&... __args)
279*7a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {}
280*7a6dacacSDimitry Andric 
281*7a6dacacSDimitry Andric     template <class... _Args>
282*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_in_place_from_invoke_tag __tag,
283*7a6dacacSDimitry Andric                                                     _Args&&... __args)
284*7a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(true) {}
285*7a6dacacSDimitry Andric 
286*7a6dacacSDimitry Andric     template <class... _Args>
287*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_unexpected_from_invoke_tag __tag,
288*7a6dacacSDimitry Andric                                                     _Args&&... __args)
289*7a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {}
290*7a6dacacSDimitry Andric 
291*7a6dacacSDimitry Andric     // The return value of `__make_union` must be constructed in place in the
292*7a6dacacSDimitry Andric     // `__v` member of `__union_`, relying on guaranteed copy elision. To do
293*7a6dacacSDimitry Andric     // this, the `__conditional_no_unique_address_invoke_tag` constructor is
294*7a6dacacSDimitry Andric     // called with a lambda that is immediately called inside
295*7a6dacacSDimitry Andric     // `__conditional_no_unique_address`'s constructor.
296*7a6dacacSDimitry Andric     template <class _OtherUnion>
297*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(bool __has_val, _OtherUnion&& __other)
298*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
299*7a6dacacSDimitry Andric         : __union_(__conditional_no_unique_address_invoke_tag{},
300*7a6dacacSDimitry Andric                    [&] { return __make_union(__has_val, std::forward<_OtherUnion>(__other)); }),
301*7a6dacacSDimitry Andric           __has_val_(__has_val) {}
302*7a6dacacSDimitry Andric 
303*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) = delete;
304*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&)
305*7a6dacacSDimitry Andric       requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
306*7a6dacacSDimitry Andric                is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>)
307*7a6dacacSDimitry Andric     = default;
308*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) = delete;
309*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&)
310*7a6dacacSDimitry Andric       requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
311*7a6dacacSDimitry Andric                is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)
312*7a6dacacSDimitry Andric     = default;
313*7a6dacacSDimitry Andric 
314*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(const __repr&) = delete;
315*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(__repr&&)      = delete;
316*7a6dacacSDimitry Andric 
317*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__repr()
318*7a6dacacSDimitry Andric       requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
319*7a6dacacSDimitry Andric     = default;
320*7a6dacacSDimitry Andric 
321*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__repr()
322*7a6dacacSDimitry Andric       requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
323*7a6dacacSDimitry Andric     {
324*7a6dacacSDimitry Andric       __destroy_union_member();
325*7a6dacacSDimitry Andric     }
326*7a6dacacSDimitry Andric 
327*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union()
328*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding &&
329*7a6dacacSDimitry Andric                (is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>))
330*7a6dacacSDimitry Andric     {
331*7a6dacacSDimitry Andric       // Note: Since the destructor of the union is trivial, this does nothing
332*7a6dacacSDimitry Andric       // except to end the lifetime of the union.
333*7a6dacacSDimitry Andric       std::destroy_at(&__union_.__v);
334*7a6dacacSDimitry Andric     }
335*7a6dacacSDimitry Andric 
336*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union()
337*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding &&
338*7a6dacacSDimitry Andric                (!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>))
339*7a6dacacSDimitry Andric     {
340*7a6dacacSDimitry Andric       __destroy_union_member();
341*7a6dacacSDimitry Andric       std::destroy_at(&__union_.__v);
342*7a6dacacSDimitry Andric     }
343*7a6dacacSDimitry Andric 
344*7a6dacacSDimitry Andric     template <class... _Args>
345*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(in_place_t, _Args&&... __args)
346*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
347*7a6dacacSDimitry Andric     {
348*7a6dacacSDimitry Andric       std::construct_at(&__union_.__v, in_place, std::forward<_Args>(__args)...);
349*7a6dacacSDimitry Andric       __has_val_ = true;
350*7a6dacacSDimitry Andric     }
351*7a6dacacSDimitry Andric 
352*7a6dacacSDimitry Andric     template <class... _Args>
353*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(unexpect_t, _Args&&... __args)
354*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
355*7a6dacacSDimitry Andric     {
356*7a6dacacSDimitry Andric       std::construct_at(&__union_.__v, unexpect, std::forward<_Args>(__args)...);
357*7a6dacacSDimitry Andric       __has_val_ = false;
358*7a6dacacSDimitry Andric     }
359*7a6dacacSDimitry Andric 
360*7a6dacacSDimitry Andric   private:
361*7a6dacacSDimitry Andric     template <class, class>
362*7a6dacacSDimitry Andric     friend class __expected_base;
363*7a6dacacSDimitry Andric 
364*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union_member()
365*7a6dacacSDimitry Andric       requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
366*7a6dacacSDimitry Andric     {
367*7a6dacacSDimitry Andric       if (__has_val_) {
368*7a6dacacSDimitry Andric         std::destroy_at(std::addressof(__union_.__v.__val_));
369*7a6dacacSDimitry Andric       } else {
370*7a6dacacSDimitry Andric         std::destroy_at(std::addressof(__union_.__v.__unex_));
371*7a6dacacSDimitry Andric       }
372*7a6dacacSDimitry Andric     }
373*7a6dacacSDimitry Andric 
374*7a6dacacSDimitry Andric     template <class _OtherUnion>
375*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI static constexpr __union_t __make_union(bool __has_val, _OtherUnion&& __other)
376*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
377*7a6dacacSDimitry Andric     {
378*7a6dacacSDimitry Andric       if (__has_val)
379*7a6dacacSDimitry Andric         return __union_t(in_place, std::forward<_OtherUnion>(__other).__val_);
380*7a6dacacSDimitry Andric       else
381*7a6dacacSDimitry Andric         return __union_t(unexpect, std::forward<_OtherUnion>(__other).__unex_);
382*7a6dacacSDimitry Andric     }
383*7a6dacacSDimitry Andric 
384*7a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__put_flag_in_tail, __union_t> __union_;
385*7a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS bool __has_val_;
386*7a6dacacSDimitry Andric   };
387*7a6dacacSDimitry Andric 
388*7a6dacacSDimitry Andric   template <class _OtherUnion>
389*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr __repr __make_repr(bool __has_val, _OtherUnion&& __other)
390*7a6dacacSDimitry Andric     requires(__put_flag_in_tail)
391*7a6dacacSDimitry Andric   {
392*7a6dacacSDimitry Andric     if (__has_val)
393*7a6dacacSDimitry Andric       return __repr(in_place, std::forward<_OtherUnion>(__other).__val_);
394*7a6dacacSDimitry Andric     else
395*7a6dacacSDimitry Andric       return __repr(unexpect, std::forward<_OtherUnion>(__other).__unex_);
396*7a6dacacSDimitry Andric   }
397*7a6dacacSDimitry Andric 
398*7a6dacacSDimitry Andric protected:
399*7a6dacacSDimitry Andric   template <class... _Args>
400*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_base(_Args&&... __args)
401*7a6dacacSDimitry Andric       : __repr_(in_place, std::forward<_Args>(__args)...) {}
402*7a6dacacSDimitry Andric 
403*7a6dacacSDimitry Andric   // In case we copy/move construct from another `expected` we need to create
404*7a6dacacSDimitry Andric   // our `expected` so that it either has a value or not, depending on the "has
405*7a6dacacSDimitry Andric   // value" flag of the other `expected`. To do this without falling back on
406*7a6dacacSDimitry Andric   // `std::construct_at` we rely on guaranteed copy elision using two helper
407*7a6dacacSDimitry Andric   // functions `__make_repr` and `__make_union`. There have to be two since
408*7a6dacacSDimitry Andric   // there are two data layouts with different members being
409*7a6dacacSDimitry Andric   // `[[no_unique_address]]`. GCC (as of version 13) does not do guaranteed
410*7a6dacacSDimitry Andric   // copy elision when initializing `[[no_unique_address]]` members. The two
411*7a6dacacSDimitry Andric   // cases are:
412*7a6dacacSDimitry Andric   //
413*7a6dacacSDimitry Andric   // - `__make_repr`: This is used when the "has value" flag lives in the tail
414*7a6dacacSDimitry Andric   //   of the union. In this case, the `__repr` member is _not_
415*7a6dacacSDimitry Andric   //   `[[no_unique_address]]`.
416*7a6dacacSDimitry Andric   // - `__make_union`: When the "has value" flag does _not_ fit in the tail of
417*7a6dacacSDimitry Andric   //   the union, the `__repr` member is `[[no_unique_address]]` and the union
418*7a6dacacSDimitry Andric   //   is not.
419*7a6dacacSDimitry Andric   //
420*7a6dacacSDimitry Andric   // This constructor "catches" the first case and leaves the second case to
421*7a6dacacSDimitry Andric   // `__union_t`, its constructors and `__make_union`.
422*7a6dacacSDimitry Andric   template <class _OtherUnion>
423*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_base(bool __has_val, _OtherUnion&& __other)
424*7a6dacacSDimitry Andric     requires(__put_flag_in_tail)
425*7a6dacacSDimitry Andric       : __repr_(__conditional_no_unique_address_invoke_tag{},
426*7a6dacacSDimitry Andric                 [&] { return __make_repr(__has_val, std::forward<_OtherUnion>(__other)); }) {}
427*7a6dacacSDimitry Andric 
428*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __destroy() {
429*7a6dacacSDimitry Andric     if constexpr (__put_flag_in_tail)
430*7a6dacacSDimitry Andric       std::destroy_at(&__repr_.__v);
431*7a6dacacSDimitry Andric     else
432*7a6dacacSDimitry Andric       __repr_.__v.__destroy_union();
433*7a6dacacSDimitry Andric   }
434*7a6dacacSDimitry Andric 
435*7a6dacacSDimitry Andric   template <class _Tag, class... _Args>
436*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __construct(_Tag __tag, _Args&&... __args) {
437*7a6dacacSDimitry Andric     if constexpr (__put_flag_in_tail)
438*7a6dacacSDimitry Andric       std::construct_at(&__repr_.__v, __tag, std::forward<_Args>(__args)...);
439*7a6dacacSDimitry Andric     else
440*7a6dacacSDimitry Andric       __repr_.__v.__construct_union(__tag, std::forward<_Args>(__args)...);
441*7a6dacacSDimitry Andric   }
442*7a6dacacSDimitry Andric 
443*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool __has_val() const { return __repr_.__v.__has_val_; }
444*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr __union_t& __union() { return __repr_.__v.__union_.__v; }
445*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const __union_t& __union() const { return __repr_.__v.__union_.__v; }
446*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& __val() { return __repr_.__v.__union_.__v.__val_; }
447*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& __val() const { return __repr_.__v.__union_.__v.__val_; }
448*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& __unex() { return __repr_.__v.__union_.__v.__unex_; }
449*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& __unex() const { return __repr_.__v.__union_.__v.__unex_; }
450*7a6dacacSDimitry Andric 
451*7a6dacacSDimitry Andric private:
452*7a6dacacSDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__allow_reusing_expected_tail_padding, __repr> __repr_;
453*7a6dacacSDimitry Andric };
454*7a6dacacSDimitry Andric 
455*7a6dacacSDimitry Andric template <class _Tp, class _Err>
456*7a6dacacSDimitry Andric class expected : private __expected_base<_Tp, _Err> {
457cb14a3feSDimitry Andric   static_assert(!is_reference_v<_Tp> && !is_function_v<_Tp> && !is_same_v<remove_cv_t<_Tp>, in_place_t> &&
458cb14a3feSDimitry Andric                     !is_same_v<remove_cv_t<_Tp>, unexpect_t> && !__is_std_unexpected<remove_cv_t<_Tp>>::value &&
459cb14a3feSDimitry Andric                     __valid_std_unexpected<_Err>::value,
460bdd1243dSDimitry Andric                 "[expected.object.general] A program that instantiates the definition of template expected<T, E> for a "
461bdd1243dSDimitry Andric                 "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a "
462bdd1243dSDimitry Andric                 "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the "
463bdd1243dSDimitry Andric                 "definition of the template expected<T, E> with a type for the E parameter that is not a valid "
464bdd1243dSDimitry Andric                 "template argument for unexpected is ill-formed.");
465bdd1243dSDimitry Andric 
466bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
467bdd1243dSDimitry Andric   friend class expected;
468bdd1243dSDimitry Andric 
469*7a6dacacSDimitry Andric   using __base = __expected_base<_Tp, _Err>;
470*7a6dacacSDimitry Andric 
471bdd1243dSDimitry Andric public:
472bdd1243dSDimitry Andric   using value_type      = _Tp;
473bdd1243dSDimitry Andric   using error_type      = _Err;
474bdd1243dSDimitry Andric   using unexpected_type = unexpected<_Err>;
475bdd1243dSDimitry Andric 
476bdd1243dSDimitry Andric   template <class _Up>
477bdd1243dSDimitry Andric   using rebind = expected<_Up, error_type>;
478bdd1243dSDimitry Andric 
479bdd1243dSDimitry Andric   // [expected.object.ctor], constructors
480cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened
481bdd1243dSDimitry Andric     requires is_default_constructible_v<_Tp>
482*7a6dacacSDimitry Andric       : __base(in_place) {}
483bdd1243dSDimitry Andric 
484bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
485bdd1243dSDimitry Andric 
486bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
487cb14a3feSDimitry Andric     requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Tp> &&
488bdd1243dSDimitry Andric              is_trivially_copy_constructible_v<_Err>)
489bdd1243dSDimitry Andric   = default;
490bdd1243dSDimitry Andric 
491cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other) noexcept(
492cb14a3feSDimitry Andric       is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened
493bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
494bdd1243dSDimitry Andric              !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>))
495*7a6dacacSDimitry Andric       : __base(__other.__has_val(), __other.__union()) {}
496bdd1243dSDimitry Andric 
497bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
498cb14a3feSDimitry Andric     requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Tp> &&
499cb14a3feSDimitry Andric              is_trivially_move_constructible_v<_Err>)
500bdd1243dSDimitry Andric   = default;
501bdd1243dSDimitry Andric 
502cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other) noexcept(
503cb14a3feSDimitry Andric       is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>)
504bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
505bdd1243dSDimitry Andric              !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>))
506*7a6dacacSDimitry Andric       : __base(__other.__has_val(), std::move(__other.__union())) {}
507bdd1243dSDimitry Andric 
508bdd1243dSDimitry Andric private:
509bdd1243dSDimitry Andric   template <class _Up, class _OtherErr, class _UfQual, class _OtherErrQual>
510bdd1243dSDimitry Andric   using __can_convert =
511bdd1243dSDimitry Andric       _And< is_constructible<_Tp, _UfQual>,
512bdd1243dSDimitry Andric             is_constructible<_Err, _OtherErrQual>,
5135f757f3fSDimitry Andric             _If<_Not<is_same<remove_cv_t<_Tp>, bool>>::value,
5145f757f3fSDimitry Andric                 _And< _Not<is_constructible<_Tp, expected<_Up, _OtherErr>&>>,
515bdd1243dSDimitry Andric                       _Not<is_constructible<_Tp, expected<_Up, _OtherErr>>>,
516bdd1243dSDimitry Andric                       _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>&>>,
517bdd1243dSDimitry Andric                       _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>>>,
518bdd1243dSDimitry Andric                       _Not<is_convertible<expected<_Up, _OtherErr>&, _Tp>>,
519bdd1243dSDimitry Andric                       _Not<is_convertible<expected<_Up, _OtherErr>&&, _Tp>>,
520bdd1243dSDimitry Andric                       _Not<is_convertible<const expected<_Up, _OtherErr>&, _Tp>>,
5215f757f3fSDimitry Andric                       _Not<is_convertible<const expected<_Up, _OtherErr>&&, _Tp>>>,
5225f757f3fSDimitry Andric                 true_type>,
523bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
524bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
525bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
526bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >;
527bdd1243dSDimitry Andric 
52806c3fb27SDimitry Andric   template <class _Func, class... _Args>
52906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
53006c3fb27SDimitry Andric       std::__expected_construct_in_place_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
531*7a6dacacSDimitry Andric       : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {}
53206c3fb27SDimitry Andric 
53306c3fb27SDimitry Andric   template <class _Func, class... _Args>
53406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
53506c3fb27SDimitry Andric       std::__expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
536*7a6dacacSDimitry Andric       : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {}
537bdd1243dSDimitry Andric 
538bdd1243dSDimitry Andric public:
539bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
540bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value
541bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _Up&, _Tp> ||
542bdd1243dSDimitry Andric                                            !is_convertible_v<const _OtherErr&, _Err>)
543cb14a3feSDimitry Andric       expected(const expected<_Up, _OtherErr>& __other) noexcept(
544cb14a3feSDimitry Andric           is_nothrow_constructible_v<_Tp, const _Up&> &&
545bdd1243dSDimitry Andric           is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
546*7a6dacacSDimitry Andric       : __base(__other.__has_val(), __other.__union()) {}
547bdd1243dSDimitry Andric 
548bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
549bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value
550bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>)
551cb14a3feSDimitry Andric       expected(expected<_Up, _OtherErr>&& __other) noexcept(
552cb14a3feSDimitry Andric           is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
553*7a6dacacSDimitry Andric       : __base(__other.__has_val(), std::move(__other.__union())) {}
554bdd1243dSDimitry Andric 
555bdd1243dSDimitry Andric   template <class _Up = _Tp>
556bdd1243dSDimitry Andric     requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> &&
5575f757f3fSDimitry Andric              is_constructible_v<_Tp, _Up> && !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
5585f757f3fSDimitry Andric              (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_expected<remove_cvref_t<_Up>>::value))
559bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>)
560b121cb00SDimitry Andric       expected(_Up&& __u) noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened
561*7a6dacacSDimitry Andric       : __base(in_place, std::forward<_Up>(__u)) {}
562bdd1243dSDimitry Andric 
563bdd1243dSDimitry Andric   template <class _OtherErr>
564bdd1243dSDimitry Andric     requires is_constructible_v<_Err, const _OtherErr&>
565cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>) expected(
566cb14a3feSDimitry Andric       const unexpected<_OtherErr>& __unex) noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
567*7a6dacacSDimitry Andric       : __base(unexpect, __unex.error()) {}
568bdd1243dSDimitry Andric 
569bdd1243dSDimitry Andric   template <class _OtherErr>
570bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _OtherErr>
571bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
572cb14a3feSDimitry Andric       expected(unexpected<_OtherErr>&& __unex) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
573*7a6dacacSDimitry Andric       : __base(unexpect, std::move(__unex.error())) {}
574bdd1243dSDimitry Andric 
575bdd1243dSDimitry Andric   template <class... _Args>
576bdd1243dSDimitry Andric     requires is_constructible_v<_Tp, _Args...>
577cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args) noexcept(
578cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Tp, _Args...>) // strengthened
579*7a6dacacSDimitry Andric       : __base(in_place, std::forward<_Args>(__args)...) {}
580bdd1243dSDimitry Andric 
581bdd1243dSDimitry Andric   template <class _Up, class... _Args>
582bdd1243dSDimitry Andric     requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... >
583cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) noexcept(
584cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened
585*7a6dacacSDimitry Andric       : __base(in_place, __il, std::forward<_Args>(__args)...) {}
586bdd1243dSDimitry Andric 
587bdd1243dSDimitry Andric   template <class... _Args>
588bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _Args...>
589cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) noexcept(
590cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Err, _Args...>) // strengthened
591*7a6dacacSDimitry Andric       : __base(unexpect, std::forward<_Args>(__args)...) {}
592bdd1243dSDimitry Andric 
593bdd1243dSDimitry Andric   template <class _Up, class... _Args>
594bdd1243dSDimitry Andric     requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
595cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) noexcept(
596cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
597*7a6dacacSDimitry Andric       : __base(unexpect, __il, std::forward<_Args>(__args)...) {}
598bdd1243dSDimitry Andric 
599bdd1243dSDimitry Andric   // [expected.object.dtor], destructor
600bdd1243dSDimitry Andric 
601*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected() = default;
602bdd1243dSDimitry Andric 
603bdd1243dSDimitry Andric private:
604*7a6dacacSDimitry Andric   template <class _Tag, class _OtherTag, class _T1, class _T2, class... _Args>
605*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(_T2& __oldval, _Args&&... __args) {
606bdd1243dSDimitry Andric     if constexpr (is_nothrow_constructible_v<_T1, _Args...>) {
607*7a6dacacSDimitry Andric       this->__destroy();
608*7a6dacacSDimitry Andric       this->__construct(_Tag{}, std::forward<_Args>(__args)...);
609bdd1243dSDimitry Andric     } else if constexpr (is_nothrow_move_constructible_v<_T1>) {
610bdd1243dSDimitry Andric       _T1 __tmp(std::forward<_Args>(__args)...);
611*7a6dacacSDimitry Andric       this->__destroy();
612*7a6dacacSDimitry Andric       this->__construct(_Tag{}, std::move(__tmp));
613bdd1243dSDimitry Andric     } else {
614bdd1243dSDimitry Andric       static_assert(
615bdd1243dSDimitry Andric           is_nothrow_move_constructible_v<_T2>,
616bdd1243dSDimitry Andric           "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can "
617bdd1243dSDimitry Andric           "be reverted to the previous state in case an exception is thrown during the assignment.");
618bdd1243dSDimitry Andric       _T2 __tmp(std::move(__oldval));
619*7a6dacacSDimitry Andric       this->__destroy();
620*7a6dacacSDimitry Andric       auto __trans = std::__make_exception_guard([&] { this->__construct(_OtherTag{}, std::move(__tmp)); });
621*7a6dacacSDimitry Andric       this->__construct(_Tag{}, std::forward<_Args>(__args)...);
622bdd1243dSDimitry Andric       __trans.__complete();
623bdd1243dSDimitry Andric     }
624bdd1243dSDimitry Andric   }
625bdd1243dSDimitry Andric 
626bdd1243dSDimitry Andric public:
627bdd1243dSDimitry Andric   // [expected.object.assign], assignment
628bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
629bdd1243dSDimitry Andric 
630cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) noexcept(
631cb14a3feSDimitry Andric       is_nothrow_copy_assignable_v<_Tp> && is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_assignable_v<_Err> &&
632bdd1243dSDimitry Andric       is_nothrow_copy_constructible_v<_Err>) // strengthened
633cb14a3feSDimitry Andric     requires(is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp> && is_copy_assignable_v<_Err> &&
634bdd1243dSDimitry Andric              is_copy_constructible_v<_Err> &&
635cb14a3feSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>))
636bdd1243dSDimitry Andric   {
637*7a6dacacSDimitry Andric     if (this->__has_val() && __rhs.__has_val()) {
638*7a6dacacSDimitry Andric       this->__val() = __rhs.__val();
639*7a6dacacSDimitry Andric     } else if (this->__has_val()) {
640*7a6dacacSDimitry Andric       __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), __rhs.__unex());
641*7a6dacacSDimitry Andric     } else if (__rhs.__has_val()) {
642*7a6dacacSDimitry Andric       __reinit_expected<in_place_t, unexpect_t, _Tp, _Err>(this->__unex(), __rhs.__val());
643bdd1243dSDimitry Andric     } else {
644*7a6dacacSDimitry Andric       this->__unex() = __rhs.__unex();
645bdd1243dSDimitry Andric     }
646bdd1243dSDimitry Andric     return *this;
647bdd1243dSDimitry Andric   }
648bdd1243dSDimitry Andric 
649cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected&
650cb14a3feSDimitry Andric   operator=(expected&& __rhs) noexcept(is_nothrow_move_assignable_v<_Tp> && is_nothrow_move_constructible_v<_Tp> &&
651cb14a3feSDimitry Andric                                        is_nothrow_move_assignable_v<_Err> && is_nothrow_move_constructible_v<_Err>)
652cb14a3feSDimitry Andric     requires(is_move_constructible_v<_Tp> && is_move_assignable_v<_Tp> && is_move_constructible_v<_Err> &&
653bdd1243dSDimitry Andric              is_move_assignable_v<_Err> &&
654cb14a3feSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>))
655bdd1243dSDimitry Andric   {
656*7a6dacacSDimitry Andric     if (this->__has_val() && __rhs.__has_val()) {
657*7a6dacacSDimitry Andric       this->__val() = std::move(__rhs.__val());
658*7a6dacacSDimitry Andric     } else if (this->__has_val()) {
659*7a6dacacSDimitry Andric       __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), std::move(__rhs.__unex()));
660*7a6dacacSDimitry Andric     } else if (__rhs.__has_val()) {
661*7a6dacacSDimitry Andric       __reinit_expected<in_place_t, unexpect_t, _Tp, _Err>(this->__unex(), std::move(__rhs.__val()));
662bdd1243dSDimitry Andric     } else {
663*7a6dacacSDimitry Andric       this->__unex() = std::move(__rhs.__unex());
664bdd1243dSDimitry Andric     }
665bdd1243dSDimitry Andric     return *this;
666bdd1243dSDimitry Andric   }
667bdd1243dSDimitry Andric 
668bdd1243dSDimitry Andric   template <class _Up = _Tp>
669bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v)
670cb14a3feSDimitry Andric     requires(!is_same_v<expected, remove_cvref_t<_Up>> && !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
671cb14a3feSDimitry Andric              is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up> &&
672cb14a3feSDimitry Andric              (is_nothrow_constructible_v<_Tp, _Up> || is_nothrow_move_constructible_v<_Tp> ||
673bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Err>))
674bdd1243dSDimitry Andric   {
675*7a6dacacSDimitry Andric     if (this->__has_val()) {
676*7a6dacacSDimitry Andric       this->__val() = std::forward<_Up>(__v);
677bdd1243dSDimitry Andric     } else {
678*7a6dacacSDimitry Andric       __reinit_expected<in_place_t, unexpect_t, _Tp, _Err>(this->__unex(), std::forward<_Up>(__v));
679bdd1243dSDimitry Andric     }
680bdd1243dSDimitry Andric     return *this;
681bdd1243dSDimitry Andric   }
682bdd1243dSDimitry Andric 
683bdd1243dSDimitry Andric private:
684bdd1243dSDimitry Andric   template <class _OtherErrQual>
685bdd1243dSDimitry Andric   static constexpr bool __can_assign_from_unexpected =
686bdd1243dSDimitry Andric       _And< is_constructible<_Err, _OtherErrQual>,
687bdd1243dSDimitry Andric             is_assignable<_Err&, _OtherErrQual>,
688bdd1243dSDimitry Andric             _Lazy<_Or,
689bdd1243dSDimitry Andric                   is_nothrow_constructible<_Err, _OtherErrQual>,
690bdd1243dSDimitry Andric                   is_nothrow_move_constructible<_Tp>,
691bdd1243dSDimitry Andric                   is_nothrow_move_constructible<_Err>> >::value;
692bdd1243dSDimitry Andric 
693bdd1243dSDimitry Andric public:
694bdd1243dSDimitry Andric   template <class _OtherErr>
695bdd1243dSDimitry Andric     requires(__can_assign_from_unexpected<const _OtherErr&>)
696bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
697*7a6dacacSDimitry Andric     if (this->__has_val()) {
698*7a6dacacSDimitry Andric       __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), __un.error());
699bdd1243dSDimitry Andric     } else {
700*7a6dacacSDimitry Andric       this->__unex() = __un.error();
701bdd1243dSDimitry Andric     }
702bdd1243dSDimitry Andric     return *this;
703bdd1243dSDimitry Andric   }
704bdd1243dSDimitry Andric 
705bdd1243dSDimitry Andric   template <class _OtherErr>
706bdd1243dSDimitry Andric     requires(__can_assign_from_unexpected<_OtherErr>)
707bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
708*7a6dacacSDimitry Andric     if (this->__has_val()) {
709*7a6dacacSDimitry Andric       __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), std::move(__un.error()));
710bdd1243dSDimitry Andric     } else {
711*7a6dacacSDimitry Andric       this->__unex() = std::move(__un.error());
712bdd1243dSDimitry Andric     }
713bdd1243dSDimitry Andric     return *this;
714bdd1243dSDimitry Andric   }
715bdd1243dSDimitry Andric 
716bdd1243dSDimitry Andric   template <class... _Args>
717bdd1243dSDimitry Andric     requires is_nothrow_constructible_v<_Tp, _Args...>
718bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept {
719*7a6dacacSDimitry Andric     this->__destroy();
720*7a6dacacSDimitry Andric     this->__construct(in_place, std::forward<_Args>(__args)...);
721*7a6dacacSDimitry Andric     return this->__val();
722bdd1243dSDimitry Andric   }
723bdd1243dSDimitry Andric 
724bdd1243dSDimitry Andric   template <class _Up, class... _Args>
725bdd1243dSDimitry Andric     requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
726bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept {
727*7a6dacacSDimitry Andric     this->__destroy();
728*7a6dacacSDimitry Andric     this->__construct(in_place, __il, std::forward<_Args>(__args)...);
729*7a6dacacSDimitry Andric     return this->__val();
730bdd1243dSDimitry Andric   }
731bdd1243dSDimitry Andric 
732bdd1243dSDimitry Andric public:
733bdd1243dSDimitry Andric   // [expected.object.swap], swap
734cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void
735cb14a3feSDimitry Andric   swap(expected& __rhs) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp> &&
736cb14a3feSDimitry Andric                                  is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
737cb14a3feSDimitry Andric     requires(is_swappable_v<_Tp> && is_swappable_v<_Err> && is_move_constructible_v<_Tp> &&
738bdd1243dSDimitry Andric              is_move_constructible_v<_Err> &&
739cb14a3feSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>))
740bdd1243dSDimitry Andric   {
741*7a6dacacSDimitry Andric     auto __swap_val_unex_impl = [](expected& __with_val, expected& __with_err) {
742bdd1243dSDimitry Andric       if constexpr (is_nothrow_move_constructible_v<_Err>) {
743*7a6dacacSDimitry Andric         _Err __tmp(std::move(__with_err.__unex()));
744*7a6dacacSDimitry Andric         __with_err.__destroy();
745*7a6dacacSDimitry Andric         auto __trans = std::__make_exception_guard([&] { __with_err.__construct(unexpect, std::move(__tmp)); });
746*7a6dacacSDimitry Andric         __with_err.__construct(in_place, std::move(__with_val.__val()));
747bdd1243dSDimitry Andric         __trans.__complete();
748*7a6dacacSDimitry Andric         __with_val.__destroy();
749*7a6dacacSDimitry Andric         __with_val.__construct(unexpect, std::move(__tmp));
750bdd1243dSDimitry Andric       } else {
751bdd1243dSDimitry Andric         static_assert(is_nothrow_move_constructible_v<_Tp>,
752bdd1243dSDimitry Andric                       "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so "
753bdd1243dSDimitry Andric                       "that it can be reverted to the previous state in case an exception is thrown during swap.");
754*7a6dacacSDimitry Andric         _Tp __tmp(std::move(__with_val.__val()));
755*7a6dacacSDimitry Andric         __with_val.__destroy();
756*7a6dacacSDimitry Andric         auto __trans = std::__make_exception_guard([&] { __with_val.__construct(in_place, std::move(__tmp)); });
757*7a6dacacSDimitry Andric         __with_val.__construct(unexpect, std::move(__with_err.__unex()));
758bdd1243dSDimitry Andric         __trans.__complete();
759*7a6dacacSDimitry Andric         __with_err.__destroy();
760*7a6dacacSDimitry Andric         __with_err.__construct(in_place, std::move(__tmp));
761bdd1243dSDimitry Andric       }
762bdd1243dSDimitry Andric     };
763bdd1243dSDimitry Andric 
764*7a6dacacSDimitry Andric     if (this->__has_val()) {
765*7a6dacacSDimitry Andric       if (__rhs.__has_val()) {
766bdd1243dSDimitry Andric         using std::swap;
767*7a6dacacSDimitry Andric         swap(this->__val(), __rhs.__val());
768bdd1243dSDimitry Andric       } else {
769bdd1243dSDimitry Andric         __swap_val_unex_impl(*this, __rhs);
770bdd1243dSDimitry Andric       }
771bdd1243dSDimitry Andric     } else {
772*7a6dacacSDimitry Andric       if (__rhs.__has_val()) {
773bdd1243dSDimitry Andric         __swap_val_unex_impl(__rhs, *this);
774bdd1243dSDimitry Andric       } else {
775bdd1243dSDimitry Andric         using std::swap;
776*7a6dacacSDimitry Andric         swap(this->__unex(), __rhs.__unex());
777bdd1243dSDimitry Andric       }
778bdd1243dSDimitry Andric     }
779bdd1243dSDimitry Andric   }
780bdd1243dSDimitry Andric 
781cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) noexcept(noexcept(__x.swap(__y)))
782bdd1243dSDimitry Andric     requires requires { __x.swap(__y); }
783bdd1243dSDimitry Andric   {
784bdd1243dSDimitry Andric     __x.swap(__y);
785bdd1243dSDimitry Andric   }
786bdd1243dSDimitry Andric 
787bdd1243dSDimitry Andric   // [expected.object.obs], observers
788bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept {
789*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
790*7a6dacacSDimitry Andric         this->__has_val(), "expected::operator-> requires the expected to contain a value");
791*7a6dacacSDimitry Andric     return std::addressof(this->__val());
792bdd1243dSDimitry Andric   }
793bdd1243dSDimitry Andric 
794bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept {
795*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
796*7a6dacacSDimitry Andric         this->__has_val(), "expected::operator-> requires the expected to contain a value");
797*7a6dacacSDimitry Andric     return std::addressof(this->__val());
798bdd1243dSDimitry Andric   }
799bdd1243dSDimitry Andric 
800bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
801*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
802*7a6dacacSDimitry Andric         this->__has_val(), "expected::operator* requires the expected to contain a value");
803*7a6dacacSDimitry Andric     return this->__val();
804bdd1243dSDimitry Andric   }
805bdd1243dSDimitry Andric 
806bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
807*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
808*7a6dacacSDimitry Andric         this->__has_val(), "expected::operator* requires the expected to contain a value");
809*7a6dacacSDimitry Andric     return this->__val();
810bdd1243dSDimitry Andric   }
811bdd1243dSDimitry Andric 
812bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
813*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
814*7a6dacacSDimitry Andric         this->__has_val(), "expected::operator* requires the expected to contain a value");
815*7a6dacacSDimitry Andric     return std::move(this->__val());
816bdd1243dSDimitry Andric   }
817bdd1243dSDimitry Andric 
818bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
819*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
820*7a6dacacSDimitry Andric         this->__has_val(), "expected::operator* requires the expected to contain a value");
821*7a6dacacSDimitry Andric     return std::move(this->__val());
822bdd1243dSDimitry Andric   }
823bdd1243dSDimitry Andric 
824*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return this->__has_val(); }
825bdd1243dSDimitry Andric 
826*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); }
827bdd1243dSDimitry Andric 
828bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& {
82906c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
830*7a6dacacSDimitry Andric     if (!this->__has_val()) {
83106c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::as_const(error()));
832bdd1243dSDimitry Andric     }
833*7a6dacacSDimitry Andric     return this->__val();
834bdd1243dSDimitry Andric   }
835bdd1243dSDimitry Andric 
836bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
83706c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
838*7a6dacacSDimitry Andric     if (!this->__has_val()) {
83906c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::as_const(error()));
840bdd1243dSDimitry Andric     }
841*7a6dacacSDimitry Andric     return this->__val();
842bdd1243dSDimitry Andric   }
843bdd1243dSDimitry Andric 
844bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& {
84506c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
84606c3fb27SDimitry Andric                   "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
847*7a6dacacSDimitry Andric     if (!this->__has_val()) {
84806c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::move(error()));
849bdd1243dSDimitry Andric     }
850*7a6dacacSDimitry Andric     return std::move(this->__val());
851bdd1243dSDimitry Andric   }
852bdd1243dSDimitry Andric 
853bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
85406c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
85506c3fb27SDimitry Andric                   "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
856*7a6dacacSDimitry Andric     if (!this->__has_val()) {
85706c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::move(error()));
858bdd1243dSDimitry Andric     }
859*7a6dacacSDimitry Andric     return std::move(this->__val());
860bdd1243dSDimitry Andric   }
861bdd1243dSDimitry Andric 
862bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
863*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
864*7a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
865*7a6dacacSDimitry Andric     return this->__unex();
866bdd1243dSDimitry Andric   }
867bdd1243dSDimitry Andric 
868bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
869*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
870*7a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
871*7a6dacacSDimitry Andric     return this->__unex();
872bdd1243dSDimitry Andric   }
873bdd1243dSDimitry Andric 
874bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
875*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
876*7a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
877*7a6dacacSDimitry Andric     return std::move(this->__unex());
878bdd1243dSDimitry Andric   }
879bdd1243dSDimitry Andric 
880bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
881*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
882*7a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
883*7a6dacacSDimitry Andric     return std::move(this->__unex());
884bdd1243dSDimitry Andric   }
885bdd1243dSDimitry Andric 
886bdd1243dSDimitry Andric   template <class _Up>
887bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
888bdd1243dSDimitry Andric     static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible");
889bdd1243dSDimitry Andric     static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
890*7a6dacacSDimitry Andric     return this->__has_val() ? this->__val() : static_cast<_Tp>(std::forward<_Up>(__v));
891bdd1243dSDimitry Andric   }
892bdd1243dSDimitry Andric 
893bdd1243dSDimitry Andric   template <class _Up>
894bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
895bdd1243dSDimitry Andric     static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible");
896bdd1243dSDimitry Andric     static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
897*7a6dacacSDimitry Andric     return this->__has_val() ? std::move(this->__val()) : static_cast<_Tp>(std::forward<_Up>(__v));
898bdd1243dSDimitry Andric   }
899bdd1243dSDimitry Andric 
90006c3fb27SDimitry Andric   template <class _Up = _Err>
90106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
90206c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
90306c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
90406c3fb27SDimitry Andric     if (has_value())
90506c3fb27SDimitry Andric       return std::forward<_Up>(__error);
90606c3fb27SDimitry Andric     return error();
90706c3fb27SDimitry Andric   }
90806c3fb27SDimitry Andric 
90906c3fb27SDimitry Andric   template <class _Up = _Err>
91006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
91106c3fb27SDimitry Andric     static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
91206c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
91306c3fb27SDimitry Andric     if (has_value())
91406c3fb27SDimitry Andric       return std::forward<_Up>(__error);
91506c3fb27SDimitry Andric     return std::move(error());
91606c3fb27SDimitry Andric   }
91706c3fb27SDimitry Andric 
91806c3fb27SDimitry Andric   // [expected.void.monadic], monadic
91906c3fb27SDimitry Andric   template <class _Func>
92006c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
92106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
92206c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>;
9235f757f3fSDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f(**this) must be a specialization of std::expected");
92406c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
9255f757f3fSDimitry Andric                   "The result of f(**this) must have the same error_type as this expected");
92606c3fb27SDimitry Andric     if (has_value()) {
927*7a6dacacSDimitry Andric       return std::invoke(std::forward<_Func>(__f), this->__val());
92806c3fb27SDimitry Andric     }
92906c3fb27SDimitry Andric     return _Up(unexpect, error());
93006c3fb27SDimitry Andric   }
93106c3fb27SDimitry Andric 
93206c3fb27SDimitry Andric   template <class _Func>
93306c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
93406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
93506c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&>>;
9365f757f3fSDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f(**this) must be a specialization of std::expected");
93706c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
9385f757f3fSDimitry Andric                   "The result of f(**this) must have the same error_type as this expected");
93906c3fb27SDimitry Andric     if (has_value()) {
940*7a6dacacSDimitry Andric       return std::invoke(std::forward<_Func>(__f), this->__val());
94106c3fb27SDimitry Andric     }
94206c3fb27SDimitry Andric     return _Up(unexpect, error());
94306c3fb27SDimitry Andric   }
94406c3fb27SDimitry Andric 
94506c3fb27SDimitry Andric   template <class _Func>
94606c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
94706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
94806c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&&>>;
94906c3fb27SDimitry Andric     static_assert(
9505f757f3fSDimitry Andric         __is_std_expected<_Up>::value, "The result of f(std::move(**this)) must be a specialization of std::expected");
95106c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
9525f757f3fSDimitry Andric                   "The result of f(std::move(**this)) must have the same error_type as this expected");
95306c3fb27SDimitry Andric     if (has_value()) {
954*7a6dacacSDimitry Andric       return std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
95506c3fb27SDimitry Andric     }
95606c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
95706c3fb27SDimitry Andric   }
95806c3fb27SDimitry Andric 
95906c3fb27SDimitry Andric   template <class _Func>
96006c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
96106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
96206c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>;
96306c3fb27SDimitry Andric     static_assert(
9645f757f3fSDimitry Andric         __is_std_expected<_Up>::value, "The result of f(std::move(**this)) must be a specialization of std::expected");
96506c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
9665f757f3fSDimitry Andric                   "The result of f(std::move(**this)) must have the same error_type as this expected");
96706c3fb27SDimitry Andric     if (has_value()) {
968*7a6dacacSDimitry Andric       return std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
96906c3fb27SDimitry Andric     }
97006c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
97106c3fb27SDimitry Andric   }
97206c3fb27SDimitry Andric 
97306c3fb27SDimitry Andric   template <class _Func>
97406c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&>
97506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
97606c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
97706c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
97806c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
97906c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
98006c3fb27SDimitry Andric     if (has_value()) {
981*7a6dacacSDimitry Andric       return _Gp(in_place, this->__val());
98206c3fb27SDimitry Andric     }
98306c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
98406c3fb27SDimitry Andric   }
98506c3fb27SDimitry Andric 
98606c3fb27SDimitry Andric   template <class _Func>
98706c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&>
98806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
98906c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
99006c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
99106c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
99206c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
99306c3fb27SDimitry Andric     if (has_value()) {
994*7a6dacacSDimitry Andric       return _Gp(in_place, this->__val());
99506c3fb27SDimitry Andric     }
99606c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
99706c3fb27SDimitry Andric   }
99806c3fb27SDimitry Andric 
99906c3fb27SDimitry Andric   template <class _Func>
100006c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&&>
100106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
100206c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
100306c3fb27SDimitry Andric     static_assert(
100406c3fb27SDimitry Andric         __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
100506c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
100606c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
100706c3fb27SDimitry Andric     if (has_value()) {
1008*7a6dacacSDimitry Andric       return _Gp(in_place, std::move(this->__val()));
100906c3fb27SDimitry Andric     }
101006c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
101106c3fb27SDimitry Andric   }
101206c3fb27SDimitry Andric 
101306c3fb27SDimitry Andric   template <class _Func>
101406c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&&>
101506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
101606c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
101706c3fb27SDimitry Andric     static_assert(
101806c3fb27SDimitry Andric         __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
101906c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
102006c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
102106c3fb27SDimitry Andric     if (has_value()) {
1022*7a6dacacSDimitry Andric       return _Gp(in_place, std::move(this->__val()));
102306c3fb27SDimitry Andric     }
102406c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
102506c3fb27SDimitry Andric   }
102606c3fb27SDimitry Andric 
102706c3fb27SDimitry Andric   template <class _Func>
102806c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
102906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
103006c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>;
103106c3fb27SDimitry Andric     if (!has_value()) {
103206c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
103306c3fb27SDimitry Andric     }
103406c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
1035cb14a3feSDimitry Andric       return expected<_Up, _Err>(
1036*7a6dacacSDimitry Andric           __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), this->__val());
103706c3fb27SDimitry Andric     } else {
1038*7a6dacacSDimitry Andric       std::invoke(std::forward<_Func>(__f), this->__val());
103906c3fb27SDimitry Andric       return expected<_Up, _Err>();
104006c3fb27SDimitry Andric     }
104106c3fb27SDimitry Andric   }
104206c3fb27SDimitry Andric 
104306c3fb27SDimitry Andric   template <class _Func>
104406c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
104506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
104606c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>;
104706c3fb27SDimitry Andric     if (!has_value()) {
104806c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
104906c3fb27SDimitry Andric     }
105006c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
1051cb14a3feSDimitry Andric       return expected<_Up, _Err>(
1052*7a6dacacSDimitry Andric           __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), this->__val());
105306c3fb27SDimitry Andric     } else {
1054*7a6dacacSDimitry Andric       std::invoke(std::forward<_Func>(__f), this->__val());
105506c3fb27SDimitry Andric       return expected<_Up, _Err>();
105606c3fb27SDimitry Andric     }
105706c3fb27SDimitry Andric   }
105806c3fb27SDimitry Andric 
105906c3fb27SDimitry Andric   template <class _Func>
106006c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
106106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
106206c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>;
106306c3fb27SDimitry Andric     if (!has_value()) {
106406c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
106506c3fb27SDimitry Andric     }
106606c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
106706c3fb27SDimitry Andric       return expected<_Up, _Err>(
1068*7a6dacacSDimitry Andric           __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(this->__val()));
106906c3fb27SDimitry Andric     } else {
1070*7a6dacacSDimitry Andric       std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
107106c3fb27SDimitry Andric       return expected<_Up, _Err>();
107206c3fb27SDimitry Andric     }
107306c3fb27SDimitry Andric   }
107406c3fb27SDimitry Andric 
107506c3fb27SDimitry Andric   template <class _Func>
107606c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
107706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
107806c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&&>>;
107906c3fb27SDimitry Andric     if (!has_value()) {
108006c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
108106c3fb27SDimitry Andric     }
108206c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
108306c3fb27SDimitry Andric       return expected<_Up, _Err>(
1084*7a6dacacSDimitry Andric           __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(this->__val()));
108506c3fb27SDimitry Andric     } else {
1086*7a6dacacSDimitry Andric       std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
108706c3fb27SDimitry Andric       return expected<_Up, _Err>();
108806c3fb27SDimitry Andric     }
108906c3fb27SDimitry Andric   }
109006c3fb27SDimitry Andric 
109106c3fb27SDimitry Andric   template <class _Func>
109206c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&>
109306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
109406c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
109506c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
109606c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
109706c3fb27SDimitry Andric     if (has_value()) {
1098*7a6dacacSDimitry Andric       return expected<_Tp, _Gp>(in_place, this->__val());
109906c3fb27SDimitry Andric     }
110006c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
110106c3fb27SDimitry Andric   }
110206c3fb27SDimitry Andric 
110306c3fb27SDimitry Andric   template <class _Func>
110406c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&>
110506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
110606c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
110706c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
110806c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
110906c3fb27SDimitry Andric     if (has_value()) {
1110*7a6dacacSDimitry Andric       return expected<_Tp, _Gp>(in_place, this->__val());
111106c3fb27SDimitry Andric     }
111206c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
111306c3fb27SDimitry Andric   }
111406c3fb27SDimitry Andric 
111506c3fb27SDimitry Andric   template <class _Func>
111606c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&&>
111706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
111806c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
111906c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
112006c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
112106c3fb27SDimitry Andric     if (has_value()) {
1122*7a6dacacSDimitry Andric       return expected<_Tp, _Gp>(in_place, std::move(this->__val()));
112306c3fb27SDimitry Andric     }
112406c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
112506c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
112606c3fb27SDimitry Andric   }
112706c3fb27SDimitry Andric 
112806c3fb27SDimitry Andric   template <class _Func>
112906c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&&>
113006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
113106c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
113206c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
113306c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
113406c3fb27SDimitry Andric     if (has_value()) {
1135*7a6dacacSDimitry Andric       return expected<_Tp, _Gp>(in_place, std::move(this->__val()));
113606c3fb27SDimitry Andric     }
113706c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
113806c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
113906c3fb27SDimitry Andric   }
114006c3fb27SDimitry Andric 
1141bdd1243dSDimitry Andric   // [expected.object.eq], equality operators
1142bdd1243dSDimitry Andric   template <class _T2, class _E2>
1143bdd1243dSDimitry Andric     requires(!is_void_v<_T2>)
1144bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
1145*7a6dacacSDimitry Andric     if (__x.__has_val() != __y.__has_val()) {
1146bdd1243dSDimitry Andric       return false;
1147bdd1243dSDimitry Andric     } else {
1148*7a6dacacSDimitry Andric       if (__x.__has_val()) {
1149*7a6dacacSDimitry Andric         return __x.__val() == __y.__val();
1150bdd1243dSDimitry Andric       } else {
1151*7a6dacacSDimitry Andric         return __x.__unex() == __y.__unex();
1152bdd1243dSDimitry Andric       }
1153bdd1243dSDimitry Andric     }
1154bdd1243dSDimitry Andric   }
1155bdd1243dSDimitry Andric 
1156bdd1243dSDimitry Andric   template <class _T2>
1157bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) {
1158*7a6dacacSDimitry Andric     return __x.__has_val() && static_cast<bool>(__x.__val() == __v);
1159bdd1243dSDimitry Andric   }
1160bdd1243dSDimitry Andric 
1161bdd1243dSDimitry Andric   template <class _E2>
1162bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) {
1163*7a6dacacSDimitry Andric     return !__x.__has_val() && static_cast<bool>(__x.__unex() == __e.error());
1164bdd1243dSDimitry Andric   }
116506c3fb27SDimitry Andric };
116606c3fb27SDimitry Andric 
1167*7a6dacacSDimitry Andric template <class _Err>
1168*7a6dacacSDimitry Andric class __expected_void_base {
1169*7a6dacacSDimitry Andric   struct __empty_t {};
117006c3fb27SDimitry Andric   // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
117106c3fb27SDimitry Andric   // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
117206c3fb27SDimitry Andric   // it's not clear that it's implementable, given that the function is allowed to clobber
117306c3fb27SDimitry Andric   // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
1174*7a6dacacSDimitry Andric   union __union_t {
1175*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = delete;
1176*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&)
1177*7a6dacacSDimitry Andric       requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>)
1178*7a6dacacSDimitry Andric     = default;
1179*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) = delete;
1180*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&)
1181*7a6dacacSDimitry Andric       requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
1182*7a6dacacSDimitry Andric     = default;
1183*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(const __union_t&) = delete;
1184*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(__union_t&&)      = delete;
1185*7a6dacacSDimitry Andric 
1186*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(in_place_t) : __empty_() {}
1187b121cb00SDimitry Andric 
1188b121cb00SDimitry Andric     template <class... _Args>
1189*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(unexpect_t, _Args&&... __args)
1190b121cb00SDimitry Andric         : __unex_(std::forward<_Args>(__args)...) {}
119106c3fb27SDimitry Andric 
119206c3fb27SDimitry Andric     template <class _Func, class... _Args>
119306c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
1194*7a6dacacSDimitry Andric         __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
119506c3fb27SDimitry Andric         : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
119606c3fb27SDimitry Andric 
119706c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
1198*7a6dacacSDimitry Andric       requires(is_trivially_destructible_v<_Err>)
1199bdd1243dSDimitry Andric     = default;
1200bdd1243dSDimitry Andric 
1201*7a6dacacSDimitry Andric     // __repr's destructor handles this
1202bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
1203*7a6dacacSDimitry Andric       requires(!is_trivially_destructible_v<_Err>)
1204bdd1243dSDimitry Andric     {}
1205bdd1243dSDimitry Andric 
1206*7a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
1207*7a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
120806c3fb27SDimitry Andric   };
1209bdd1243dSDimitry Andric 
1210*7a6dacacSDimitry Andric   static constexpr bool __put_flag_in_tail                    = __fits_in_tail_padding<__union_t, bool>;
1211*7a6dacacSDimitry Andric   static constexpr bool __allow_reusing_expected_tail_padding = !__put_flag_in_tail;
1212*7a6dacacSDimitry Andric 
1213*7a6dacacSDimitry Andric   struct __repr {
1214*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr() = delete;
1215*7a6dacacSDimitry Andric 
1216*7a6dacacSDimitry Andric     template <class... _Args>
1217*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(in_place_t __tag) : __union_(in_place, __tag), __has_val_(true) {}
1218*7a6dacacSDimitry Andric 
1219*7a6dacacSDimitry Andric     template <class... _Args>
1220*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(unexpect_t __tag, _Args&&... __args)
1221*7a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {}
1222*7a6dacacSDimitry Andric 
1223*7a6dacacSDimitry Andric     template <class... _Args>
1224*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_unexpected_from_invoke_tag __tag,
1225*7a6dacacSDimitry Andric                                                     _Args&&... __args)
1226*7a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {}
1227*7a6dacacSDimitry Andric 
1228*7a6dacacSDimitry Andric     template <class _OtherUnion>
1229*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(bool __has_val, _OtherUnion&& __other)
1230*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
1231*7a6dacacSDimitry Andric         : __union_(__conditional_no_unique_address_invoke_tag{},
1232*7a6dacacSDimitry Andric                    [&] { return __make_union(__has_val, std::forward<_OtherUnion>(__other)); }),
1233*7a6dacacSDimitry Andric           __has_val_(__has_val) {}
1234*7a6dacacSDimitry Andric 
1235*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) = delete;
1236*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&)
1237*7a6dacacSDimitry Andric       requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>)
1238*7a6dacacSDimitry Andric     = default;
1239*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) = delete;
1240*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&)
1241*7a6dacacSDimitry Andric       requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
1242*7a6dacacSDimitry Andric     = default;
1243*7a6dacacSDimitry Andric 
1244*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(const __repr&) = delete;
1245*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(__repr&&)      = delete;
1246*7a6dacacSDimitry Andric 
1247*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__repr()
1248*7a6dacacSDimitry Andric       requires(is_trivially_destructible_v<_Err>)
1249*7a6dacacSDimitry Andric     = default;
1250*7a6dacacSDimitry Andric 
1251*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__repr()
1252*7a6dacacSDimitry Andric       requires(!is_trivially_destructible_v<_Err>)
1253*7a6dacacSDimitry Andric     {
1254*7a6dacacSDimitry Andric       __destroy_union_member();
1255*7a6dacacSDimitry Andric     }
1256*7a6dacacSDimitry Andric 
1257*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union()
1258*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding && is_trivially_destructible_v<_Err>)
1259*7a6dacacSDimitry Andric     {
1260*7a6dacacSDimitry Andric       std::destroy_at(&__union_.__v);
1261*7a6dacacSDimitry Andric     }
1262*7a6dacacSDimitry Andric 
1263*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union()
1264*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding && !is_trivially_destructible_v<_Err>)
1265*7a6dacacSDimitry Andric     {
1266*7a6dacacSDimitry Andric       __destroy_union_member();
1267*7a6dacacSDimitry Andric       std::destroy_at(&__union_.__v);
1268*7a6dacacSDimitry Andric     }
1269*7a6dacacSDimitry Andric 
1270*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(in_place_t)
1271*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
1272*7a6dacacSDimitry Andric     {
1273*7a6dacacSDimitry Andric       std::construct_at(&__union_.__v, in_place);
1274*7a6dacacSDimitry Andric       __has_val_ = true;
1275*7a6dacacSDimitry Andric     }
1276*7a6dacacSDimitry Andric 
1277*7a6dacacSDimitry Andric     template <class... _Args>
1278*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(unexpect_t, _Args&&... __args)
1279*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
1280*7a6dacacSDimitry Andric     {
1281*7a6dacacSDimitry Andric       std::construct_at(&__union_.__v, unexpect, std::forward<_Args>(__args)...);
1282*7a6dacacSDimitry Andric       __has_val_ = false;
1283*7a6dacacSDimitry Andric     }
1284*7a6dacacSDimitry Andric 
1285*7a6dacacSDimitry Andric   private:
1286*7a6dacacSDimitry Andric     template <class>
1287*7a6dacacSDimitry Andric     friend class __expected_void_base;
1288*7a6dacacSDimitry Andric 
1289*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union_member()
1290*7a6dacacSDimitry Andric       requires(!is_trivially_destructible_v<_Err>)
1291*7a6dacacSDimitry Andric     {
1292*7a6dacacSDimitry Andric       if (!__has_val_)
1293*7a6dacacSDimitry Andric         std::destroy_at(std::addressof(__union_.__v.__unex_));
1294*7a6dacacSDimitry Andric     }
1295*7a6dacacSDimitry Andric 
1296*7a6dacacSDimitry Andric     template <class _OtherUnion>
1297*7a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI static constexpr __union_t __make_union(bool __has_val, _OtherUnion&& __other)
1298*7a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
1299*7a6dacacSDimitry Andric     {
1300*7a6dacacSDimitry Andric       if (__has_val)
1301*7a6dacacSDimitry Andric         return __union_t(in_place);
1302*7a6dacacSDimitry Andric       else
1303*7a6dacacSDimitry Andric         return __union_t(unexpect, std::forward<_OtherUnion>(__other).__unex_);
1304*7a6dacacSDimitry Andric     }
1305*7a6dacacSDimitry Andric 
1306*7a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__put_flag_in_tail, __union_t> __union_;
1307*7a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS bool __has_val_;
1308*7a6dacacSDimitry Andric   };
1309*7a6dacacSDimitry Andric 
1310*7a6dacacSDimitry Andric   template <class _OtherUnion>
1311*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr __repr __make_repr(bool __has_val, _OtherUnion&& __other)
1312*7a6dacacSDimitry Andric     requires(__put_flag_in_tail)
1313*7a6dacacSDimitry Andric   {
1314*7a6dacacSDimitry Andric     if (__has_val)
1315*7a6dacacSDimitry Andric       return __repr(in_place);
1316*7a6dacacSDimitry Andric     else
1317*7a6dacacSDimitry Andric       return __repr(unexpect, std::forward<_OtherUnion>(__other).__unex_);
1318*7a6dacacSDimitry Andric   }
1319*7a6dacacSDimitry Andric 
1320*7a6dacacSDimitry Andric protected:
1321*7a6dacacSDimitry Andric   template <class... _Args>
1322*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_void_base(_Args&&... __args)
1323*7a6dacacSDimitry Andric       : __repr_(in_place, std::forward<_Args>(__args)...) {}
1324*7a6dacacSDimitry Andric 
1325*7a6dacacSDimitry Andric   template <class _OtherUnion>
1326*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_void_base(bool __has_val, _OtherUnion&& __other)
1327*7a6dacacSDimitry Andric     requires(__put_flag_in_tail)
1328*7a6dacacSDimitry Andric       : __repr_(__conditional_no_unique_address_invoke_tag{},
1329*7a6dacacSDimitry Andric                 [&] { return __make_repr(__has_val, std::forward<_OtherUnion>(__other)); }) {}
1330*7a6dacacSDimitry Andric 
1331*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __destroy() {
1332*7a6dacacSDimitry Andric     if constexpr (__put_flag_in_tail)
1333*7a6dacacSDimitry Andric       std::destroy_at(&__repr_.__v);
1334*7a6dacacSDimitry Andric     else
1335*7a6dacacSDimitry Andric       __repr_.__v.__destroy_union();
1336*7a6dacacSDimitry Andric   }
1337*7a6dacacSDimitry Andric 
1338*7a6dacacSDimitry Andric   template <class _Tag, class... _Args>
1339*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __construct(_Tag __tag, _Args&&... __args) {
1340*7a6dacacSDimitry Andric     if constexpr (__put_flag_in_tail)
1341*7a6dacacSDimitry Andric       std::construct_at(&__repr_.__v, __tag, std::forward<_Args>(__args)...);
1342*7a6dacacSDimitry Andric     else
1343*7a6dacacSDimitry Andric       __repr_.__v.__construct_union(__tag, std::forward<_Args>(__args)...);
1344*7a6dacacSDimitry Andric   }
1345*7a6dacacSDimitry Andric 
1346*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool __has_val() const { return __repr_.__v.__has_val_; }
1347*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr __union_t& __union() { return __repr_.__v.__union_.__v; }
1348*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const __union_t& __union() const { return __repr_.__v.__union_.__v; }
1349*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& __unex() { return __repr_.__v.__union_.__v.__unex_; }
1350*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& __unex() const { return __repr_.__v.__union_.__v.__unex_; }
1351*7a6dacacSDimitry Andric 
1352*7a6dacacSDimitry Andric private:
1353*7a6dacacSDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__allow_reusing_expected_tail_padding, __repr> __repr_;
1354bdd1243dSDimitry Andric };
1355bdd1243dSDimitry Andric 
1356bdd1243dSDimitry Andric template <class _Tp, class _Err>
1357bdd1243dSDimitry Andric   requires is_void_v<_Tp>
1358*7a6dacacSDimitry Andric class expected<_Tp, _Err> : private __expected_void_base<_Err> {
1359bdd1243dSDimitry Andric   static_assert(__valid_std_unexpected<_Err>::value,
1360bdd1243dSDimitry Andric                 "[expected.void.general] A program that instantiates expected<T, E> with a E that is not a "
1361bdd1243dSDimitry Andric                 "valid argument for unexpected<E> is ill-formed");
1362bdd1243dSDimitry Andric 
1363bdd1243dSDimitry Andric   template <class, class>
1364bdd1243dSDimitry Andric   friend class expected;
1365bdd1243dSDimitry Andric 
1366bdd1243dSDimitry Andric   template <class _Up, class _OtherErr, class _OtherErrQual>
1367bdd1243dSDimitry Andric   using __can_convert =
1368bdd1243dSDimitry Andric       _And< is_void<_Up>,
1369bdd1243dSDimitry Andric             is_constructible<_Err, _OtherErrQual>,
1370bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
1371bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
1372bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
1373bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>>>;
1374bdd1243dSDimitry Andric 
1375*7a6dacacSDimitry Andric   using __base = __expected_void_base<_Err>;
1376*7a6dacacSDimitry Andric 
1377bdd1243dSDimitry Andric public:
1378bdd1243dSDimitry Andric   using value_type      = _Tp;
1379bdd1243dSDimitry Andric   using error_type      = _Err;
1380bdd1243dSDimitry Andric   using unexpected_type = unexpected<_Err>;
1381bdd1243dSDimitry Andric 
1382bdd1243dSDimitry Andric   template <class _Up>
1383bdd1243dSDimitry Andric   using rebind = expected<_Up, error_type>;
1384bdd1243dSDimitry Andric 
1385bdd1243dSDimitry Andric   // [expected.void.ctor], constructors
1386*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __base(in_place) {}
1387bdd1243dSDimitry Andric 
1388bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
1389bdd1243dSDimitry Andric 
1390bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
1391bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>)
1392bdd1243dSDimitry Andric   = default;
1393bdd1243dSDimitry Andric 
1394cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs) noexcept(
1395cb14a3feSDimitry Andric       is_nothrow_copy_constructible_v<_Err>) // strengthened
1396bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>)
1397*7a6dacacSDimitry Andric       : __base(__rhs.__has_val(), __rhs.__union()) {}
1398bdd1243dSDimitry Andric 
1399bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
1400bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
1401bdd1243dSDimitry Andric   = default;
1402bdd1243dSDimitry Andric 
1403cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs) noexcept(is_nothrow_move_constructible_v<_Err>)
1404bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>)
1405*7a6dacacSDimitry Andric       : __base(__rhs.__has_val(), std::move(__rhs.__union())) {}
1406bdd1243dSDimitry Andric 
1407bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
1408bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value
1409bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
1410cb14a3feSDimitry Andric       expected(const expected<_Up, _OtherErr>& __rhs) noexcept(
1411cb14a3feSDimitry Andric           is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
1412*7a6dacacSDimitry Andric       : __base(__rhs.__has_val(), __rhs.__union()) {}
1413bdd1243dSDimitry Andric 
1414bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
1415bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, _OtherErr>::value
1416bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
1417cb14a3feSDimitry Andric       expected(expected<_Up, _OtherErr>&& __rhs) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
1418*7a6dacacSDimitry Andric       : __base(__rhs.__has_val(), std::move(__rhs.__union())) {}
1419bdd1243dSDimitry Andric 
1420bdd1243dSDimitry Andric   template <class _OtherErr>
1421bdd1243dSDimitry Andric     requires is_constructible_v<_Err, const _OtherErr&>
1422cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>) expected(
1423cb14a3feSDimitry Andric       const unexpected<_OtherErr>& __unex) noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
1424*7a6dacacSDimitry Andric       : __base(unexpect, __unex.error()) {}
1425bdd1243dSDimitry Andric 
1426bdd1243dSDimitry Andric   template <class _OtherErr>
1427bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _OtherErr>
1428bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
1429cb14a3feSDimitry Andric       expected(unexpected<_OtherErr>&& __unex) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
1430*7a6dacacSDimitry Andric       : __base(unexpect, std::move(__unex.error())) {}
1431bdd1243dSDimitry Andric 
1432*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __base(in_place) {}
1433bdd1243dSDimitry Andric 
1434bdd1243dSDimitry Andric   template <class... _Args>
1435bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _Args...>
1436cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) noexcept(
1437cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Err, _Args...>) // strengthened
1438*7a6dacacSDimitry Andric       : __base(unexpect, std::forward<_Args>(__args)...) {}
1439bdd1243dSDimitry Andric 
1440bdd1243dSDimitry Andric   template <class _Up, class... _Args>
1441bdd1243dSDimitry Andric     requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
1442cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) noexcept(
1443cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
1444*7a6dacacSDimitry Andric       : __base(unexpect, __il, std::forward<_Args>(__args)...) {}
1445bdd1243dSDimitry Andric 
144606c3fb27SDimitry Andric private:
144706c3fb27SDimitry Andric   template <class _Func, class... _Args>
144806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
144906c3fb27SDimitry Andric       __expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
1450*7a6dacacSDimitry Andric       : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {}
145106c3fb27SDimitry Andric 
145206c3fb27SDimitry Andric public:
1453bdd1243dSDimitry Andric   // [expected.void.dtor], destructor
1454bdd1243dSDimitry Andric 
1455*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected() = default;
1456bdd1243dSDimitry Andric 
1457*7a6dacacSDimitry Andric private:
1458*7a6dacacSDimitry Andric   template <class... _Args>
1459*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(unexpect_t, _Args&&... __args) {
1460*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_INTERNAL(this->__has_val(), "__reinit_expected(unexpect_t, ...) needs value to be set");
1461*7a6dacacSDimitry Andric 
1462*7a6dacacSDimitry Andric     this->__destroy();
1463*7a6dacacSDimitry Andric     auto __trans = std::__make_exception_guard([&] { this->__construct(in_place); });
1464*7a6dacacSDimitry Andric     this->__construct(unexpect, std::forward<_Args>(__args)...);
1465*7a6dacacSDimitry Andric     __trans.__complete();
1466bdd1243dSDimitry Andric   }
1467bdd1243dSDimitry Andric 
1468*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(in_place_t) {
1469*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_INTERNAL(!this->__has_val(), "__reinit_expected(in_place_t, ...) needs value to be unset");
1470*7a6dacacSDimitry Andric 
1471*7a6dacacSDimitry Andric     this->__destroy();
1472*7a6dacacSDimitry Andric     this->__construct(in_place);
1473*7a6dacacSDimitry Andric   }
1474*7a6dacacSDimitry Andric 
1475*7a6dacacSDimitry Andric public:
1476bdd1243dSDimitry Andric   // [expected.void.assign], assignment
1477bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
1478bdd1243dSDimitry Andric 
1479cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) noexcept(
1480cb14a3feSDimitry Andric       is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened
1481bdd1243dSDimitry Andric     requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>)
1482bdd1243dSDimitry Andric   {
1483*7a6dacacSDimitry Andric     if (this->__has_val()) {
1484*7a6dacacSDimitry Andric       if (!__rhs.__has_val()) {
1485*7a6dacacSDimitry Andric         __reinit_expected(unexpect, __rhs.__unex());
1486bdd1243dSDimitry Andric       }
1487bdd1243dSDimitry Andric     } else {
1488*7a6dacacSDimitry Andric       if (__rhs.__has_val()) {
1489*7a6dacacSDimitry Andric         __reinit_expected(in_place);
1490bdd1243dSDimitry Andric       } else {
1491*7a6dacacSDimitry Andric         this->__unex() = __rhs.__unex();
1492bdd1243dSDimitry Andric       }
1493bdd1243dSDimitry Andric     }
1494bdd1243dSDimitry Andric     return *this;
1495bdd1243dSDimitry Andric   }
1496bdd1243dSDimitry Andric 
1497bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&&) = delete;
1498bdd1243dSDimitry Andric 
1499cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected&
1500cb14a3feSDimitry Andric   operator=(expected&& __rhs) noexcept(is_nothrow_move_assignable_v<_Err> && is_nothrow_move_constructible_v<_Err>)
1501cb14a3feSDimitry Andric     requires(is_move_assignable_v<_Err> && is_move_constructible_v<_Err>)
1502bdd1243dSDimitry Andric   {
1503*7a6dacacSDimitry Andric     if (this->__has_val()) {
1504*7a6dacacSDimitry Andric       if (!__rhs.__has_val()) {
1505*7a6dacacSDimitry Andric         __reinit_expected(unexpect, std::move(__rhs.__unex()));
1506bdd1243dSDimitry Andric       }
1507bdd1243dSDimitry Andric     } else {
1508*7a6dacacSDimitry Andric       if (__rhs.__has_val()) {
1509*7a6dacacSDimitry Andric         __reinit_expected(in_place);
1510bdd1243dSDimitry Andric       } else {
1511*7a6dacacSDimitry Andric         this->__unex() = std::move(__rhs.__unex());
1512bdd1243dSDimitry Andric       }
1513bdd1243dSDimitry Andric     }
1514bdd1243dSDimitry Andric     return *this;
1515bdd1243dSDimitry Andric   }
1516bdd1243dSDimitry Andric 
1517bdd1243dSDimitry Andric   template <class _OtherErr>
1518bdd1243dSDimitry Andric     requires(is_constructible_v<_Err, const _OtherErr&> && is_assignable_v<_Err&, const _OtherErr&>)
1519bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
1520*7a6dacacSDimitry Andric     if (this->__has_val()) {
1521*7a6dacacSDimitry Andric       __reinit_expected(unexpect, __un.error());
1522bdd1243dSDimitry Andric     } else {
1523*7a6dacacSDimitry Andric       this->__unex() = __un.error();
1524bdd1243dSDimitry Andric     }
1525bdd1243dSDimitry Andric     return *this;
1526bdd1243dSDimitry Andric   }
1527bdd1243dSDimitry Andric 
1528bdd1243dSDimitry Andric   template <class _OtherErr>
1529bdd1243dSDimitry Andric     requires(is_constructible_v<_Err, _OtherErr> && is_assignable_v<_Err&, _OtherErr>)
1530bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
1531*7a6dacacSDimitry Andric     if (this->__has_val()) {
1532*7a6dacacSDimitry Andric       __reinit_expected(unexpect, std::move(__un.error()));
1533bdd1243dSDimitry Andric     } else {
1534*7a6dacacSDimitry Andric       this->__unex() = std::move(__un.error());
1535bdd1243dSDimitry Andric     }
1536bdd1243dSDimitry Andric     return *this;
1537bdd1243dSDimitry Andric   }
1538bdd1243dSDimitry Andric 
1539bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept {
1540*7a6dacacSDimitry Andric     if (!this->__has_val()) {
1541*7a6dacacSDimitry Andric       __reinit_expected(in_place);
1542bdd1243dSDimitry Andric     }
1543bdd1243dSDimitry Andric   }
1544bdd1243dSDimitry Andric 
1545bdd1243dSDimitry Andric   // [expected.void.swap], swap
1546cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void
1547cb14a3feSDimitry Andric   swap(expected& __rhs) noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
1548bdd1243dSDimitry Andric     requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>)
1549bdd1243dSDimitry Andric   {
1550*7a6dacacSDimitry Andric     auto __swap_val_unex_impl = [](expected& __with_val, expected& __with_err) {
1551*7a6dacacSDimitry Andric       // May throw, but will re-engage `__with_val` in that case.
1552*7a6dacacSDimitry Andric       __with_val.__reinit_expected(unexpect, std::move(__with_err.__unex()));
1553*7a6dacacSDimitry Andric       // Will not throw.
1554*7a6dacacSDimitry Andric       __with_err.__reinit_expected(in_place);
1555bdd1243dSDimitry Andric     };
1556bdd1243dSDimitry Andric 
1557*7a6dacacSDimitry Andric     if (this->__has_val()) {
1558*7a6dacacSDimitry Andric       if (!__rhs.__has_val()) {
1559bdd1243dSDimitry Andric         __swap_val_unex_impl(*this, __rhs);
1560bdd1243dSDimitry Andric       }
1561bdd1243dSDimitry Andric     } else {
1562*7a6dacacSDimitry Andric       if (__rhs.__has_val()) {
1563bdd1243dSDimitry Andric         __swap_val_unex_impl(__rhs, *this);
1564bdd1243dSDimitry Andric       } else {
1565bdd1243dSDimitry Andric         using std::swap;
1566*7a6dacacSDimitry Andric         swap(this->__unex(), __rhs.__unex());
1567bdd1243dSDimitry Andric       }
1568bdd1243dSDimitry Andric     }
1569bdd1243dSDimitry Andric   }
1570bdd1243dSDimitry Andric 
1571cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) noexcept(noexcept(__x.swap(__y)))
1572bdd1243dSDimitry Andric     requires requires { __x.swap(__y); }
1573bdd1243dSDimitry Andric   {
1574bdd1243dSDimitry Andric     __x.swap(__y);
1575bdd1243dSDimitry Andric   }
1576bdd1243dSDimitry Andric 
1577bdd1243dSDimitry Andric   // [expected.void.obs], observers
1578*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return this->__has_val(); }
1579bdd1243dSDimitry Andric 
1580*7a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); }
1581bdd1243dSDimitry Andric 
1582bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept {
1583*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1584*7a6dacacSDimitry Andric         this->__has_val(), "expected::operator* requires the expected to contain a value");
1585bdd1243dSDimitry Andric   }
1586bdd1243dSDimitry Andric 
1587bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void value() const& {
1588*7a6dacacSDimitry Andric     static_assert(is_copy_constructible_v<_Err>);
1589*7a6dacacSDimitry Andric     if (!this->__has_val()) {
1590*7a6dacacSDimitry Andric       std::__throw_bad_expected_access<_Err>(this->__unex());
1591bdd1243dSDimitry Andric     }
1592bdd1243dSDimitry Andric   }
1593bdd1243dSDimitry Andric 
1594bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void value() && {
1595*7a6dacacSDimitry Andric     static_assert(is_copy_constructible_v<_Err> && is_move_constructible_v<_Err>);
1596*7a6dacacSDimitry Andric     if (!this->__has_val()) {
1597*7a6dacacSDimitry Andric       std::__throw_bad_expected_access<_Err>(std::move(this->__unex()));
1598bdd1243dSDimitry Andric     }
1599bdd1243dSDimitry Andric   }
1600bdd1243dSDimitry Andric 
1601bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
1602*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1603*7a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
1604*7a6dacacSDimitry Andric     return this->__unex();
1605bdd1243dSDimitry Andric   }
1606bdd1243dSDimitry Andric 
1607bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
1608*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1609*7a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
1610*7a6dacacSDimitry Andric     return this->__unex();
1611bdd1243dSDimitry Andric   }
1612bdd1243dSDimitry Andric 
1613bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
1614*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1615*7a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
1616*7a6dacacSDimitry Andric     return std::move(this->__unex());
1617bdd1243dSDimitry Andric   }
1618bdd1243dSDimitry Andric 
1619bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
1620*7a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
1621*7a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
1622*7a6dacacSDimitry Andric     return std::move(this->__unex());
1623bdd1243dSDimitry Andric   }
1624bdd1243dSDimitry Andric 
162506c3fb27SDimitry Andric   template <class _Up = _Err>
162606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
162706c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
162806c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
162906c3fb27SDimitry Andric     if (has_value()) {
163006c3fb27SDimitry Andric       return std::forward<_Up>(__error);
163106c3fb27SDimitry Andric     }
163206c3fb27SDimitry Andric     return error();
163306c3fb27SDimitry Andric   }
163406c3fb27SDimitry Andric 
163506c3fb27SDimitry Andric   template <class _Up = _Err>
163606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
163706c3fb27SDimitry Andric     static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
163806c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
163906c3fb27SDimitry Andric     if (has_value()) {
164006c3fb27SDimitry Andric       return std::forward<_Up>(__error);
164106c3fb27SDimitry Andric     }
164206c3fb27SDimitry Andric     return std::move(error());
164306c3fb27SDimitry Andric   }
164406c3fb27SDimitry Andric 
164506c3fb27SDimitry Andric   // [expected.void.monadic], monadic
164606c3fb27SDimitry Andric   template <class _Func>
164706c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
164806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
164906c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
165006c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
165106c3fb27SDimitry Andric     static_assert(
165206c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
165306c3fb27SDimitry Andric     if (has_value()) {
165406c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
165506c3fb27SDimitry Andric     }
165606c3fb27SDimitry Andric     return _Up(unexpect, error());
165706c3fb27SDimitry Andric   }
165806c3fb27SDimitry Andric 
165906c3fb27SDimitry Andric   template <class _Func>
166006c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
166106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
166206c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
166306c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
166406c3fb27SDimitry Andric     static_assert(
166506c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
166606c3fb27SDimitry Andric     if (has_value()) {
166706c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
166806c3fb27SDimitry Andric     }
166906c3fb27SDimitry Andric     return _Up(unexpect, error());
167006c3fb27SDimitry Andric   }
167106c3fb27SDimitry Andric 
167206c3fb27SDimitry Andric   template <class _Func>
167306c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
167406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
167506c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
167606c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
167706c3fb27SDimitry Andric     static_assert(
167806c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
167906c3fb27SDimitry Andric     if (has_value()) {
168006c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
168106c3fb27SDimitry Andric     }
168206c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
168306c3fb27SDimitry Andric   }
168406c3fb27SDimitry Andric 
168506c3fb27SDimitry Andric   template <class _Func>
168606c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
168706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
168806c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
168906c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
169006c3fb27SDimitry Andric     static_assert(
169106c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
169206c3fb27SDimitry Andric     if (has_value()) {
169306c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
169406c3fb27SDimitry Andric     }
169506c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
169606c3fb27SDimitry Andric   }
169706c3fb27SDimitry Andric 
169806c3fb27SDimitry Andric   template <class _Func>
169906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
170006c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
170106c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
170206c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
170306c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
170406c3fb27SDimitry Andric     if (has_value()) {
170506c3fb27SDimitry Andric       return _Gp();
170606c3fb27SDimitry Andric     }
170706c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
170806c3fb27SDimitry Andric   }
170906c3fb27SDimitry Andric 
171006c3fb27SDimitry Andric   template <class _Func>
171106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
171206c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
171306c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
171406c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
171506c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
171606c3fb27SDimitry Andric     if (has_value()) {
171706c3fb27SDimitry Andric       return _Gp();
171806c3fb27SDimitry Andric     }
171906c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
172006c3fb27SDimitry Andric   }
172106c3fb27SDimitry Andric 
172206c3fb27SDimitry Andric   template <class _Func>
172306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
172406c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
1725cb14a3feSDimitry Andric     static_assert(
1726cb14a3feSDimitry Andric         __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
172706c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
172806c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
172906c3fb27SDimitry Andric     if (has_value()) {
173006c3fb27SDimitry Andric       return _Gp();
173106c3fb27SDimitry Andric     }
173206c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
173306c3fb27SDimitry Andric   }
173406c3fb27SDimitry Andric 
173506c3fb27SDimitry Andric   template <class _Func>
173606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
173706c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
1738cb14a3feSDimitry Andric     static_assert(
1739cb14a3feSDimitry Andric         __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
174006c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
174106c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
174206c3fb27SDimitry Andric     if (has_value()) {
174306c3fb27SDimitry Andric       return _Gp();
174406c3fb27SDimitry Andric     }
174506c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
174606c3fb27SDimitry Andric   }
174706c3fb27SDimitry Andric 
174806c3fb27SDimitry Andric   template <class _Func>
174906c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
175006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
175106c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
175206c3fb27SDimitry Andric     if (!has_value()) {
175306c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
175406c3fb27SDimitry Andric     }
175506c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
175606c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
175706c3fb27SDimitry Andric     } else {
175806c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
175906c3fb27SDimitry Andric       return expected<_Up, _Err>();
176006c3fb27SDimitry Andric     }
176106c3fb27SDimitry Andric   }
176206c3fb27SDimitry Andric 
176306c3fb27SDimitry Andric   template <class _Func>
176406c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
176506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
176606c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
176706c3fb27SDimitry Andric     if (!has_value()) {
176806c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
176906c3fb27SDimitry Andric     }
177006c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
177106c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
177206c3fb27SDimitry Andric     } else {
177306c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
177406c3fb27SDimitry Andric       return expected<_Up, _Err>();
177506c3fb27SDimitry Andric     }
177606c3fb27SDimitry Andric   }
177706c3fb27SDimitry Andric 
177806c3fb27SDimitry Andric   template <class _Func>
177906c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
178006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
178106c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
178206c3fb27SDimitry Andric     if (!has_value()) {
178306c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
178406c3fb27SDimitry Andric     }
178506c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
178606c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
178706c3fb27SDimitry Andric     } else {
178806c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
178906c3fb27SDimitry Andric       return expected<_Up, _Err>();
179006c3fb27SDimitry Andric     }
179106c3fb27SDimitry Andric   }
179206c3fb27SDimitry Andric 
179306c3fb27SDimitry Andric   template <class _Func>
179406c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
179506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
179606c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
179706c3fb27SDimitry Andric     if (!has_value()) {
179806c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
179906c3fb27SDimitry Andric     }
180006c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
180106c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
180206c3fb27SDimitry Andric     } else {
180306c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
180406c3fb27SDimitry Andric       return expected<_Up, _Err>();
180506c3fb27SDimitry Andric     }
180606c3fb27SDimitry Andric   }
180706c3fb27SDimitry Andric 
180806c3fb27SDimitry Andric   template <class _Func>
180906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
181006c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
181106c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
181206c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
181306c3fb27SDimitry Andric     if (has_value()) {
181406c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
181506c3fb27SDimitry Andric     }
181606c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
181706c3fb27SDimitry Andric   }
181806c3fb27SDimitry Andric 
181906c3fb27SDimitry Andric   template <class _Func>
182006c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
182106c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
182206c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
182306c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
182406c3fb27SDimitry Andric     if (has_value()) {
182506c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
182606c3fb27SDimitry Andric     }
182706c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
182806c3fb27SDimitry Andric   }
182906c3fb27SDimitry Andric 
183006c3fb27SDimitry Andric   template <class _Func>
183106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
183206c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
183306c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
183406c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
183506c3fb27SDimitry Andric     if (has_value()) {
183606c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
183706c3fb27SDimitry Andric     }
183806c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
183906c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
184006c3fb27SDimitry Andric   }
184106c3fb27SDimitry Andric 
184206c3fb27SDimitry Andric   template <class _Func>
184306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
184406c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
184506c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
184606c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
184706c3fb27SDimitry Andric     if (has_value()) {
184806c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
184906c3fb27SDimitry Andric     }
185006c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
185106c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
185206c3fb27SDimitry Andric   }
185306c3fb27SDimitry Andric 
1854bdd1243dSDimitry Andric   // [expected.void.eq], equality operators
1855bdd1243dSDimitry Andric   template <class _T2, class _E2>
1856bdd1243dSDimitry Andric     requires is_void_v<_T2>
1857bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
1858*7a6dacacSDimitry Andric     if (__x.__has_val() != __y.__has_val()) {
1859bdd1243dSDimitry Andric       return false;
1860bdd1243dSDimitry Andric     } else {
1861*7a6dacacSDimitry Andric       return __x.__has_val() || static_cast<bool>(__x.__unex() == __y.__unex());
1862bdd1243dSDimitry Andric     }
1863bdd1243dSDimitry Andric   }
1864bdd1243dSDimitry Andric 
1865bdd1243dSDimitry Andric   template <class _E2>
1866bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) {
1867*7a6dacacSDimitry Andric     return !__x.__has_val() && static_cast<bool>(__x.__unex() == __y.error());
1868bdd1243dSDimitry Andric   }
1869bdd1243dSDimitry Andric };
1870bdd1243dSDimitry Andric 
1871bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
1872bdd1243dSDimitry Andric 
1873bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER >= 23
1874bdd1243dSDimitry Andric 
187506c3fb27SDimitry Andric _LIBCPP_POP_MACROS
187606c3fb27SDimitry Andric 
1877bdd1243dSDimitry Andric #endif // _LIBCPP___EXPECTED_EXPECTED_H
1878