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