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