xref: /freebsd-src/contrib/llvm-project/libcxx/include/__expected/expected.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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_function.h>
27*0fca6ea1SDimitry Andric #include <__type_traits/is_nothrow_assignable.h>
28bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_constructible.h>
29bdd1243dSDimitry Andric #include <__type_traits/is_reference.h>
30bdd1243dSDimitry Andric #include <__type_traits/is_same.h>
31bdd1243dSDimitry Andric #include <__type_traits/is_swappable.h>
32*0fca6ea1SDimitry Andric #include <__type_traits/is_trivially_constructible.h>
33bdd1243dSDimitry Andric #include <__type_traits/is_trivially_destructible.h>
34*0fca6ea1SDimitry Andric #include <__type_traits/is_trivially_relocatable.h>
35bdd1243dSDimitry Andric #include <__type_traits/is_void.h>
36bdd1243dSDimitry Andric #include <__type_traits/lazy.h>
37bdd1243dSDimitry Andric #include <__type_traits/negation.h>
38bdd1243dSDimitry Andric #include <__type_traits/remove_cv.h>
39bdd1243dSDimitry Andric #include <__type_traits/remove_cvref.h>
4006c3fb27SDimitry Andric #include <__utility/as_const.h>
41bdd1243dSDimitry Andric #include <__utility/exception_guard.h>
42bdd1243dSDimitry Andric #include <__utility/forward.h>
43bdd1243dSDimitry Andric #include <__utility/in_place.h>
44bdd1243dSDimitry Andric #include <__utility/move.h>
45bdd1243dSDimitry Andric #include <__utility/swap.h>
4606c3fb27SDimitry Andric #include <__verbose_abort>
47bdd1243dSDimitry Andric #include <initializer_list>
48bdd1243dSDimitry Andric 
49bdd1243dSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
50bdd1243dSDimitry Andric #  pragma GCC system_header
51bdd1243dSDimitry Andric #endif
52bdd1243dSDimitry Andric 
5306c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS
5406c3fb27SDimitry Andric #include <__undef_macros>
5506c3fb27SDimitry Andric 
56bdd1243dSDimitry Andric #if _LIBCPP_STD_VER >= 23
57bdd1243dSDimitry Andric 
58bdd1243dSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
59bdd1243dSDimitry Andric 
6006c3fb27SDimitry Andric template <class _Tp, class _Err>
6106c3fb27SDimitry Andric class expected;
6206c3fb27SDimitry Andric 
6306c3fb27SDimitry Andric template <class _Tp>
6406c3fb27SDimitry Andric struct __is_std_expected : false_type {};
6506c3fb27SDimitry Andric 
6606c3fb27SDimitry Andric template <class _Tp, class _Err>
6706c3fb27SDimitry Andric struct __is_std_expected<expected<_Tp, _Err>> : true_type {};
6806c3fb27SDimitry Andric 
6906c3fb27SDimitry Andric struct __expected_construct_in_place_from_invoke_tag {};
7006c3fb27SDimitry Andric struct __expected_construct_unexpected_from_invoke_tag {};
71bdd1243dSDimitry Andric 
72bdd1243dSDimitry Andric template <class _Err, class _Arg>
73bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) {
7406c3fb27SDimitry Andric #  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
75bdd1243dSDimitry Andric   throw bad_expected_access<_Err>(std::forward<_Arg>(__arg));
76bdd1243dSDimitry Andric #  else
77bdd1243dSDimitry Andric   (void)__arg;
7806c3fb27SDimitry Andric   _LIBCPP_VERBOSE_ABORT("bad_expected_access was thrown in -fno-exceptions mode");
79bdd1243dSDimitry Andric #  endif
80bdd1243dSDimitry Andric }
81bdd1243dSDimitry Andric 
827a6dacacSDimitry Andric // If parameter type `_Tp` of `__conditional_no_unique_address` is neither
837a6dacacSDimitry Andric // copyable nor movable, a constructor with this tag is provided. For that
847a6dacacSDimitry Andric // constructor, the user has to provide a function and arguments. The function
857a6dacacSDimitry Andric // must return an object of type `_Tp`. When the function is invoked by the
867a6dacacSDimitry Andric // constructor, guaranteed copy elision kicks in and the `_Tp` is constructed
877a6dacacSDimitry Andric // in place.
887a6dacacSDimitry Andric struct __conditional_no_unique_address_invoke_tag {};
897a6dacacSDimitry Andric 
907a6dacacSDimitry Andric // This class implements an object with `[[no_unique_address]]` conditionally applied to it,
917a6dacacSDimitry Andric // based on the value of `_NoUnique`.
927a6dacacSDimitry Andric //
937a6dacacSDimitry Andric // A member of this class must always have `[[no_unique_address]]` applied to
947a6dacacSDimitry Andric // it. Otherwise, the `[[no_unique_address]]` in the "`_NoUnique == true`" case
957a6dacacSDimitry Andric // would not have any effect. In the `false` case, the `__v` is not
967a6dacacSDimitry Andric // `[[no_unique_address]]`, so nullifies the effects of the "outer"
977a6dacacSDimitry Andric // `[[no_unique_address]]` regarding data layout.
987a6dacacSDimitry Andric //
997a6dacacSDimitry Andric // If we had a language feature, this class would basically be replaced by `[[no_unique_address(condition)]]`.
1007a6dacacSDimitry Andric template <bool _NoUnique, class _Tp>
1017a6dacacSDimitry Andric struct __conditional_no_unique_address;
1027a6dacacSDimitry Andric 
1037a6dacacSDimitry Andric template <class _Tp>
1047a6dacacSDimitry Andric struct __conditional_no_unique_address<true, _Tp> {
1057a6dacacSDimitry Andric   template <class... _Args>
1067a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(in_place_t, _Args&&... __args)
1077a6dacacSDimitry Andric       : __v(std::forward<_Args>(__args)...) {}
1087a6dacacSDimitry Andric 
1097a6dacacSDimitry Andric   template <class _Func, class... _Args>
1107a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(
1117a6dacacSDimitry Andric       __conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args)
1127a6dacacSDimitry Andric       : __v(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
1137a6dacacSDimitry Andric 
1147a6dacacSDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS _Tp __v;
1157a6dacacSDimitry Andric };
1167a6dacacSDimitry Andric 
1177a6dacacSDimitry Andric template <class _Tp>
1187a6dacacSDimitry Andric struct __conditional_no_unique_address<false, _Tp> {
1197a6dacacSDimitry Andric   template <class... _Args>
1207a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(in_place_t, _Args&&... __args)
1217a6dacacSDimitry Andric       : __v(std::forward<_Args>(__args)...) {}
1227a6dacacSDimitry Andric 
1237a6dacacSDimitry Andric   template <class _Func, class... _Args>
1247a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(
1257a6dacacSDimitry Andric       __conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args)
1267a6dacacSDimitry Andric       : __v(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
1277a6dacacSDimitry Andric 
1287a6dacacSDimitry Andric   _Tp __v;
1297a6dacacSDimitry Andric };
1307a6dacacSDimitry Andric 
1317a6dacacSDimitry Andric // This function returns whether the type `_Second` can be stuffed into the tail padding
1327a6dacacSDimitry Andric // of the `_First` type if both of them are given `[[no_unique_address]]`.
1337a6dacacSDimitry Andric template <class _First, class _Second>
1347a6dacacSDimitry Andric inline constexpr bool __fits_in_tail_padding = []() {
1357a6dacacSDimitry Andric   struct __x {
1367a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _First __first;
1377a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _Second __second;
1387a6dacacSDimitry Andric   };
1397a6dacacSDimitry Andric   return sizeof(__x) == sizeof(_First);
1407a6dacacSDimitry Andric }();
1417a6dacacSDimitry Andric 
1427a6dacacSDimitry Andric // This class implements the storage used by `std::expected`. We have a few
1437a6dacacSDimitry Andric // goals for this storage:
1447a6dacacSDimitry Andric // 1. Whenever the underlying {_Tp | _Unex} combination has free bytes in its
1457a6dacacSDimitry Andric //    tail padding, we should reuse it to store the bool discriminator of the
1467a6dacacSDimitry Andric //    expected, so as to save space.
1477a6dacacSDimitry Andric // 2. Whenever the `expected<_Tp, _Unex>` as a whole has free bytes in its tail
1487a6dacacSDimitry Andric //    padding, we should allow an object following the expected to be stored in
1497a6dacacSDimitry Andric //    its tail padding.
1507a6dacacSDimitry Andric // 3. However, we never want a user object (say `X`) that would follow an
1517a6dacacSDimitry Andric //    `expected<_Tp, _Unex>` to be stored in the padding bytes of the
1527a6dacacSDimitry Andric //    underlying {_Tp | _Unex} union, if any. That is because we use
1537a6dacacSDimitry Andric //    `construct_at` on that union, which would end up overwriting the `X`
1547a6dacacSDimitry Andric //    member if it is stored in the tail padding of the union.
1557a6dacacSDimitry Andric //
1567a6dacacSDimitry Andric // To achieve this, `__expected_base`'s logic is implemented in an inner
1577a6dacacSDimitry Andric // `__repr` class. `__expected_base` holds one `__repr` member which is
1587a6dacacSDimitry Andric // conditionally `[[no_unique_address]]`. The `__repr` class holds the
1597a6dacacSDimitry Andric // underlying {_Tp | _Unex} union and a boolean "has value" flag.
1607a6dacacSDimitry Andric //
1617a6dacacSDimitry Andric // Which one of the `__repr_`/`__union_` members is `[[no_unique_address]]`
1627a6dacacSDimitry Andric // depends on whether the "has value" boolean fits into the tail padding of
1637a6dacacSDimitry Andric // the underlying {_Tp | _Unex} union:
1647a6dacacSDimitry Andric //
1657a6dacacSDimitry Andric // - In case the "has value" bool fits into the tail padding of the union, the
1667a6dacacSDimitry Andric //   whole `__repr_` member is _not_ `[[no_unique_address]]` as it needs to be
1677a6dacacSDimitry Andric //   transparently replaced on `emplace()`/`swap()` etc.
1687a6dacacSDimitry Andric // - In case the "has value" bool does not fit into the tail padding of the
1697a6dacacSDimitry Andric //   union, only the union member must be transparently replaced (therefore is
1707a6dacacSDimitry Andric //   _not_ `[[no_unique_address]]`) and the "has value" flag must be adjusted
1717a6dacacSDimitry Andric //   manually.
1727a6dacacSDimitry Andric //
1737a6dacacSDimitry Andric // This way, the member that is transparently replaced on mutating operations
1747a6dacacSDimitry Andric // is never `[[no_unique_address]]`, satisfying the requirements from
1757a6dacacSDimitry Andric // "[basic.life]" in the standard.
1767a6dacacSDimitry Andric //
1777a6dacacSDimitry Andric // Stripped away of all superfluous elements, the layout of `__expected_base`
1787a6dacacSDimitry Andric // then looks like this:
1797a6dacacSDimitry Andric //
1807a6dacacSDimitry Andric //     template <class Tp, class Err>
1817a6dacacSDimitry Andric //     class expected_base {
1827a6dacacSDimitry Andric //       union union_t {
1837a6dacacSDimitry Andric //         [[no_unique_address]] Tp val;
1847a6dacacSDimitry Andric //         [[no_unique_address]] Err unex;
1857a6dacacSDimitry Andric //       };
1867a6dacacSDimitry Andric //
1877a6dacacSDimitry Andric //       static constexpr bool put_flag_in_tail                    = fits_in_tail_padding<union_t, bool>;
1887a6dacacSDimitry Andric //       static constexpr bool allow_reusing_expected_tail_padding = !put_flag_in_tail;
1897a6dacacSDimitry Andric //
1907a6dacacSDimitry Andric //       struct repr {
1917a6dacacSDimitry Andric //       private:
1927a6dacacSDimitry Andric //         // If "has value" fits into the tail, this should be
1937a6dacacSDimitry Andric //         // `[[no_unique_address]]`, otherwise not.
1947a6dacacSDimitry Andric //         [[no_unique_address]] conditional_no_unique_address<
1957a6dacacSDimitry Andric //             put_flag_in_tail,
1967a6dacacSDimitry Andric //             union_t>::type union_;
1977a6dacacSDimitry Andric //         [[no_unique_address]] bool has_val_;
1987a6dacacSDimitry Andric //       };
1997a6dacacSDimitry Andric //
2007a6dacacSDimitry Andric //     protected:
2017a6dacacSDimitry Andric //       // If "has value" fits into the tail, this must _not_ be
2027a6dacacSDimitry Andric //       // `[[no_unique_address]]` so that we fill out the
2037a6dacacSDimitry Andric //       // complete `expected` object.
2047a6dacacSDimitry Andric //       [[no_unique_address]] conditional_no_unique_address<
2057a6dacacSDimitry Andric //           allow_reusing_expected_tail_padding,
2067a6dacacSDimitry Andric //           repr>::type repr_;
2077a6dacacSDimitry Andric //     };
2087a6dacacSDimitry Andric //
209bdd1243dSDimitry Andric template <class _Tp, class _Err>
2107a6dacacSDimitry Andric class __expected_base {
2117a6dacacSDimitry Andric   // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
2127a6dacacSDimitry Andric   // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
2137a6dacacSDimitry Andric   // it's not clear that it's implementable, given that the function is allowed to clobber
2147a6dacacSDimitry Andric   // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
2157a6dacacSDimitry Andric   union __union_t {
2167a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = delete;
2177a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&)
2187a6dacacSDimitry Andric       requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
2197a6dacacSDimitry Andric                is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>)
2207a6dacacSDimitry Andric     = default;
2217a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) = delete;
2227a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&)
2237a6dacacSDimitry Andric       requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
2247a6dacacSDimitry Andric                is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)
2257a6dacacSDimitry Andric     = default;
2267a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(const __union_t&) = delete;
2277a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(__union_t&&)      = delete;
2287a6dacacSDimitry Andric 
2297a6dacacSDimitry Andric     template <class... _Args>
2307a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(in_place_t, _Args&&... __args)
2317a6dacacSDimitry Andric         : __val_(std::forward<_Args>(__args)...) {}
2327a6dacacSDimitry Andric 
2337a6dacacSDimitry Andric     template <class... _Args>
2347a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(unexpect_t, _Args&&... __args)
2357a6dacacSDimitry Andric         : __unex_(std::forward<_Args>(__args)...) {}
2367a6dacacSDimitry Andric 
2377a6dacacSDimitry Andric     template <class _Func, class... _Args>
2387a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
2397a6dacacSDimitry Andric         std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args)
2407a6dacacSDimitry Andric         : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
2417a6dacacSDimitry Andric 
2427a6dacacSDimitry Andric     template <class _Func, class... _Args>
2437a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
2447a6dacacSDimitry Andric         std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
2457a6dacacSDimitry Andric         : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
2467a6dacacSDimitry Andric 
2477a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
2487a6dacacSDimitry Andric       requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
2497a6dacacSDimitry Andric     = default;
2507a6dacacSDimitry Andric 
2517a6dacacSDimitry Andric     // __repr's destructor handles this
2527a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {}
2537a6dacacSDimitry Andric 
2547a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
2557a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
2567a6dacacSDimitry Andric   };
2577a6dacacSDimitry Andric 
2587a6dacacSDimitry Andric   static constexpr bool __put_flag_in_tail                    = __fits_in_tail_padding<__union_t, bool>;
2597a6dacacSDimitry Andric   static constexpr bool __allow_reusing_expected_tail_padding = !__put_flag_in_tail;
2607a6dacacSDimitry Andric 
2617a6dacacSDimitry Andric   struct __repr {
2627a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr() = delete;
2637a6dacacSDimitry Andric 
2647a6dacacSDimitry Andric     template <class... _Args>
2657a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(in_place_t __tag, _Args&&... __args)
2667a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(true) {}
2677a6dacacSDimitry Andric 
2687a6dacacSDimitry Andric     template <class... _Args>
2697a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(unexpect_t __tag, _Args&&... __args)
2707a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {}
2717a6dacacSDimitry Andric 
2727a6dacacSDimitry Andric     template <class... _Args>
2737a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_in_place_from_invoke_tag __tag,
2747a6dacacSDimitry Andric                                                     _Args&&... __args)
2757a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(true) {}
2767a6dacacSDimitry Andric 
2777a6dacacSDimitry Andric     template <class... _Args>
2787a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_unexpected_from_invoke_tag __tag,
2797a6dacacSDimitry Andric                                                     _Args&&... __args)
2807a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {}
2817a6dacacSDimitry Andric 
2827a6dacacSDimitry Andric     // The return value of `__make_union` must be constructed in place in the
2837a6dacacSDimitry Andric     // `__v` member of `__union_`, relying on guaranteed copy elision. To do
2847a6dacacSDimitry Andric     // this, the `__conditional_no_unique_address_invoke_tag` constructor is
2857a6dacacSDimitry Andric     // called with a lambda that is immediately called inside
2867a6dacacSDimitry Andric     // `__conditional_no_unique_address`'s constructor.
2877a6dacacSDimitry Andric     template <class _OtherUnion>
2887a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(bool __has_val, _OtherUnion&& __other)
2897a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
2907a6dacacSDimitry Andric         : __union_(__conditional_no_unique_address_invoke_tag{},
2917a6dacacSDimitry Andric                    [&] { return __make_union(__has_val, std::forward<_OtherUnion>(__other)); }),
2927a6dacacSDimitry Andric           __has_val_(__has_val) {}
2937a6dacacSDimitry Andric 
2947a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) = delete;
2957a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&)
2967a6dacacSDimitry Andric       requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
2977a6dacacSDimitry Andric                is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>)
2987a6dacacSDimitry Andric     = default;
2997a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) = delete;
3007a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&)
3017a6dacacSDimitry Andric       requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
3027a6dacacSDimitry Andric                is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)
3037a6dacacSDimitry Andric     = default;
3047a6dacacSDimitry Andric 
3057a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(const __repr&) = delete;
3067a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(__repr&&)      = delete;
3077a6dacacSDimitry Andric 
3087a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__repr()
3097a6dacacSDimitry Andric       requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)
3107a6dacacSDimitry Andric     = default;
3117a6dacacSDimitry Andric 
3127a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__repr()
3137a6dacacSDimitry Andric       requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
3147a6dacacSDimitry Andric     {
3157a6dacacSDimitry Andric       __destroy_union_member();
3167a6dacacSDimitry Andric     }
3177a6dacacSDimitry Andric 
3187a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union()
3197a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding &&
3207a6dacacSDimitry Andric                (is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>))
3217a6dacacSDimitry Andric     {
3227a6dacacSDimitry Andric       // Note: Since the destructor of the union is trivial, this does nothing
3237a6dacacSDimitry Andric       // except to end the lifetime of the union.
3247a6dacacSDimitry Andric       std::destroy_at(&__union_.__v);
3257a6dacacSDimitry Andric     }
3267a6dacacSDimitry Andric 
3277a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union()
3287a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding &&
3297a6dacacSDimitry Andric                (!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>))
3307a6dacacSDimitry Andric     {
3317a6dacacSDimitry Andric       __destroy_union_member();
3327a6dacacSDimitry Andric       std::destroy_at(&__union_.__v);
3337a6dacacSDimitry Andric     }
3347a6dacacSDimitry Andric 
3357a6dacacSDimitry Andric     template <class... _Args>
3367a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(in_place_t, _Args&&... __args)
3377a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
3387a6dacacSDimitry Andric     {
3397a6dacacSDimitry Andric       std::construct_at(&__union_.__v, in_place, std::forward<_Args>(__args)...);
3407a6dacacSDimitry Andric       __has_val_ = true;
3417a6dacacSDimitry Andric     }
3427a6dacacSDimitry Andric 
3437a6dacacSDimitry Andric     template <class... _Args>
3447a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(unexpect_t, _Args&&... __args)
3457a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
3467a6dacacSDimitry Andric     {
3477a6dacacSDimitry Andric       std::construct_at(&__union_.__v, unexpect, std::forward<_Args>(__args)...);
3487a6dacacSDimitry Andric       __has_val_ = false;
3497a6dacacSDimitry Andric     }
3507a6dacacSDimitry Andric 
3517a6dacacSDimitry Andric   private:
3527a6dacacSDimitry Andric     template <class, class>
3537a6dacacSDimitry Andric     friend class __expected_base;
3547a6dacacSDimitry Andric 
3557a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union_member()
3567a6dacacSDimitry Andric       requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)
3577a6dacacSDimitry Andric     {
3587a6dacacSDimitry Andric       if (__has_val_) {
3597a6dacacSDimitry Andric         std::destroy_at(std::addressof(__union_.__v.__val_));
3607a6dacacSDimitry Andric       } else {
3617a6dacacSDimitry Andric         std::destroy_at(std::addressof(__union_.__v.__unex_));
3627a6dacacSDimitry Andric       }
3637a6dacacSDimitry Andric     }
3647a6dacacSDimitry Andric 
3657a6dacacSDimitry Andric     template <class _OtherUnion>
3667a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI static constexpr __union_t __make_union(bool __has_val, _OtherUnion&& __other)
3677a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
3687a6dacacSDimitry Andric     {
3697a6dacacSDimitry Andric       if (__has_val)
3707a6dacacSDimitry Andric         return __union_t(in_place, std::forward<_OtherUnion>(__other).__val_);
3717a6dacacSDimitry Andric       else
3727a6dacacSDimitry Andric         return __union_t(unexpect, std::forward<_OtherUnion>(__other).__unex_);
3737a6dacacSDimitry Andric     }
3747a6dacacSDimitry Andric 
3757a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__put_flag_in_tail, __union_t> __union_;
3767a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS bool __has_val_;
3777a6dacacSDimitry Andric   };
3787a6dacacSDimitry Andric 
3797a6dacacSDimitry Andric   template <class _OtherUnion>
3807a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr __repr __make_repr(bool __has_val, _OtherUnion&& __other)
3817a6dacacSDimitry Andric     requires(__put_flag_in_tail)
3827a6dacacSDimitry Andric   {
3837a6dacacSDimitry Andric     if (__has_val)
3847a6dacacSDimitry Andric       return __repr(in_place, std::forward<_OtherUnion>(__other).__val_);
3857a6dacacSDimitry Andric     else
3867a6dacacSDimitry Andric       return __repr(unexpect, std::forward<_OtherUnion>(__other).__unex_);
3877a6dacacSDimitry Andric   }
3887a6dacacSDimitry Andric 
3897a6dacacSDimitry Andric protected:
3907a6dacacSDimitry Andric   template <class... _Args>
3917a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_base(_Args&&... __args)
3927a6dacacSDimitry Andric       : __repr_(in_place, std::forward<_Args>(__args)...) {}
3937a6dacacSDimitry Andric 
3947a6dacacSDimitry Andric   // In case we copy/move construct from another `expected` we need to create
3957a6dacacSDimitry Andric   // our `expected` so that it either has a value or not, depending on the "has
3967a6dacacSDimitry Andric   // value" flag of the other `expected`. To do this without falling back on
3977a6dacacSDimitry Andric   // `std::construct_at` we rely on guaranteed copy elision using two helper
3987a6dacacSDimitry Andric   // functions `__make_repr` and `__make_union`. There have to be two since
3997a6dacacSDimitry Andric   // there are two data layouts with different members being
4007a6dacacSDimitry Andric   // `[[no_unique_address]]`. GCC (as of version 13) does not do guaranteed
4017a6dacacSDimitry Andric   // copy elision when initializing `[[no_unique_address]]` members. The two
4027a6dacacSDimitry Andric   // cases are:
4037a6dacacSDimitry Andric   //
4047a6dacacSDimitry Andric   // - `__make_repr`: This is used when the "has value" flag lives in the tail
4057a6dacacSDimitry Andric   //   of the union. In this case, the `__repr` member is _not_
4067a6dacacSDimitry Andric   //   `[[no_unique_address]]`.
4077a6dacacSDimitry Andric   // - `__make_union`: When the "has value" flag does _not_ fit in the tail of
4087a6dacacSDimitry Andric   //   the union, the `__repr` member is `[[no_unique_address]]` and the union
4097a6dacacSDimitry Andric   //   is not.
4107a6dacacSDimitry Andric   //
4117a6dacacSDimitry Andric   // This constructor "catches" the first case and leaves the second case to
4127a6dacacSDimitry Andric   // `__union_t`, its constructors and `__make_union`.
4137a6dacacSDimitry Andric   template <class _OtherUnion>
4147a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_base(bool __has_val, _OtherUnion&& __other)
4157a6dacacSDimitry Andric     requires(__put_flag_in_tail)
4167a6dacacSDimitry Andric       : __repr_(__conditional_no_unique_address_invoke_tag{},
4177a6dacacSDimitry Andric                 [&] { return __make_repr(__has_val, std::forward<_OtherUnion>(__other)); }) {}
4187a6dacacSDimitry Andric 
4197a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __destroy() {
4207a6dacacSDimitry Andric     if constexpr (__put_flag_in_tail)
4217a6dacacSDimitry Andric       std::destroy_at(&__repr_.__v);
4227a6dacacSDimitry Andric     else
4237a6dacacSDimitry Andric       __repr_.__v.__destroy_union();
4247a6dacacSDimitry Andric   }
4257a6dacacSDimitry Andric 
4267a6dacacSDimitry Andric   template <class _Tag, class... _Args>
4277a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __construct(_Tag __tag, _Args&&... __args) {
4287a6dacacSDimitry Andric     if constexpr (__put_flag_in_tail)
4297a6dacacSDimitry Andric       std::construct_at(&__repr_.__v, __tag, std::forward<_Args>(__args)...);
4307a6dacacSDimitry Andric     else
4317a6dacacSDimitry Andric       __repr_.__v.__construct_union(__tag, std::forward<_Args>(__args)...);
4327a6dacacSDimitry Andric   }
4337a6dacacSDimitry Andric 
4347a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool __has_val() const { return __repr_.__v.__has_val_; }
4357a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr __union_t& __union() { return __repr_.__v.__union_.__v; }
4367a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const __union_t& __union() const { return __repr_.__v.__union_.__v; }
4377a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& __val() { return __repr_.__v.__union_.__v.__val_; }
4387a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& __val() const { return __repr_.__v.__union_.__v.__val_; }
4397a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& __unex() { return __repr_.__v.__union_.__v.__unex_; }
4407a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& __unex() const { return __repr_.__v.__union_.__v.__unex_; }
4417a6dacacSDimitry Andric 
4427a6dacacSDimitry Andric private:
4437a6dacacSDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__allow_reusing_expected_tail_padding, __repr> __repr_;
4447a6dacacSDimitry Andric };
4457a6dacacSDimitry Andric 
4467a6dacacSDimitry Andric template <class _Tp, class _Err>
4477a6dacacSDimitry Andric class expected : private __expected_base<_Tp, _Err> {
448cb14a3feSDimitry Andric   static_assert(!is_reference_v<_Tp> && !is_function_v<_Tp> && !is_same_v<remove_cv_t<_Tp>, in_place_t> &&
449cb14a3feSDimitry Andric                     !is_same_v<remove_cv_t<_Tp>, unexpect_t> && !__is_std_unexpected<remove_cv_t<_Tp>>::value &&
450cb14a3feSDimitry Andric                     __valid_std_unexpected<_Err>::value,
451bdd1243dSDimitry Andric                 "[expected.object.general] A program that instantiates the definition of template expected<T, E> for a "
452bdd1243dSDimitry Andric                 "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a "
453bdd1243dSDimitry Andric                 "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the "
454bdd1243dSDimitry Andric                 "definition of the template expected<T, E> with a type for the E parameter that is not a valid "
455bdd1243dSDimitry Andric                 "template argument for unexpected is ill-formed.");
456bdd1243dSDimitry Andric 
457bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
458bdd1243dSDimitry Andric   friend class expected;
459bdd1243dSDimitry Andric 
4607a6dacacSDimitry Andric   using __base = __expected_base<_Tp, _Err>;
4617a6dacacSDimitry Andric 
462bdd1243dSDimitry Andric public:
463bdd1243dSDimitry Andric   using value_type      = _Tp;
464bdd1243dSDimitry Andric   using error_type      = _Err;
465bdd1243dSDimitry Andric   using unexpected_type = unexpected<_Err>;
466bdd1243dSDimitry Andric 
467*0fca6ea1SDimitry Andric   using __trivially_relocatable =
468*0fca6ea1SDimitry Andric       __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value && __libcpp_is_trivially_relocatable<_Err>::value,
469*0fca6ea1SDimitry Andric                       expected,
470*0fca6ea1SDimitry Andric                       void>;
471*0fca6ea1SDimitry Andric 
472bdd1243dSDimitry Andric   template <class _Up>
473bdd1243dSDimitry Andric   using rebind = expected<_Up, error_type>;
474bdd1243dSDimitry Andric 
475bdd1243dSDimitry Andric   // [expected.object.ctor], constructors
476cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened
477bdd1243dSDimitry Andric     requires is_default_constructible_v<_Tp>
4787a6dacacSDimitry Andric       : __base(in_place) {}
479bdd1243dSDimitry Andric 
480bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
481bdd1243dSDimitry Andric 
482bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
483cb14a3feSDimitry Andric     requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Tp> &&
484bdd1243dSDimitry Andric              is_trivially_copy_constructible_v<_Err>)
485bdd1243dSDimitry Andric   = default;
486bdd1243dSDimitry Andric 
487cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other) noexcept(
488cb14a3feSDimitry Andric       is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened
489bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
490bdd1243dSDimitry Andric              !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>))
4917a6dacacSDimitry Andric       : __base(__other.__has_val(), __other.__union()) {}
492bdd1243dSDimitry Andric 
493bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
494cb14a3feSDimitry Andric     requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Tp> &&
495cb14a3feSDimitry Andric              is_trivially_move_constructible_v<_Err>)
496bdd1243dSDimitry Andric   = default;
497bdd1243dSDimitry Andric 
498cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other) noexcept(
499cb14a3feSDimitry Andric       is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>)
500bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> &&
501bdd1243dSDimitry Andric              !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>))
5027a6dacacSDimitry Andric       : __base(__other.__has_val(), std::move(__other.__union())) {}
503bdd1243dSDimitry Andric 
504bdd1243dSDimitry Andric private:
505bdd1243dSDimitry Andric   template <class _Up, class _OtherErr, class _UfQual, class _OtherErrQual>
506bdd1243dSDimitry Andric   using __can_convert =
507bdd1243dSDimitry Andric       _And< is_constructible<_Tp, _UfQual>,
508bdd1243dSDimitry Andric             is_constructible<_Err, _OtherErrQual>,
5095f757f3fSDimitry Andric             _If<_Not<is_same<remove_cv_t<_Tp>, bool>>::value,
510*0fca6ea1SDimitry Andric                 _And<
511*0fca6ea1SDimitry Andric                       _Not<_And<is_same<_Tp, _Up>, is_same<_Err, _OtherErr>>>, // use the copy constructor instead, see #92676
512*0fca6ea1SDimitry Andric                       _Not<is_constructible<_Tp, expected<_Up, _OtherErr>&>>,
513bdd1243dSDimitry Andric                       _Not<is_constructible<_Tp, expected<_Up, _OtherErr>>>,
514bdd1243dSDimitry Andric                       _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>&>>,
515bdd1243dSDimitry Andric                       _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>>>,
516bdd1243dSDimitry Andric                       _Not<is_convertible<expected<_Up, _OtherErr>&, _Tp>>,
517bdd1243dSDimitry Andric                       _Not<is_convertible<expected<_Up, _OtherErr>&&, _Tp>>,
518bdd1243dSDimitry Andric                       _Not<is_convertible<const expected<_Up, _OtherErr>&, _Tp>>,
5195f757f3fSDimitry Andric                       _Not<is_convertible<const expected<_Up, _OtherErr>&&, _Tp>>>,
5205f757f3fSDimitry Andric                 true_type>,
521bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
522bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
523bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
524bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >;
525bdd1243dSDimitry Andric 
52606c3fb27SDimitry Andric   template <class _Func, class... _Args>
52706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
52806c3fb27SDimitry Andric       std::__expected_construct_in_place_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
5297a6dacacSDimitry Andric       : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {}
53006c3fb27SDimitry Andric 
53106c3fb27SDimitry Andric   template <class _Func, class... _Args>
53206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
53306c3fb27SDimitry Andric       std::__expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
5347a6dacacSDimitry Andric       : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {}
535bdd1243dSDimitry Andric 
536bdd1243dSDimitry Andric public:
537bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
538bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value
539bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _Up&, _Tp> ||
540bdd1243dSDimitry Andric                                            !is_convertible_v<const _OtherErr&, _Err>)
541cb14a3feSDimitry Andric       expected(const expected<_Up, _OtherErr>& __other) noexcept(
542cb14a3feSDimitry Andric           is_nothrow_constructible_v<_Tp, const _Up&> &&
543bdd1243dSDimitry Andric           is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
5447a6dacacSDimitry Andric       : __base(__other.__has_val(), __other.__union()) {}
545bdd1243dSDimitry Andric 
546bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
547bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value
548bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>)
549cb14a3feSDimitry Andric       expected(expected<_Up, _OtherErr>&& __other) noexcept(
550cb14a3feSDimitry Andric           is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
5517a6dacacSDimitry Andric       : __base(__other.__has_val(), std::move(__other.__union())) {}
552bdd1243dSDimitry Andric 
553bdd1243dSDimitry Andric   template <class _Up = _Tp>
554bdd1243dSDimitry Andric     requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> &&
5555f757f3fSDimitry Andric              is_constructible_v<_Tp, _Up> && !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
5565f757f3fSDimitry Andric              (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_expected<remove_cvref_t<_Up>>::value))
557bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>)
558b121cb00SDimitry Andric       expected(_Up&& __u) noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened
5597a6dacacSDimitry Andric       : __base(in_place, std::forward<_Up>(__u)) {}
560bdd1243dSDimitry Andric 
561bdd1243dSDimitry Andric   template <class _OtherErr>
562bdd1243dSDimitry Andric     requires is_constructible_v<_Err, const _OtherErr&>
563cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>) expected(
564cb14a3feSDimitry Andric       const unexpected<_OtherErr>& __unex) noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
5657a6dacacSDimitry Andric       : __base(unexpect, __unex.error()) {}
566bdd1243dSDimitry Andric 
567bdd1243dSDimitry Andric   template <class _OtherErr>
568bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _OtherErr>
569bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
570cb14a3feSDimitry Andric       expected(unexpected<_OtherErr>&& __unex) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
5717a6dacacSDimitry Andric       : __base(unexpect, std::move(__unex.error())) {}
572bdd1243dSDimitry Andric 
573bdd1243dSDimitry Andric   template <class... _Args>
574bdd1243dSDimitry Andric     requires is_constructible_v<_Tp, _Args...>
575cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args) noexcept(
576cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Tp, _Args...>) // strengthened
5777a6dacacSDimitry Andric       : __base(in_place, std::forward<_Args>(__args)...) {}
578bdd1243dSDimitry Andric 
579bdd1243dSDimitry Andric   template <class _Up, class... _Args>
580bdd1243dSDimitry Andric     requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... >
581cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) noexcept(
582cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened
5837a6dacacSDimitry Andric       : __base(in_place, __il, std::forward<_Args>(__args)...) {}
584bdd1243dSDimitry Andric 
585bdd1243dSDimitry Andric   template <class... _Args>
586bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _Args...>
587cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) noexcept(
588cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Err, _Args...>) // strengthened
5897a6dacacSDimitry Andric       : __base(unexpect, std::forward<_Args>(__args)...) {}
590bdd1243dSDimitry Andric 
591bdd1243dSDimitry Andric   template <class _Up, class... _Args>
592bdd1243dSDimitry Andric     requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
593cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) noexcept(
594cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
5957a6dacacSDimitry Andric       : __base(unexpect, __il, std::forward<_Args>(__args)...) {}
596bdd1243dSDimitry Andric 
597bdd1243dSDimitry Andric   // [expected.object.dtor], destructor
598bdd1243dSDimitry Andric 
5997a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected() = default;
600bdd1243dSDimitry Andric 
601bdd1243dSDimitry Andric private:
6027a6dacacSDimitry Andric   template <class _Tag, class _OtherTag, class _T1, class _T2, class... _Args>
6037a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(_T2& __oldval, _Args&&... __args) {
604bdd1243dSDimitry Andric     if constexpr (is_nothrow_constructible_v<_T1, _Args...>) {
6057a6dacacSDimitry Andric       this->__destroy();
6067a6dacacSDimitry Andric       this->__construct(_Tag{}, std::forward<_Args>(__args)...);
607bdd1243dSDimitry Andric     } else if constexpr (is_nothrow_move_constructible_v<_T1>) {
608bdd1243dSDimitry Andric       _T1 __tmp(std::forward<_Args>(__args)...);
6097a6dacacSDimitry Andric       this->__destroy();
6107a6dacacSDimitry Andric       this->__construct(_Tag{}, std::move(__tmp));
611bdd1243dSDimitry Andric     } else {
612bdd1243dSDimitry Andric       static_assert(
613bdd1243dSDimitry Andric           is_nothrow_move_constructible_v<_T2>,
614bdd1243dSDimitry Andric           "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can "
615bdd1243dSDimitry Andric           "be reverted to the previous state in case an exception is thrown during the assignment.");
616bdd1243dSDimitry Andric       _T2 __tmp(std::move(__oldval));
6177a6dacacSDimitry Andric       this->__destroy();
6187a6dacacSDimitry Andric       auto __trans = std::__make_exception_guard([&] { this->__construct(_OtherTag{}, std::move(__tmp)); });
6197a6dacacSDimitry Andric       this->__construct(_Tag{}, std::forward<_Args>(__args)...);
620bdd1243dSDimitry Andric       __trans.__complete();
621bdd1243dSDimitry Andric     }
622bdd1243dSDimitry Andric   }
623bdd1243dSDimitry Andric 
624bdd1243dSDimitry Andric public:
625bdd1243dSDimitry Andric   // [expected.object.assign], assignment
626bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
627bdd1243dSDimitry Andric 
628cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) noexcept(
629cb14a3feSDimitry Andric       is_nothrow_copy_assignable_v<_Tp> && is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_assignable_v<_Err> &&
630bdd1243dSDimitry Andric       is_nothrow_copy_constructible_v<_Err>) // strengthened
631cb14a3feSDimitry Andric     requires(is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp> && is_copy_assignable_v<_Err> &&
632bdd1243dSDimitry Andric              is_copy_constructible_v<_Err> &&
633cb14a3feSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>))
634bdd1243dSDimitry Andric   {
6357a6dacacSDimitry Andric     if (this->__has_val() && __rhs.__has_val()) {
6367a6dacacSDimitry Andric       this->__val() = __rhs.__val();
6377a6dacacSDimitry Andric     } else if (this->__has_val()) {
6387a6dacacSDimitry Andric       __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), __rhs.__unex());
6397a6dacacSDimitry Andric     } else if (__rhs.__has_val()) {
6407a6dacacSDimitry Andric       __reinit_expected<in_place_t, unexpect_t, _Tp, _Err>(this->__unex(), __rhs.__val());
641bdd1243dSDimitry Andric     } else {
6427a6dacacSDimitry Andric       this->__unex() = __rhs.__unex();
643bdd1243dSDimitry Andric     }
644bdd1243dSDimitry Andric     return *this;
645bdd1243dSDimitry Andric   }
646bdd1243dSDimitry Andric 
647cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected&
648cb14a3feSDimitry Andric   operator=(expected&& __rhs) noexcept(is_nothrow_move_assignable_v<_Tp> && is_nothrow_move_constructible_v<_Tp> &&
649cb14a3feSDimitry Andric                                        is_nothrow_move_assignable_v<_Err> && is_nothrow_move_constructible_v<_Err>)
650cb14a3feSDimitry Andric     requires(is_move_constructible_v<_Tp> && is_move_assignable_v<_Tp> && is_move_constructible_v<_Err> &&
651bdd1243dSDimitry Andric              is_move_assignable_v<_Err> &&
652cb14a3feSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>))
653bdd1243dSDimitry Andric   {
6547a6dacacSDimitry Andric     if (this->__has_val() && __rhs.__has_val()) {
6557a6dacacSDimitry Andric       this->__val() = std::move(__rhs.__val());
6567a6dacacSDimitry Andric     } else if (this->__has_val()) {
6577a6dacacSDimitry Andric       __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), std::move(__rhs.__unex()));
6587a6dacacSDimitry Andric     } else if (__rhs.__has_val()) {
6597a6dacacSDimitry Andric       __reinit_expected<in_place_t, unexpect_t, _Tp, _Err>(this->__unex(), std::move(__rhs.__val()));
660bdd1243dSDimitry Andric     } else {
6617a6dacacSDimitry Andric       this->__unex() = std::move(__rhs.__unex());
662bdd1243dSDimitry Andric     }
663bdd1243dSDimitry Andric     return *this;
664bdd1243dSDimitry Andric   }
665bdd1243dSDimitry Andric 
666bdd1243dSDimitry Andric   template <class _Up = _Tp>
667bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v)
668cb14a3feSDimitry Andric     requires(!is_same_v<expected, remove_cvref_t<_Up>> && !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
669cb14a3feSDimitry Andric              is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up> &&
670cb14a3feSDimitry Andric              (is_nothrow_constructible_v<_Tp, _Up> || is_nothrow_move_constructible_v<_Tp> ||
671bdd1243dSDimitry Andric               is_nothrow_move_constructible_v<_Err>))
672bdd1243dSDimitry Andric   {
6737a6dacacSDimitry Andric     if (this->__has_val()) {
6747a6dacacSDimitry Andric       this->__val() = std::forward<_Up>(__v);
675bdd1243dSDimitry Andric     } else {
6767a6dacacSDimitry Andric       __reinit_expected<in_place_t, unexpect_t, _Tp, _Err>(this->__unex(), std::forward<_Up>(__v));
677bdd1243dSDimitry Andric     }
678bdd1243dSDimitry Andric     return *this;
679bdd1243dSDimitry Andric   }
680bdd1243dSDimitry Andric 
681bdd1243dSDimitry Andric private:
682bdd1243dSDimitry Andric   template <class _OtherErrQual>
683bdd1243dSDimitry Andric   static constexpr bool __can_assign_from_unexpected =
684bdd1243dSDimitry Andric       _And< is_constructible<_Err, _OtherErrQual>,
685bdd1243dSDimitry Andric             is_assignable<_Err&, _OtherErrQual>,
686bdd1243dSDimitry Andric             _Lazy<_Or,
687bdd1243dSDimitry Andric                   is_nothrow_constructible<_Err, _OtherErrQual>,
688bdd1243dSDimitry Andric                   is_nothrow_move_constructible<_Tp>,
689bdd1243dSDimitry Andric                   is_nothrow_move_constructible<_Err>> >::value;
690bdd1243dSDimitry Andric 
691bdd1243dSDimitry Andric public:
692bdd1243dSDimitry Andric   template <class _OtherErr>
693bdd1243dSDimitry Andric     requires(__can_assign_from_unexpected<const _OtherErr&>)
694bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
6957a6dacacSDimitry Andric     if (this->__has_val()) {
6967a6dacacSDimitry Andric       __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), __un.error());
697bdd1243dSDimitry Andric     } else {
6987a6dacacSDimitry Andric       this->__unex() = __un.error();
699bdd1243dSDimitry Andric     }
700bdd1243dSDimitry Andric     return *this;
701bdd1243dSDimitry Andric   }
702bdd1243dSDimitry Andric 
703bdd1243dSDimitry Andric   template <class _OtherErr>
704bdd1243dSDimitry Andric     requires(__can_assign_from_unexpected<_OtherErr>)
705bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
7067a6dacacSDimitry Andric     if (this->__has_val()) {
7077a6dacacSDimitry Andric       __reinit_expected<unexpect_t, in_place_t, _Err, _Tp>(this->__val(), std::move(__un.error()));
708bdd1243dSDimitry Andric     } else {
7097a6dacacSDimitry Andric       this->__unex() = std::move(__un.error());
710bdd1243dSDimitry Andric     }
711bdd1243dSDimitry Andric     return *this;
712bdd1243dSDimitry Andric   }
713bdd1243dSDimitry Andric 
714bdd1243dSDimitry Andric   template <class... _Args>
715bdd1243dSDimitry Andric     requires is_nothrow_constructible_v<_Tp, _Args...>
716bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept {
7177a6dacacSDimitry Andric     this->__destroy();
7187a6dacacSDimitry Andric     this->__construct(in_place, std::forward<_Args>(__args)...);
7197a6dacacSDimitry Andric     return this->__val();
720bdd1243dSDimitry Andric   }
721bdd1243dSDimitry Andric 
722bdd1243dSDimitry Andric   template <class _Up, class... _Args>
723bdd1243dSDimitry Andric     requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
724bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept {
7257a6dacacSDimitry Andric     this->__destroy();
7267a6dacacSDimitry Andric     this->__construct(in_place, __il, std::forward<_Args>(__args)...);
7277a6dacacSDimitry Andric     return this->__val();
728bdd1243dSDimitry Andric   }
729bdd1243dSDimitry Andric 
730bdd1243dSDimitry Andric public:
731bdd1243dSDimitry Andric   // [expected.object.swap], swap
732cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void
733cb14a3feSDimitry Andric   swap(expected& __rhs) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp> &&
734cb14a3feSDimitry Andric                                  is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
735cb14a3feSDimitry Andric     requires(is_swappable_v<_Tp> && is_swappable_v<_Err> && is_move_constructible_v<_Tp> &&
736bdd1243dSDimitry Andric              is_move_constructible_v<_Err> &&
737cb14a3feSDimitry Andric              (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>))
738bdd1243dSDimitry Andric   {
7397a6dacacSDimitry Andric     auto __swap_val_unex_impl = [](expected& __with_val, expected& __with_err) {
740bdd1243dSDimitry Andric       if constexpr (is_nothrow_move_constructible_v<_Err>) {
7417a6dacacSDimitry Andric         _Err __tmp(std::move(__with_err.__unex()));
7427a6dacacSDimitry Andric         __with_err.__destroy();
7437a6dacacSDimitry Andric         auto __trans = std::__make_exception_guard([&] { __with_err.__construct(unexpect, std::move(__tmp)); });
7447a6dacacSDimitry Andric         __with_err.__construct(in_place, std::move(__with_val.__val()));
745bdd1243dSDimitry Andric         __trans.__complete();
7467a6dacacSDimitry Andric         __with_val.__destroy();
7477a6dacacSDimitry Andric         __with_val.__construct(unexpect, std::move(__tmp));
748bdd1243dSDimitry Andric       } else {
749bdd1243dSDimitry Andric         static_assert(is_nothrow_move_constructible_v<_Tp>,
750bdd1243dSDimitry Andric                       "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so "
751bdd1243dSDimitry Andric                       "that it can be reverted to the previous state in case an exception is thrown during swap.");
7527a6dacacSDimitry Andric         _Tp __tmp(std::move(__with_val.__val()));
7537a6dacacSDimitry Andric         __with_val.__destroy();
7547a6dacacSDimitry Andric         auto __trans = std::__make_exception_guard([&] { __with_val.__construct(in_place, std::move(__tmp)); });
7557a6dacacSDimitry Andric         __with_val.__construct(unexpect, std::move(__with_err.__unex()));
756bdd1243dSDimitry Andric         __trans.__complete();
7577a6dacacSDimitry Andric         __with_err.__destroy();
7587a6dacacSDimitry Andric         __with_err.__construct(in_place, std::move(__tmp));
759bdd1243dSDimitry Andric       }
760bdd1243dSDimitry Andric     };
761bdd1243dSDimitry Andric 
7627a6dacacSDimitry Andric     if (this->__has_val()) {
7637a6dacacSDimitry Andric       if (__rhs.__has_val()) {
764bdd1243dSDimitry Andric         using std::swap;
7657a6dacacSDimitry Andric         swap(this->__val(), __rhs.__val());
766bdd1243dSDimitry Andric       } else {
767bdd1243dSDimitry Andric         __swap_val_unex_impl(*this, __rhs);
768bdd1243dSDimitry Andric       }
769bdd1243dSDimitry Andric     } else {
7707a6dacacSDimitry Andric       if (__rhs.__has_val()) {
771bdd1243dSDimitry Andric         __swap_val_unex_impl(__rhs, *this);
772bdd1243dSDimitry Andric       } else {
773bdd1243dSDimitry Andric         using std::swap;
7747a6dacacSDimitry Andric         swap(this->__unex(), __rhs.__unex());
775bdd1243dSDimitry Andric       }
776bdd1243dSDimitry Andric     }
777bdd1243dSDimitry Andric   }
778bdd1243dSDimitry Andric 
779cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) noexcept(noexcept(__x.swap(__y)))
780bdd1243dSDimitry Andric     requires requires { __x.swap(__y); }
781bdd1243dSDimitry Andric   {
782bdd1243dSDimitry Andric     __x.swap(__y);
783bdd1243dSDimitry Andric   }
784bdd1243dSDimitry Andric 
785bdd1243dSDimitry Andric   // [expected.object.obs], observers
786bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept {
7877a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
7887a6dacacSDimitry Andric         this->__has_val(), "expected::operator-> requires the expected to contain a value");
7897a6dacacSDimitry Andric     return std::addressof(this->__val());
790bdd1243dSDimitry Andric   }
791bdd1243dSDimitry Andric 
792bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept {
7937a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
7947a6dacacSDimitry Andric         this->__has_val(), "expected::operator-> requires the expected to contain a value");
7957a6dacacSDimitry Andric     return std::addressof(this->__val());
796bdd1243dSDimitry Andric   }
797bdd1243dSDimitry Andric 
798bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
7997a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
8007a6dacacSDimitry Andric         this->__has_val(), "expected::operator* requires the expected to contain a value");
8017a6dacacSDimitry Andric     return this->__val();
802bdd1243dSDimitry Andric   }
803bdd1243dSDimitry Andric 
804bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
8057a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
8067a6dacacSDimitry Andric         this->__has_val(), "expected::operator* requires the expected to contain a value");
8077a6dacacSDimitry Andric     return this->__val();
808bdd1243dSDimitry Andric   }
809bdd1243dSDimitry Andric 
810bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
8117a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
8127a6dacacSDimitry Andric         this->__has_val(), "expected::operator* requires the expected to contain a value");
8137a6dacacSDimitry Andric     return std::move(this->__val());
814bdd1243dSDimitry Andric   }
815bdd1243dSDimitry Andric 
816bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
8177a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
8187a6dacacSDimitry Andric         this->__has_val(), "expected::operator* requires the expected to contain a value");
8197a6dacacSDimitry Andric     return std::move(this->__val());
820bdd1243dSDimitry Andric   }
821bdd1243dSDimitry Andric 
8227a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return this->__has_val(); }
823bdd1243dSDimitry Andric 
8247a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); }
825bdd1243dSDimitry Andric 
826bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& {
82706c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
8287a6dacacSDimitry Andric     if (!this->__has_val()) {
82906c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::as_const(error()));
830bdd1243dSDimitry Andric     }
8317a6dacacSDimitry Andric     return this->__val();
832bdd1243dSDimitry Andric   }
833bdd1243dSDimitry Andric 
834bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
83506c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
8367a6dacacSDimitry Andric     if (!this->__has_val()) {
83706c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::as_const(error()));
838bdd1243dSDimitry Andric     }
8397a6dacacSDimitry Andric     return this->__val();
840bdd1243dSDimitry Andric   }
841bdd1243dSDimitry Andric 
842bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& {
84306c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
84406c3fb27SDimitry Andric                   "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
8457a6dacacSDimitry Andric     if (!this->__has_val()) {
84606c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::move(error()));
847bdd1243dSDimitry Andric     }
8487a6dacacSDimitry Andric     return std::move(this->__val());
849bdd1243dSDimitry Andric   }
850bdd1243dSDimitry Andric 
851bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
85206c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>,
85306c3fb27SDimitry Andric                   "error_type has to be both copy constructible and constructible from decltype(std::move(error()))");
8547a6dacacSDimitry Andric     if (!this->__has_val()) {
85506c3fb27SDimitry Andric       std::__throw_bad_expected_access<_Err>(std::move(error()));
856bdd1243dSDimitry Andric     }
8577a6dacacSDimitry Andric     return std::move(this->__val());
858bdd1243dSDimitry Andric   }
859bdd1243dSDimitry Andric 
860bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
8617a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
8627a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
8637a6dacacSDimitry Andric     return this->__unex();
864bdd1243dSDimitry Andric   }
865bdd1243dSDimitry Andric 
866bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
8677a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
8687a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
8697a6dacacSDimitry Andric     return this->__unex();
870bdd1243dSDimitry Andric   }
871bdd1243dSDimitry Andric 
872bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
8737a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
8747a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
8757a6dacacSDimitry Andric     return std::move(this->__unex());
876bdd1243dSDimitry Andric   }
877bdd1243dSDimitry Andric 
878bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
8797a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
8807a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
8817a6dacacSDimitry Andric     return std::move(this->__unex());
882bdd1243dSDimitry Andric   }
883bdd1243dSDimitry Andric 
884bdd1243dSDimitry Andric   template <class _Up>
885bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
886bdd1243dSDimitry Andric     static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible");
887bdd1243dSDimitry Andric     static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
8887a6dacacSDimitry Andric     return this->__has_val() ? this->__val() : static_cast<_Tp>(std::forward<_Up>(__v));
889bdd1243dSDimitry Andric   }
890bdd1243dSDimitry Andric 
891bdd1243dSDimitry Andric   template <class _Up>
892bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
893bdd1243dSDimitry Andric     static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible");
894bdd1243dSDimitry Andric     static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type");
8957a6dacacSDimitry Andric     return this->__has_val() ? std::move(this->__val()) : static_cast<_Tp>(std::forward<_Up>(__v));
896bdd1243dSDimitry Andric   }
897bdd1243dSDimitry Andric 
89806c3fb27SDimitry Andric   template <class _Up = _Err>
89906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
90006c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
90106c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
90206c3fb27SDimitry Andric     if (has_value())
90306c3fb27SDimitry Andric       return std::forward<_Up>(__error);
90406c3fb27SDimitry Andric     return error();
90506c3fb27SDimitry Andric   }
90606c3fb27SDimitry Andric 
90706c3fb27SDimitry Andric   template <class _Up = _Err>
90806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
90906c3fb27SDimitry Andric     static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
91006c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
91106c3fb27SDimitry Andric     if (has_value())
91206c3fb27SDimitry Andric       return std::forward<_Up>(__error);
91306c3fb27SDimitry Andric     return std::move(error());
91406c3fb27SDimitry Andric   }
91506c3fb27SDimitry Andric 
91606c3fb27SDimitry Andric   // [expected.void.monadic], monadic
91706c3fb27SDimitry Andric   template <class _Func>
91806c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
91906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
92006c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>;
9215f757f3fSDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f(**this) must be a specialization of std::expected");
92206c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
9235f757f3fSDimitry Andric                   "The result of f(**this) must have the same error_type as this expected");
92406c3fb27SDimitry Andric     if (has_value()) {
9257a6dacacSDimitry Andric       return std::invoke(std::forward<_Func>(__f), this->__val());
92606c3fb27SDimitry Andric     }
92706c3fb27SDimitry Andric     return _Up(unexpect, error());
92806c3fb27SDimitry Andric   }
92906c3fb27SDimitry Andric 
93006c3fb27SDimitry Andric   template <class _Func>
93106c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
93206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
93306c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&>>;
9345f757f3fSDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f(**this) must be a specialization of std::expected");
93506c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
9365f757f3fSDimitry Andric                   "The result of f(**this) must have the same error_type as this expected");
93706c3fb27SDimitry Andric     if (has_value()) {
9387a6dacacSDimitry Andric       return std::invoke(std::forward<_Func>(__f), this->__val());
93906c3fb27SDimitry Andric     }
94006c3fb27SDimitry Andric     return _Up(unexpect, error());
94106c3fb27SDimitry Andric   }
94206c3fb27SDimitry Andric 
94306c3fb27SDimitry Andric   template <class _Func>
94406c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
94506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
94606c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&&>>;
94706c3fb27SDimitry Andric     static_assert(
9485f757f3fSDimitry Andric         __is_std_expected<_Up>::value, "The result of f(std::move(**this)) must be a specialization of std::expected");
94906c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
9505f757f3fSDimitry Andric                   "The result of f(std::move(**this)) must have the same error_type as this expected");
95106c3fb27SDimitry Andric     if (has_value()) {
9527a6dacacSDimitry Andric       return std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
95306c3fb27SDimitry Andric     }
95406c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
95506c3fb27SDimitry Andric   }
95606c3fb27SDimitry Andric 
95706c3fb27SDimitry Andric   template <class _Func>
95806c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
95906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
96006c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>;
96106c3fb27SDimitry Andric     static_assert(
9625f757f3fSDimitry Andric         __is_std_expected<_Up>::value, "The result of f(std::move(**this)) must be a specialization of std::expected");
96306c3fb27SDimitry Andric     static_assert(is_same_v<typename _Up::error_type, _Err>,
9645f757f3fSDimitry Andric                   "The result of f(std::move(**this)) must have the same error_type as this expected");
96506c3fb27SDimitry Andric     if (has_value()) {
9667a6dacacSDimitry Andric       return std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
96706c3fb27SDimitry Andric     }
96806c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
96906c3fb27SDimitry Andric   }
97006c3fb27SDimitry Andric 
97106c3fb27SDimitry Andric   template <class _Func>
97206c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&>
97306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
97406c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
97506c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
97606c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
97706c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
97806c3fb27SDimitry Andric     if (has_value()) {
9797a6dacacSDimitry Andric       return _Gp(in_place, this->__val());
98006c3fb27SDimitry Andric     }
98106c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
98206c3fb27SDimitry Andric   }
98306c3fb27SDimitry Andric 
98406c3fb27SDimitry Andric   template <class _Func>
98506c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&>
98606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
98706c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
98806c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
98906c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
99006c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
99106c3fb27SDimitry Andric     if (has_value()) {
9927a6dacacSDimitry Andric       return _Gp(in_place, this->__val());
99306c3fb27SDimitry Andric     }
99406c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
99506c3fb27SDimitry Andric   }
99606c3fb27SDimitry Andric 
99706c3fb27SDimitry Andric   template <class _Func>
99806c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&&>
99906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
100006c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
100106c3fb27SDimitry Andric     static_assert(
100206c3fb27SDimitry Andric         __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
100306c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
100406c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
100506c3fb27SDimitry Andric     if (has_value()) {
10067a6dacacSDimitry Andric       return _Gp(in_place, std::move(this->__val()));
100706c3fb27SDimitry Andric     }
100806c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
100906c3fb27SDimitry Andric   }
101006c3fb27SDimitry Andric 
101106c3fb27SDimitry Andric   template <class _Func>
101206c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&&>
101306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
101406c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
101506c3fb27SDimitry Andric     static_assert(
101606c3fb27SDimitry Andric         __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
101706c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
101806c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
101906c3fb27SDimitry Andric     if (has_value()) {
10207a6dacacSDimitry Andric       return _Gp(in_place, std::move(this->__val()));
102106c3fb27SDimitry Andric     }
102206c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
102306c3fb27SDimitry Andric   }
102406c3fb27SDimitry Andric 
102506c3fb27SDimitry Andric   template <class _Func>
102606c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
102706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
102806c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>;
102906c3fb27SDimitry Andric     if (!has_value()) {
103006c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
103106c3fb27SDimitry Andric     }
103206c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
1033cb14a3feSDimitry Andric       return expected<_Up, _Err>(
10347a6dacacSDimitry Andric           __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), this->__val());
103506c3fb27SDimitry Andric     } else {
10367a6dacacSDimitry Andric       std::invoke(std::forward<_Func>(__f), this->__val());
103706c3fb27SDimitry Andric       return expected<_Up, _Err>();
103806c3fb27SDimitry Andric     }
103906c3fb27SDimitry Andric   }
104006c3fb27SDimitry Andric 
104106c3fb27SDimitry Andric   template <class _Func>
104206c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
104306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
104406c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>;
104506c3fb27SDimitry Andric     if (!has_value()) {
104606c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
104706c3fb27SDimitry Andric     }
104806c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
1049cb14a3feSDimitry Andric       return expected<_Up, _Err>(
10507a6dacacSDimitry Andric           __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), this->__val());
105106c3fb27SDimitry Andric     } else {
10527a6dacacSDimitry Andric       std::invoke(std::forward<_Func>(__f), this->__val());
105306c3fb27SDimitry Andric       return expected<_Up, _Err>();
105406c3fb27SDimitry Andric     }
105506c3fb27SDimitry Andric   }
105606c3fb27SDimitry Andric 
105706c3fb27SDimitry Andric   template <class _Func>
105806c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
105906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
106006c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>;
106106c3fb27SDimitry Andric     if (!has_value()) {
106206c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
106306c3fb27SDimitry Andric     }
106406c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
106506c3fb27SDimitry Andric       return expected<_Up, _Err>(
10667a6dacacSDimitry Andric           __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(this->__val()));
106706c3fb27SDimitry Andric     } else {
10687a6dacacSDimitry Andric       std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
106906c3fb27SDimitry Andric       return expected<_Up, _Err>();
107006c3fb27SDimitry Andric     }
107106c3fb27SDimitry Andric   }
107206c3fb27SDimitry Andric 
107306c3fb27SDimitry Andric   template <class _Func>
107406c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
107506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
107606c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&&>>;
107706c3fb27SDimitry Andric     if (!has_value()) {
107806c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
107906c3fb27SDimitry Andric     }
108006c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
108106c3fb27SDimitry Andric       return expected<_Up, _Err>(
10827a6dacacSDimitry Andric           __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(this->__val()));
108306c3fb27SDimitry Andric     } else {
10847a6dacacSDimitry Andric       std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
108506c3fb27SDimitry Andric       return expected<_Up, _Err>();
108606c3fb27SDimitry Andric     }
108706c3fb27SDimitry Andric   }
108806c3fb27SDimitry Andric 
108906c3fb27SDimitry Andric   template <class _Func>
109006c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&>
109106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
109206c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
109306c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
109406c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
109506c3fb27SDimitry Andric     if (has_value()) {
10967a6dacacSDimitry Andric       return expected<_Tp, _Gp>(in_place, this->__val());
109706c3fb27SDimitry Andric     }
109806c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
109906c3fb27SDimitry Andric   }
110006c3fb27SDimitry Andric 
110106c3fb27SDimitry Andric   template <class _Func>
110206c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&>
110306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
110406c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
110506c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
110606c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
110706c3fb27SDimitry Andric     if (has_value()) {
11087a6dacacSDimitry Andric       return expected<_Tp, _Gp>(in_place, this->__val());
110906c3fb27SDimitry Andric     }
111006c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
111106c3fb27SDimitry Andric   }
111206c3fb27SDimitry Andric 
111306c3fb27SDimitry Andric   template <class _Func>
111406c3fb27SDimitry Andric     requires is_constructible_v<_Tp, _Tp&&>
111506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
111606c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
111706c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
111806c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
111906c3fb27SDimitry Andric     if (has_value()) {
11207a6dacacSDimitry Andric       return expected<_Tp, _Gp>(in_place, std::move(this->__val()));
112106c3fb27SDimitry Andric     }
112206c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
112306c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
112406c3fb27SDimitry Andric   }
112506c3fb27SDimitry Andric 
112606c3fb27SDimitry Andric   template <class _Func>
112706c3fb27SDimitry Andric     requires is_constructible_v<_Tp, const _Tp&&>
112806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
112906c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
113006c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
113106c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
113206c3fb27SDimitry Andric     if (has_value()) {
11337a6dacacSDimitry Andric       return expected<_Tp, _Gp>(in_place, std::move(this->__val()));
113406c3fb27SDimitry Andric     }
113506c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
113606c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
113706c3fb27SDimitry Andric   }
113806c3fb27SDimitry Andric 
1139bdd1243dSDimitry Andric   // [expected.object.eq], equality operators
1140bdd1243dSDimitry Andric   template <class _T2, class _E2>
1141bdd1243dSDimitry Andric     requires(!is_void_v<_T2>)
1142bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
11437a6dacacSDimitry Andric     if (__x.__has_val() != __y.__has_val()) {
1144bdd1243dSDimitry Andric       return false;
1145bdd1243dSDimitry Andric     } else {
11467a6dacacSDimitry Andric       if (__x.__has_val()) {
11477a6dacacSDimitry Andric         return __x.__val() == __y.__val();
1148bdd1243dSDimitry Andric       } else {
11497a6dacacSDimitry Andric         return __x.__unex() == __y.__unex();
1150bdd1243dSDimitry Andric       }
1151bdd1243dSDimitry Andric     }
1152bdd1243dSDimitry Andric   }
1153bdd1243dSDimitry Andric 
1154bdd1243dSDimitry Andric   template <class _T2>
1155bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) {
11567a6dacacSDimitry Andric     return __x.__has_val() && static_cast<bool>(__x.__val() == __v);
1157bdd1243dSDimitry Andric   }
1158bdd1243dSDimitry Andric 
1159bdd1243dSDimitry Andric   template <class _E2>
1160bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) {
11617a6dacacSDimitry Andric     return !__x.__has_val() && static_cast<bool>(__x.__unex() == __e.error());
1162bdd1243dSDimitry Andric   }
116306c3fb27SDimitry Andric };
116406c3fb27SDimitry Andric 
11657a6dacacSDimitry Andric template <class _Err>
11667a6dacacSDimitry Andric class __expected_void_base {
11677a6dacacSDimitry Andric   struct __empty_t {};
116806c3fb27SDimitry Andric   // use named union because [[no_unique_address]] cannot be applied to an unnamed union,
116906c3fb27SDimitry Andric   // also guaranteed elision into a potentially-overlapping subobject is unsettled (and
117006c3fb27SDimitry Andric   // it's not clear that it's implementable, given that the function is allowed to clobber
117106c3fb27SDimitry Andric   // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107.
11727a6dacacSDimitry Andric   union __union_t {
11737a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = delete;
11747a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&)
11757a6dacacSDimitry Andric       requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>)
11767a6dacacSDimitry Andric     = default;
11777a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) = delete;
11787a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&)
11797a6dacacSDimitry Andric       requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
11807a6dacacSDimitry Andric     = default;
11817a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(const __union_t&) = delete;
11827a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(__union_t&&)      = delete;
11837a6dacacSDimitry Andric 
11847a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(in_place_t) : __empty_() {}
1185b121cb00SDimitry Andric 
1186b121cb00SDimitry Andric     template <class... _Args>
11877a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(unexpect_t, _Args&&... __args)
1188b121cb00SDimitry Andric         : __unex_(std::forward<_Args>(__args)...) {}
118906c3fb27SDimitry Andric 
119006c3fb27SDimitry Andric     template <class _Func, class... _Args>
119106c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(
11927a6dacacSDimitry Andric         __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args)
119306c3fb27SDimitry Andric         : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
119406c3fb27SDimitry Andric 
119506c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
11967a6dacacSDimitry Andric       requires(is_trivially_destructible_v<_Err>)
1197bdd1243dSDimitry Andric     = default;
1198bdd1243dSDimitry Andric 
11997a6dacacSDimitry Andric     // __repr's destructor handles this
1200bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t()
12017a6dacacSDimitry Andric       requires(!is_trivially_destructible_v<_Err>)
1202bdd1243dSDimitry Andric     {}
1203bdd1243dSDimitry Andric 
12047a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_;
12057a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_;
120606c3fb27SDimitry Andric   };
1207bdd1243dSDimitry Andric 
12087a6dacacSDimitry Andric   static constexpr bool __put_flag_in_tail                    = __fits_in_tail_padding<__union_t, bool>;
12097a6dacacSDimitry Andric   static constexpr bool __allow_reusing_expected_tail_padding = !__put_flag_in_tail;
12107a6dacacSDimitry Andric 
12117a6dacacSDimitry Andric   struct __repr {
12127a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr() = delete;
12137a6dacacSDimitry Andric 
12147a6dacacSDimitry Andric     template <class... _Args>
12157a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(in_place_t __tag) : __union_(in_place, __tag), __has_val_(true) {}
12167a6dacacSDimitry Andric 
12177a6dacacSDimitry Andric     template <class... _Args>
12187a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(unexpect_t __tag, _Args&&... __args)
12197a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {}
12207a6dacacSDimitry Andric 
12217a6dacacSDimitry Andric     template <class... _Args>
12227a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_unexpected_from_invoke_tag __tag,
12237a6dacacSDimitry Andric                                                     _Args&&... __args)
12247a6dacacSDimitry Andric         : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {}
12257a6dacacSDimitry Andric 
12267a6dacacSDimitry Andric     template <class _OtherUnion>
12277a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(bool __has_val, _OtherUnion&& __other)
12287a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
12297a6dacacSDimitry Andric         : __union_(__conditional_no_unique_address_invoke_tag{},
12307a6dacacSDimitry Andric                    [&] { return __make_union(__has_val, std::forward<_OtherUnion>(__other)); }),
12317a6dacacSDimitry Andric           __has_val_(__has_val) {}
12327a6dacacSDimitry Andric 
12337a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) = delete;
12347a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&)
12357a6dacacSDimitry Andric       requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>)
12367a6dacacSDimitry Andric     = default;
12377a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) = delete;
12387a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&)
12397a6dacacSDimitry Andric       requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
12407a6dacacSDimitry Andric     = default;
12417a6dacacSDimitry Andric 
12427a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(const __repr&) = delete;
12437a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(__repr&&)      = delete;
12447a6dacacSDimitry Andric 
12457a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__repr()
12467a6dacacSDimitry Andric       requires(is_trivially_destructible_v<_Err>)
12477a6dacacSDimitry Andric     = default;
12487a6dacacSDimitry Andric 
12497a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr ~__repr()
12507a6dacacSDimitry Andric       requires(!is_trivially_destructible_v<_Err>)
12517a6dacacSDimitry Andric     {
12527a6dacacSDimitry Andric       __destroy_union_member();
12537a6dacacSDimitry Andric     }
12547a6dacacSDimitry Andric 
12557a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union()
12567a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding && is_trivially_destructible_v<_Err>)
12577a6dacacSDimitry Andric     {
12587a6dacacSDimitry Andric       std::destroy_at(&__union_.__v);
12597a6dacacSDimitry Andric     }
12607a6dacacSDimitry Andric 
12617a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union()
12627a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding && !is_trivially_destructible_v<_Err>)
12637a6dacacSDimitry Andric     {
12647a6dacacSDimitry Andric       __destroy_union_member();
12657a6dacacSDimitry Andric       std::destroy_at(&__union_.__v);
12667a6dacacSDimitry Andric     }
12677a6dacacSDimitry Andric 
12687a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(in_place_t)
12697a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
12707a6dacacSDimitry Andric     {
12717a6dacacSDimitry Andric       std::construct_at(&__union_.__v, in_place);
12727a6dacacSDimitry Andric       __has_val_ = true;
12737a6dacacSDimitry Andric     }
12747a6dacacSDimitry Andric 
12757a6dacacSDimitry Andric     template <class... _Args>
12767a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(unexpect_t, _Args&&... __args)
12777a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
12787a6dacacSDimitry Andric     {
12797a6dacacSDimitry Andric       std::construct_at(&__union_.__v, unexpect, std::forward<_Args>(__args)...);
12807a6dacacSDimitry Andric       __has_val_ = false;
12817a6dacacSDimitry Andric     }
12827a6dacacSDimitry Andric 
12837a6dacacSDimitry Andric   private:
12847a6dacacSDimitry Andric     template <class>
12857a6dacacSDimitry Andric     friend class __expected_void_base;
12867a6dacacSDimitry Andric 
12877a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union_member()
12887a6dacacSDimitry Andric       requires(!is_trivially_destructible_v<_Err>)
12897a6dacacSDimitry Andric     {
12907a6dacacSDimitry Andric       if (!__has_val_)
12917a6dacacSDimitry Andric         std::destroy_at(std::addressof(__union_.__v.__unex_));
12927a6dacacSDimitry Andric     }
12937a6dacacSDimitry Andric 
12947a6dacacSDimitry Andric     template <class _OtherUnion>
12957a6dacacSDimitry Andric     _LIBCPP_HIDE_FROM_ABI static constexpr __union_t __make_union(bool __has_val, _OtherUnion&& __other)
12967a6dacacSDimitry Andric       requires(__allow_reusing_expected_tail_padding)
12977a6dacacSDimitry Andric     {
12987a6dacacSDimitry Andric       if (__has_val)
12997a6dacacSDimitry Andric         return __union_t(in_place);
13007a6dacacSDimitry Andric       else
13017a6dacacSDimitry Andric         return __union_t(unexpect, std::forward<_OtherUnion>(__other).__unex_);
13027a6dacacSDimitry Andric     }
13037a6dacacSDimitry Andric 
13047a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__put_flag_in_tail, __union_t> __union_;
13057a6dacacSDimitry Andric     _LIBCPP_NO_UNIQUE_ADDRESS bool __has_val_;
13067a6dacacSDimitry Andric   };
13077a6dacacSDimitry Andric 
13087a6dacacSDimitry Andric   template <class _OtherUnion>
13097a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr __repr __make_repr(bool __has_val, _OtherUnion&& __other)
13107a6dacacSDimitry Andric     requires(__put_flag_in_tail)
13117a6dacacSDimitry Andric   {
13127a6dacacSDimitry Andric     if (__has_val)
13137a6dacacSDimitry Andric       return __repr(in_place);
13147a6dacacSDimitry Andric     else
13157a6dacacSDimitry Andric       return __repr(unexpect, std::forward<_OtherUnion>(__other).__unex_);
13167a6dacacSDimitry Andric   }
13177a6dacacSDimitry Andric 
13187a6dacacSDimitry Andric protected:
13197a6dacacSDimitry Andric   template <class... _Args>
13207a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_void_base(_Args&&... __args)
13217a6dacacSDimitry Andric       : __repr_(in_place, std::forward<_Args>(__args)...) {}
13227a6dacacSDimitry Andric 
13237a6dacacSDimitry Andric   template <class _OtherUnion>
13247a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_void_base(bool __has_val, _OtherUnion&& __other)
13257a6dacacSDimitry Andric     requires(__put_flag_in_tail)
13267a6dacacSDimitry Andric       : __repr_(__conditional_no_unique_address_invoke_tag{},
13277a6dacacSDimitry Andric                 [&] { return __make_repr(__has_val, std::forward<_OtherUnion>(__other)); }) {}
13287a6dacacSDimitry Andric 
13297a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __destroy() {
13307a6dacacSDimitry Andric     if constexpr (__put_flag_in_tail)
13317a6dacacSDimitry Andric       std::destroy_at(&__repr_.__v);
13327a6dacacSDimitry Andric     else
13337a6dacacSDimitry Andric       __repr_.__v.__destroy_union();
13347a6dacacSDimitry Andric   }
13357a6dacacSDimitry Andric 
13367a6dacacSDimitry Andric   template <class _Tag, class... _Args>
13377a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __construct(_Tag __tag, _Args&&... __args) {
13387a6dacacSDimitry Andric     if constexpr (__put_flag_in_tail)
13397a6dacacSDimitry Andric       std::construct_at(&__repr_.__v, __tag, std::forward<_Args>(__args)...);
13407a6dacacSDimitry Andric     else
13417a6dacacSDimitry Andric       __repr_.__v.__construct_union(__tag, std::forward<_Args>(__args)...);
13427a6dacacSDimitry Andric   }
13437a6dacacSDimitry Andric 
13447a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool __has_val() const { return __repr_.__v.__has_val_; }
13457a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr __union_t& __union() { return __repr_.__v.__union_.__v; }
13467a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const __union_t& __union() const { return __repr_.__v.__union_.__v; }
13477a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& __unex() { return __repr_.__v.__union_.__v.__unex_; }
13487a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& __unex() const { return __repr_.__v.__union_.__v.__unex_; }
13497a6dacacSDimitry Andric 
13507a6dacacSDimitry Andric private:
13517a6dacacSDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__allow_reusing_expected_tail_padding, __repr> __repr_;
1352bdd1243dSDimitry Andric };
1353bdd1243dSDimitry Andric 
1354bdd1243dSDimitry Andric template <class _Tp, class _Err>
1355bdd1243dSDimitry Andric   requires is_void_v<_Tp>
13567a6dacacSDimitry Andric class expected<_Tp, _Err> : private __expected_void_base<_Err> {
1357bdd1243dSDimitry Andric   static_assert(__valid_std_unexpected<_Err>::value,
1358bdd1243dSDimitry Andric                 "[expected.void.general] A program that instantiates expected<T, E> with a E that is not a "
1359bdd1243dSDimitry Andric                 "valid argument for unexpected<E> is ill-formed");
1360bdd1243dSDimitry Andric 
1361bdd1243dSDimitry Andric   template <class, class>
1362bdd1243dSDimitry Andric   friend class expected;
1363bdd1243dSDimitry Andric 
1364bdd1243dSDimitry Andric   template <class _Up, class _OtherErr, class _OtherErrQual>
1365bdd1243dSDimitry Andric   using __can_convert =
1366bdd1243dSDimitry Andric       _And< is_void<_Up>,
1367bdd1243dSDimitry Andric             is_constructible<_Err, _OtherErrQual>,
1368bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>,
1369bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>,
1370bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>,
1371bdd1243dSDimitry Andric             _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>>>;
1372bdd1243dSDimitry Andric 
13737a6dacacSDimitry Andric   using __base = __expected_void_base<_Err>;
13747a6dacacSDimitry Andric 
1375bdd1243dSDimitry Andric public:
1376bdd1243dSDimitry Andric   using value_type      = _Tp;
1377bdd1243dSDimitry Andric   using error_type      = _Err;
1378bdd1243dSDimitry Andric   using unexpected_type = unexpected<_Err>;
1379bdd1243dSDimitry Andric 
1380bdd1243dSDimitry Andric   template <class _Up>
1381bdd1243dSDimitry Andric   using rebind = expected<_Up, error_type>;
1382bdd1243dSDimitry Andric 
1383bdd1243dSDimitry Andric   // [expected.void.ctor], constructors
13847a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __base(in_place) {}
1385bdd1243dSDimitry Andric 
1386bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete;
1387bdd1243dSDimitry Andric 
1388bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&)
1389bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>)
1390bdd1243dSDimitry Andric   = default;
1391bdd1243dSDimitry Andric 
1392cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs) noexcept(
1393cb14a3feSDimitry Andric       is_nothrow_copy_constructible_v<_Err>) // strengthened
1394bdd1243dSDimitry Andric     requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>)
13957a6dacacSDimitry Andric       : __base(__rhs.__has_val(), __rhs.__union()) {}
1396bdd1243dSDimitry Andric 
1397bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&)
1398bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>)
1399bdd1243dSDimitry Andric   = default;
1400bdd1243dSDimitry Andric 
1401cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs) noexcept(is_nothrow_move_constructible_v<_Err>)
1402bdd1243dSDimitry Andric     requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>)
14037a6dacacSDimitry Andric       : __base(__rhs.__has_val(), std::move(__rhs.__union())) {}
1404bdd1243dSDimitry Andric 
1405bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
1406bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value
1407bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>)
1408cb14a3feSDimitry Andric       expected(const expected<_Up, _OtherErr>& __rhs) noexcept(
1409cb14a3feSDimitry Andric           is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
14107a6dacacSDimitry Andric       : __base(__rhs.__has_val(), __rhs.__union()) {}
1411bdd1243dSDimitry Andric 
1412bdd1243dSDimitry Andric   template <class _Up, class _OtherErr>
1413bdd1243dSDimitry Andric     requires __can_convert<_Up, _OtherErr, _OtherErr>::value
1414bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
1415cb14a3feSDimitry Andric       expected(expected<_Up, _OtherErr>&& __rhs) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
14167a6dacacSDimitry Andric       : __base(__rhs.__has_val(), std::move(__rhs.__union())) {}
1417bdd1243dSDimitry Andric 
1418bdd1243dSDimitry Andric   template <class _OtherErr>
1419bdd1243dSDimitry Andric     requires is_constructible_v<_Err, const _OtherErr&>
1420cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>) expected(
1421cb14a3feSDimitry Andric       const unexpected<_OtherErr>& __unex) noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened
14227a6dacacSDimitry Andric       : __base(unexpect, __unex.error()) {}
1423bdd1243dSDimitry Andric 
1424bdd1243dSDimitry Andric   template <class _OtherErr>
1425bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _OtherErr>
1426bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>)
1427cb14a3feSDimitry Andric       expected(unexpected<_OtherErr>&& __unex) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened
14287a6dacacSDimitry Andric       : __base(unexpect, std::move(__unex.error())) {}
1429bdd1243dSDimitry Andric 
14307a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __base(in_place) {}
1431bdd1243dSDimitry Andric 
1432bdd1243dSDimitry Andric   template <class... _Args>
1433bdd1243dSDimitry Andric     requires is_constructible_v<_Err, _Args...>
1434cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) noexcept(
1435cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Err, _Args...>) // strengthened
14367a6dacacSDimitry Andric       : __base(unexpect, std::forward<_Args>(__args)...) {}
1437bdd1243dSDimitry Andric 
1438bdd1243dSDimitry Andric   template <class _Up, class... _Args>
1439bdd1243dSDimitry Andric     requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... >
1440cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) noexcept(
1441cb14a3feSDimitry Andric       is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened
14427a6dacacSDimitry Andric       : __base(unexpect, __il, std::forward<_Args>(__args)...) {}
1443bdd1243dSDimitry Andric 
144406c3fb27SDimitry Andric private:
144506c3fb27SDimitry Andric   template <class _Func, class... _Args>
144606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(
144706c3fb27SDimitry Andric       __expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args)
14487a6dacacSDimitry Andric       : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {}
144906c3fb27SDimitry Andric 
145006c3fb27SDimitry Andric public:
1451bdd1243dSDimitry Andric   // [expected.void.dtor], destructor
1452bdd1243dSDimitry Andric 
14537a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr ~expected() = default;
1454bdd1243dSDimitry Andric 
14557a6dacacSDimitry Andric private:
14567a6dacacSDimitry Andric   template <class... _Args>
14577a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(unexpect_t, _Args&&... __args) {
14587a6dacacSDimitry Andric     _LIBCPP_ASSERT_INTERNAL(this->__has_val(), "__reinit_expected(unexpect_t, ...) needs value to be set");
14597a6dacacSDimitry Andric 
14607a6dacacSDimitry Andric     this->__destroy();
14617a6dacacSDimitry Andric     auto __trans = std::__make_exception_guard([&] { this->__construct(in_place); });
14627a6dacacSDimitry Andric     this->__construct(unexpect, std::forward<_Args>(__args)...);
14637a6dacacSDimitry Andric     __trans.__complete();
1464bdd1243dSDimitry Andric   }
1465bdd1243dSDimitry Andric 
14667a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(in_place_t) {
14677a6dacacSDimitry Andric     _LIBCPP_ASSERT_INTERNAL(!this->__has_val(), "__reinit_expected(in_place_t, ...) needs value to be unset");
14687a6dacacSDimitry Andric 
14697a6dacacSDimitry Andric     this->__destroy();
14707a6dacacSDimitry Andric     this->__construct(in_place);
14717a6dacacSDimitry Andric   }
14727a6dacacSDimitry Andric 
14737a6dacacSDimitry Andric public:
1474bdd1243dSDimitry Andric   // [expected.void.assign], assignment
1475bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete;
1476bdd1243dSDimitry Andric 
1477cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) noexcept(
1478cb14a3feSDimitry Andric       is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened
1479bdd1243dSDimitry Andric     requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>)
1480bdd1243dSDimitry Andric   {
14817a6dacacSDimitry Andric     if (this->__has_val()) {
14827a6dacacSDimitry Andric       if (!__rhs.__has_val()) {
14837a6dacacSDimitry Andric         __reinit_expected(unexpect, __rhs.__unex());
1484bdd1243dSDimitry Andric       }
1485bdd1243dSDimitry Andric     } else {
14867a6dacacSDimitry Andric       if (__rhs.__has_val()) {
14877a6dacacSDimitry Andric         __reinit_expected(in_place);
1488bdd1243dSDimitry Andric       } else {
14897a6dacacSDimitry Andric         this->__unex() = __rhs.__unex();
1490bdd1243dSDimitry Andric       }
1491bdd1243dSDimitry Andric     }
1492bdd1243dSDimitry Andric     return *this;
1493bdd1243dSDimitry Andric   }
1494bdd1243dSDimitry Andric 
1495bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&&) = delete;
1496bdd1243dSDimitry Andric 
1497cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected&
1498cb14a3feSDimitry Andric   operator=(expected&& __rhs) noexcept(is_nothrow_move_assignable_v<_Err> && is_nothrow_move_constructible_v<_Err>)
1499cb14a3feSDimitry Andric     requires(is_move_assignable_v<_Err> && is_move_constructible_v<_Err>)
1500bdd1243dSDimitry Andric   {
15017a6dacacSDimitry Andric     if (this->__has_val()) {
15027a6dacacSDimitry Andric       if (!__rhs.__has_val()) {
15037a6dacacSDimitry Andric         __reinit_expected(unexpect, std::move(__rhs.__unex()));
1504bdd1243dSDimitry Andric       }
1505bdd1243dSDimitry Andric     } else {
15067a6dacacSDimitry Andric       if (__rhs.__has_val()) {
15077a6dacacSDimitry Andric         __reinit_expected(in_place);
1508bdd1243dSDimitry Andric       } else {
15097a6dacacSDimitry Andric         this->__unex() = std::move(__rhs.__unex());
1510bdd1243dSDimitry Andric       }
1511bdd1243dSDimitry Andric     }
1512bdd1243dSDimitry Andric     return *this;
1513bdd1243dSDimitry Andric   }
1514bdd1243dSDimitry Andric 
1515bdd1243dSDimitry Andric   template <class _OtherErr>
1516bdd1243dSDimitry Andric     requires(is_constructible_v<_Err, const _OtherErr&> && is_assignable_v<_Err&, const _OtherErr&>)
1517bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) {
15187a6dacacSDimitry Andric     if (this->__has_val()) {
15197a6dacacSDimitry Andric       __reinit_expected(unexpect, __un.error());
1520bdd1243dSDimitry Andric     } else {
15217a6dacacSDimitry Andric       this->__unex() = __un.error();
1522bdd1243dSDimitry Andric     }
1523bdd1243dSDimitry Andric     return *this;
1524bdd1243dSDimitry Andric   }
1525bdd1243dSDimitry Andric 
1526bdd1243dSDimitry Andric   template <class _OtherErr>
1527bdd1243dSDimitry Andric     requires(is_constructible_v<_Err, _OtherErr> && is_assignable_v<_Err&, _OtherErr>)
1528bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) {
15297a6dacacSDimitry Andric     if (this->__has_val()) {
15307a6dacacSDimitry Andric       __reinit_expected(unexpect, std::move(__un.error()));
1531bdd1243dSDimitry Andric     } else {
15327a6dacacSDimitry Andric       this->__unex() = std::move(__un.error());
1533bdd1243dSDimitry Andric     }
1534bdd1243dSDimitry Andric     return *this;
1535bdd1243dSDimitry Andric   }
1536bdd1243dSDimitry Andric 
1537bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept {
15387a6dacacSDimitry Andric     if (!this->__has_val()) {
15397a6dacacSDimitry Andric       __reinit_expected(in_place);
1540bdd1243dSDimitry Andric     }
1541bdd1243dSDimitry Andric   }
1542bdd1243dSDimitry Andric 
1543bdd1243dSDimitry Andric   // [expected.void.swap], swap
1544cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void
1545cb14a3feSDimitry Andric   swap(expected& __rhs) noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>)
1546bdd1243dSDimitry Andric     requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>)
1547bdd1243dSDimitry Andric   {
15487a6dacacSDimitry Andric     auto __swap_val_unex_impl = [](expected& __with_val, expected& __with_err) {
15497a6dacacSDimitry Andric       // May throw, but will re-engage `__with_val` in that case.
15507a6dacacSDimitry Andric       __with_val.__reinit_expected(unexpect, std::move(__with_err.__unex()));
15517a6dacacSDimitry Andric       // Will not throw.
15527a6dacacSDimitry Andric       __with_err.__reinit_expected(in_place);
1553bdd1243dSDimitry Andric     };
1554bdd1243dSDimitry Andric 
15557a6dacacSDimitry Andric     if (this->__has_val()) {
15567a6dacacSDimitry Andric       if (!__rhs.__has_val()) {
1557bdd1243dSDimitry Andric         __swap_val_unex_impl(*this, __rhs);
1558bdd1243dSDimitry Andric       }
1559bdd1243dSDimitry Andric     } else {
15607a6dacacSDimitry Andric       if (__rhs.__has_val()) {
1561bdd1243dSDimitry Andric         __swap_val_unex_impl(__rhs, *this);
1562bdd1243dSDimitry Andric       } else {
1563bdd1243dSDimitry Andric         using std::swap;
15647a6dacacSDimitry Andric         swap(this->__unex(), __rhs.__unex());
1565bdd1243dSDimitry Andric       }
1566bdd1243dSDimitry Andric     }
1567bdd1243dSDimitry Andric   }
1568bdd1243dSDimitry Andric 
1569cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) noexcept(noexcept(__x.swap(__y)))
1570bdd1243dSDimitry Andric     requires requires { __x.swap(__y); }
1571bdd1243dSDimitry Andric   {
1572bdd1243dSDimitry Andric     __x.swap(__y);
1573bdd1243dSDimitry Andric   }
1574bdd1243dSDimitry Andric 
1575bdd1243dSDimitry Andric   // [expected.void.obs], observers
15767a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return this->__has_val(); }
1577bdd1243dSDimitry Andric 
15787a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); }
1579bdd1243dSDimitry Andric 
1580bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept {
15817a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
15827a6dacacSDimitry Andric         this->__has_val(), "expected::operator* requires the expected to contain a value");
1583bdd1243dSDimitry Andric   }
1584bdd1243dSDimitry Andric 
1585bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void value() const& {
15867a6dacacSDimitry Andric     static_assert(is_copy_constructible_v<_Err>);
15877a6dacacSDimitry Andric     if (!this->__has_val()) {
15887a6dacacSDimitry Andric       std::__throw_bad_expected_access<_Err>(this->__unex());
1589bdd1243dSDimitry Andric     }
1590bdd1243dSDimitry Andric   }
1591bdd1243dSDimitry Andric 
1592bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr void value() && {
15937a6dacacSDimitry Andric     static_assert(is_copy_constructible_v<_Err> && is_move_constructible_v<_Err>);
15947a6dacacSDimitry Andric     if (!this->__has_val()) {
15957a6dacacSDimitry Andric       std::__throw_bad_expected_access<_Err>(std::move(this->__unex()));
1596bdd1243dSDimitry Andric     }
1597bdd1243dSDimitry Andric   }
1598bdd1243dSDimitry Andric 
1599bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept {
16007a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
16017a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
16027a6dacacSDimitry Andric     return this->__unex();
1603bdd1243dSDimitry Andric   }
1604bdd1243dSDimitry Andric 
1605bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept {
16067a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
16077a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
16087a6dacacSDimitry Andric     return this->__unex();
1609bdd1243dSDimitry Andric   }
1610bdd1243dSDimitry Andric 
1611bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept {
16127a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
16137a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
16147a6dacacSDimitry Andric     return std::move(this->__unex());
1615bdd1243dSDimitry Andric   }
1616bdd1243dSDimitry Andric 
1617bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept {
16187a6dacacSDimitry Andric     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
16197a6dacacSDimitry Andric         !this->__has_val(), "expected::error requires the expected to contain an error");
16207a6dacacSDimitry Andric     return std::move(this->__unex());
1621bdd1243dSDimitry Andric   }
1622bdd1243dSDimitry Andric 
162306c3fb27SDimitry Andric   template <class _Up = _Err>
162406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& {
162506c3fb27SDimitry Andric     static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible");
162606c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
162706c3fb27SDimitry Andric     if (has_value()) {
162806c3fb27SDimitry Andric       return std::forward<_Up>(__error);
162906c3fb27SDimitry Andric     }
163006c3fb27SDimitry Andric     return error();
163106c3fb27SDimitry Andric   }
163206c3fb27SDimitry Andric 
163306c3fb27SDimitry Andric   template <class _Up = _Err>
163406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && {
163506c3fb27SDimitry Andric     static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible");
163606c3fb27SDimitry Andric     static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type");
163706c3fb27SDimitry Andric     if (has_value()) {
163806c3fb27SDimitry Andric       return std::forward<_Up>(__error);
163906c3fb27SDimitry Andric     }
164006c3fb27SDimitry Andric     return std::move(error());
164106c3fb27SDimitry Andric   }
164206c3fb27SDimitry Andric 
164306c3fb27SDimitry Andric   // [expected.void.monadic], monadic
164406c3fb27SDimitry Andric   template <class _Func>
164506c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
164606c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
164706c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
164806c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
164906c3fb27SDimitry Andric     static_assert(
165006c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
165106c3fb27SDimitry Andric     if (has_value()) {
165206c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
165306c3fb27SDimitry Andric     }
165406c3fb27SDimitry Andric     return _Up(unexpect, error());
165506c3fb27SDimitry Andric   }
165606c3fb27SDimitry Andric 
165706c3fb27SDimitry Andric   template <class _Func>
165806c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
165906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
166006c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
166106c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
166206c3fb27SDimitry Andric     static_assert(
166306c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
166406c3fb27SDimitry Andric     if (has_value()) {
166506c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
166606c3fb27SDimitry Andric     }
166706c3fb27SDimitry Andric     return _Up(unexpect, error());
166806c3fb27SDimitry Andric   }
166906c3fb27SDimitry Andric 
167006c3fb27SDimitry Andric   template <class _Func>
167106c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
167206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
167306c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
167406c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
167506c3fb27SDimitry Andric     static_assert(
167606c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
167706c3fb27SDimitry Andric     if (has_value()) {
167806c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
167906c3fb27SDimitry Andric     }
168006c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
168106c3fb27SDimitry Andric   }
168206c3fb27SDimitry Andric 
168306c3fb27SDimitry Andric   template <class _Func>
168406c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
168506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
168606c3fb27SDimitry Andric     using _Up = remove_cvref_t<invoke_result_t<_Func>>;
168706c3fb27SDimitry Andric     static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected");
168806c3fb27SDimitry Andric     static_assert(
168906c3fb27SDimitry Andric         is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected");
169006c3fb27SDimitry Andric     if (has_value()) {
169106c3fb27SDimitry Andric       return std::invoke(std::forward<_Func>(__f));
169206c3fb27SDimitry Andric     }
169306c3fb27SDimitry Andric     return _Up(unexpect, std::move(error()));
169406c3fb27SDimitry Andric   }
169506c3fb27SDimitry Andric 
169606c3fb27SDimitry Andric   template <class _Func>
169706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & {
169806c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>;
169906c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
170006c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
170106c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
170206c3fb27SDimitry Andric     if (has_value()) {
170306c3fb27SDimitry Andric       return _Gp();
170406c3fb27SDimitry Andric     }
170506c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
170606c3fb27SDimitry Andric   }
170706c3fb27SDimitry Andric 
170806c3fb27SDimitry Andric   template <class _Func>
170906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& {
171006c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>;
171106c3fb27SDimitry Andric     static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected");
171206c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
171306c3fb27SDimitry Andric                   "The result of f(error()) must have the same value_type as this expected");
171406c3fb27SDimitry Andric     if (has_value()) {
171506c3fb27SDimitry Andric       return _Gp();
171606c3fb27SDimitry Andric     }
171706c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), error());
171806c3fb27SDimitry Andric   }
171906c3fb27SDimitry Andric 
172006c3fb27SDimitry Andric   template <class _Func>
172106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && {
172206c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>;
1723cb14a3feSDimitry Andric     static_assert(
1724cb14a3feSDimitry Andric         __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
172506c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
172606c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
172706c3fb27SDimitry Andric     if (has_value()) {
172806c3fb27SDimitry Andric       return _Gp();
172906c3fb27SDimitry Andric     }
173006c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
173106c3fb27SDimitry Andric   }
173206c3fb27SDimitry Andric 
173306c3fb27SDimitry Andric   template <class _Func>
173406c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& {
173506c3fb27SDimitry Andric     using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>;
1736cb14a3feSDimitry Andric     static_assert(
1737cb14a3feSDimitry Andric         __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected");
173806c3fb27SDimitry Andric     static_assert(is_same_v<typename _Gp::value_type, _Tp>,
173906c3fb27SDimitry Andric                   "The result of f(std::move(error())) must have the same value_type as this expected");
174006c3fb27SDimitry Andric     if (has_value()) {
174106c3fb27SDimitry Andric       return _Gp();
174206c3fb27SDimitry Andric     }
174306c3fb27SDimitry Andric     return std::invoke(std::forward<_Func>(__f), std::move(error()));
174406c3fb27SDimitry Andric   }
174506c3fb27SDimitry Andric 
174606c3fb27SDimitry Andric   template <class _Func>
174706c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&>
174806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
174906c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
175006c3fb27SDimitry Andric     if (!has_value()) {
175106c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
175206c3fb27SDimitry Andric     }
175306c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
175406c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
175506c3fb27SDimitry Andric     } else {
175606c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
175706c3fb27SDimitry Andric       return expected<_Up, _Err>();
175806c3fb27SDimitry Andric     }
175906c3fb27SDimitry Andric   }
176006c3fb27SDimitry Andric 
176106c3fb27SDimitry Andric   template <class _Func>
176206c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&>
176306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
176406c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
176506c3fb27SDimitry Andric     if (!has_value()) {
176606c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, error());
176706c3fb27SDimitry Andric     }
176806c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
176906c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
177006c3fb27SDimitry Andric     } else {
177106c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
177206c3fb27SDimitry Andric       return expected<_Up, _Err>();
177306c3fb27SDimitry Andric     }
177406c3fb27SDimitry Andric   }
177506c3fb27SDimitry Andric 
177606c3fb27SDimitry Andric   template <class _Func>
177706c3fb27SDimitry Andric     requires is_constructible_v<_Err, _Err&&>
177806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
177906c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
178006c3fb27SDimitry Andric     if (!has_value()) {
178106c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
178206c3fb27SDimitry Andric     }
178306c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
178406c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
178506c3fb27SDimitry Andric     } else {
178606c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
178706c3fb27SDimitry Andric       return expected<_Up, _Err>();
178806c3fb27SDimitry Andric     }
178906c3fb27SDimitry Andric   }
179006c3fb27SDimitry Andric 
179106c3fb27SDimitry Andric   template <class _Func>
179206c3fb27SDimitry Andric     requires is_constructible_v<_Err, const _Err&&>
179306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
179406c3fb27SDimitry Andric     using _Up = remove_cv_t<invoke_result_t<_Func>>;
179506c3fb27SDimitry Andric     if (!has_value()) {
179606c3fb27SDimitry Andric       return expected<_Up, _Err>(unexpect, std::move(error()));
179706c3fb27SDimitry Andric     }
179806c3fb27SDimitry Andric     if constexpr (!is_void_v<_Up>) {
179906c3fb27SDimitry Andric       return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f));
180006c3fb27SDimitry Andric     } else {
180106c3fb27SDimitry Andric       std::invoke(std::forward<_Func>(__f));
180206c3fb27SDimitry Andric       return expected<_Up, _Err>();
180306c3fb27SDimitry Andric     }
180406c3fb27SDimitry Andric   }
180506c3fb27SDimitry Andric 
180606c3fb27SDimitry Andric   template <class _Func>
180706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & {
180806c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>;
180906c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
181006c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
181106c3fb27SDimitry Andric     if (has_value()) {
181206c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
181306c3fb27SDimitry Andric     }
181406c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
181506c3fb27SDimitry Andric   }
181606c3fb27SDimitry Andric 
181706c3fb27SDimitry Andric   template <class _Func>
181806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& {
181906c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>;
182006c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
182106c3fb27SDimitry Andric                   "The result of f(error()) must be a valid template argument for unexpected");
182206c3fb27SDimitry Andric     if (has_value()) {
182306c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
182406c3fb27SDimitry Andric     }
182506c3fb27SDimitry Andric     return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error());
182606c3fb27SDimitry Andric   }
182706c3fb27SDimitry Andric 
182806c3fb27SDimitry Andric   template <class _Func>
182906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && {
183006c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>;
183106c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
183206c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
183306c3fb27SDimitry Andric     if (has_value()) {
183406c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
183506c3fb27SDimitry Andric     }
183606c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
183706c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
183806c3fb27SDimitry Andric   }
183906c3fb27SDimitry Andric 
184006c3fb27SDimitry Andric   template <class _Func>
184106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& {
184206c3fb27SDimitry Andric     using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>;
184306c3fb27SDimitry Andric     static_assert(__valid_std_unexpected<_Gp>::value,
184406c3fb27SDimitry Andric                   "The result of f(std::move(error())) must be a valid template argument for unexpected");
184506c3fb27SDimitry Andric     if (has_value()) {
184606c3fb27SDimitry Andric       return expected<_Tp, _Gp>();
184706c3fb27SDimitry Andric     }
184806c3fb27SDimitry Andric     return expected<_Tp, _Gp>(
184906c3fb27SDimitry Andric         __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error()));
185006c3fb27SDimitry Andric   }
185106c3fb27SDimitry Andric 
1852bdd1243dSDimitry Andric   // [expected.void.eq], equality operators
1853bdd1243dSDimitry Andric   template <class _T2, class _E2>
1854bdd1243dSDimitry Andric     requires is_void_v<_T2>
1855bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) {
18567a6dacacSDimitry Andric     if (__x.__has_val() != __y.__has_val()) {
1857bdd1243dSDimitry Andric       return false;
1858bdd1243dSDimitry Andric     } else {
18597a6dacacSDimitry Andric       return __x.__has_val() || static_cast<bool>(__x.__unex() == __y.__unex());
1860bdd1243dSDimitry Andric     }
1861bdd1243dSDimitry Andric   }
1862bdd1243dSDimitry Andric 
1863bdd1243dSDimitry Andric   template <class _E2>
1864bdd1243dSDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) {
18657a6dacacSDimitry Andric     return !__x.__has_val() && static_cast<bool>(__x.__unex() == __y.error());
1866bdd1243dSDimitry Andric   }
1867bdd1243dSDimitry Andric };
1868bdd1243dSDimitry Andric 
1869bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD
1870bdd1243dSDimitry Andric 
1871bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER >= 23
1872bdd1243dSDimitry Andric 
187306c3fb27SDimitry Andric _LIBCPP_POP_MACROS
187406c3fb27SDimitry Andric 
1875bdd1243dSDimitry Andric #endif // _LIBCPP___EXPECTED_EXPECTED_H
1876