1*b1e83836Smrg// <expected> -*- C++ -*- 2*b1e83836Smrg 3*b1e83836Smrg// Copyright The GNU Toolchain Authors. 4*b1e83836Smrg// 5*b1e83836Smrg// This file is part of the GNU ISO C++ Library. This library is free 6*b1e83836Smrg// software; you can redistribute it and/or modify it under the 7*b1e83836Smrg// terms of the GNU General Public License as published by the 8*b1e83836Smrg// Free Software Foundation; either version 3, or (at your option) 9*b1e83836Smrg// any later version. 10*b1e83836Smrg 11*b1e83836Smrg// This library is distributed in the hope that it will be useful, 12*b1e83836Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*b1e83836Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*b1e83836Smrg// GNU General Public License for more details. 15*b1e83836Smrg 16*b1e83836Smrg// Under Section 7 of GPL version 3, you are granted additional 17*b1e83836Smrg// permissions described in the GCC Runtime Library Exception, version 18*b1e83836Smrg// 3.1, as published by the Free Software Foundation. 19*b1e83836Smrg 20*b1e83836Smrg// You should have received a copy of the GNU General Public License and 21*b1e83836Smrg// a copy of the GCC Runtime Library Exception along with this program; 22*b1e83836Smrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*b1e83836Smrg// <http://www.gnu.org/licenses/>. 24*b1e83836Smrg 25*b1e83836Smrg/** @file include/expected 26*b1e83836Smrg * This is a Standard C++ Library header. 27*b1e83836Smrg */ 28*b1e83836Smrg 29*b1e83836Smrg#ifndef _GLIBCXX_EXPECTED 30*b1e83836Smrg#define _GLIBCXX_EXPECTED 31*b1e83836Smrg 32*b1e83836Smrg#pragma GCC system_header 33*b1e83836Smrg 34*b1e83836Smrg#if __cplusplus > 202002L && __cpp_concepts >= 202002L 35*b1e83836Smrg 36*b1e83836Smrg#include <initializer_list> 37*b1e83836Smrg#include <bits/exception.h> // exception 38*b1e83836Smrg#include <bits/stl_construct.h> // construct_at 39*b1e83836Smrg#include <bits/utility.h> // in_place_t 40*b1e83836Smrg 41*b1e83836Smrgnamespace std _GLIBCXX_VISIBILITY(default) 42*b1e83836Smrg{ 43*b1e83836Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 44*b1e83836Smrg 45*b1e83836Smrg /** 46*b1e83836Smrg * @defgroup expected_values Expected values 47*b1e83836Smrg * @addtogroup utilities 48*b1e83836Smrg * @since C++23 49*b1e83836Smrg * @{ 50*b1e83836Smrg */ 51*b1e83836Smrg 52*b1e83836Smrg#define __cpp_lib_expected 202202L 53*b1e83836Smrg 54*b1e83836Smrg /// Discriminated union that holds an expected value or an error value. 55*b1e83836Smrg /** 56*b1e83836Smrg * @since C++23 57*b1e83836Smrg */ 58*b1e83836Smrg template<typename _Tp, typename _Er> 59*b1e83836Smrg class expected; 60*b1e83836Smrg 61*b1e83836Smrg /// Wrapper type used to pass an error value to a `std::expected`. 62*b1e83836Smrg /** 63*b1e83836Smrg * @since C++23 64*b1e83836Smrg */ 65*b1e83836Smrg template<typename _Er> 66*b1e83836Smrg class unexpected; 67*b1e83836Smrg 68*b1e83836Smrg /// Exception thrown by std::expected when the value() is not present. 69*b1e83836Smrg /** 70*b1e83836Smrg * @since C++23 71*b1e83836Smrg */ 72*b1e83836Smrg template<typename _Er> 73*b1e83836Smrg class bad_expected_access; 74*b1e83836Smrg 75*b1e83836Smrg template<> 76*b1e83836Smrg class bad_expected_access<void> : public exception 77*b1e83836Smrg { 78*b1e83836Smrg protected: 79*b1e83836Smrg bad_expected_access() noexcept { } 80*b1e83836Smrg bad_expected_access(const bad_expected_access&) = default; 81*b1e83836Smrg bad_expected_access(bad_expected_access&&) = default; 82*b1e83836Smrg bad_expected_access& operator=(const bad_expected_access&) = default; 83*b1e83836Smrg bad_expected_access& operator=(bad_expected_access&&) = default; 84*b1e83836Smrg ~bad_expected_access() = default; 85*b1e83836Smrg 86*b1e83836Smrg public: 87*b1e83836Smrg 88*b1e83836Smrg [[nodiscard]] 89*b1e83836Smrg const char* 90*b1e83836Smrg what() const noexcept override 91*b1e83836Smrg { return "bad access to std::expected without expected value"; } 92*b1e83836Smrg }; 93*b1e83836Smrg 94*b1e83836Smrg template<typename _Er> 95*b1e83836Smrg class bad_expected_access : public bad_expected_access<void> { 96*b1e83836Smrg public: 97*b1e83836Smrg explicit 98*b1e83836Smrg bad_expected_access(_Er __e) : _M_unex(std::move(__e)) { } 99*b1e83836Smrg 100*b1e83836Smrg // XXX const char* what() const noexcept override; 101*b1e83836Smrg 102*b1e83836Smrg [[nodiscard]] 103*b1e83836Smrg _Er& 104*b1e83836Smrg error() & noexcept 105*b1e83836Smrg { return _M_unex; } 106*b1e83836Smrg 107*b1e83836Smrg [[nodiscard]] 108*b1e83836Smrg const _Er& 109*b1e83836Smrg error() const & noexcept 110*b1e83836Smrg { return _M_unex; } 111*b1e83836Smrg 112*b1e83836Smrg [[nodiscard]] 113*b1e83836Smrg _Er&& 114*b1e83836Smrg error() && noexcept 115*b1e83836Smrg { return std::move(_M_unex); } 116*b1e83836Smrg 117*b1e83836Smrg [[nodiscard]] 118*b1e83836Smrg const _Er&& 119*b1e83836Smrg error() const && noexcept 120*b1e83836Smrg { return std::move(_M_unex); } 121*b1e83836Smrg 122*b1e83836Smrg private: 123*b1e83836Smrg _Er _M_unex; 124*b1e83836Smrg }; 125*b1e83836Smrg 126*b1e83836Smrg /// Tag type for constructing unexpected values in a std::expected 127*b1e83836Smrg /** 128*b1e83836Smrg * @since C++23 129*b1e83836Smrg */ 130*b1e83836Smrg struct unexpect_t 131*b1e83836Smrg { 132*b1e83836Smrg explicit unexpect_t() = default; 133*b1e83836Smrg }; 134*b1e83836Smrg 135*b1e83836Smrg /// Tag for constructing unexpected values in a std::expected 136*b1e83836Smrg /** 137*b1e83836Smrg * @since C++23 138*b1e83836Smrg */ 139*b1e83836Smrg inline constexpr unexpect_t unexpect{}; 140*b1e83836Smrg 141*b1e83836Smrg/// @cond undoc 142*b1e83836Smrgnamespace __expected 143*b1e83836Smrg{ 144*b1e83836Smrg template<typename _Tp> 145*b1e83836Smrg constexpr bool __is_expected = false; 146*b1e83836Smrg template<typename _Tp, typename _Er> 147*b1e83836Smrg constexpr bool __is_expected<expected<_Tp, _Er>> = true; 148*b1e83836Smrg 149*b1e83836Smrg template<typename _Tp> 150*b1e83836Smrg constexpr bool __is_unexpected = false; 151*b1e83836Smrg template<typename _Tp> 152*b1e83836Smrg constexpr bool __is_unexpected<unexpected<_Tp>> = true; 153*b1e83836Smrg 154*b1e83836Smrg template<typename _Er> 155*b1e83836Smrg concept __can_be_unexpected 156*b1e83836Smrg = is_object_v<_Er> && (!is_array_v<_Er>) 157*b1e83836Smrg && (!__expected::__is_unexpected<_Er>) 158*b1e83836Smrg && (!is_const_v<_Er>) && (!is_volatile_v<_Er>); 159*b1e83836Smrg} 160*b1e83836Smrg/// @endcond 161*b1e83836Smrg 162*b1e83836Smrg template<typename _Er> 163*b1e83836Smrg class unexpected 164*b1e83836Smrg { 165*b1e83836Smrg static_assert( __expected::__can_be_unexpected<_Er> ); 166*b1e83836Smrg 167*b1e83836Smrg public: 168*b1e83836Smrg constexpr unexpected(const unexpected&) = default; 169*b1e83836Smrg constexpr unexpected(unexpected&&) = default; 170*b1e83836Smrg 171*b1e83836Smrg template<typename _Err = _Er> 172*b1e83836Smrg requires (!is_same_v<remove_cvref_t<_Err>, unexpected>) 173*b1e83836Smrg && (!is_same_v<remove_cvref_t<_Err>, in_place_t>) 174*b1e83836Smrg && is_constructible_v<_Er, _Err> 175*b1e83836Smrg constexpr explicit 176*b1e83836Smrg unexpected(_Err&& __e) 177*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, _Err>) 178*b1e83836Smrg : _M_unex(std::forward<_Err>(__e)) 179*b1e83836Smrg { } 180*b1e83836Smrg 181*b1e83836Smrg template<typename... _Args> 182*b1e83836Smrg requires is_constructible_v<_Er, _Args...> 183*b1e83836Smrg constexpr explicit 184*b1e83836Smrg unexpected(in_place_t, _Args&&... __args) 185*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, _Args...>) 186*b1e83836Smrg : _M_unex(std::forward<_Args>(__args)...) 187*b1e83836Smrg { } 188*b1e83836Smrg 189*b1e83836Smrg template<typename _Up, typename... _Args> 190*b1e83836Smrg requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...> 191*b1e83836Smrg constexpr explicit 192*b1e83836Smrg unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 193*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&, 194*b1e83836Smrg _Args...>) 195*b1e83836Smrg : _M_unex(__il, std::forward<_Args>(__args)...) 196*b1e83836Smrg { } 197*b1e83836Smrg 198*b1e83836Smrg constexpr unexpected& operator=(const unexpected&) = default; 199*b1e83836Smrg constexpr unexpected& operator=(unexpected&&) = default; 200*b1e83836Smrg 201*b1e83836Smrg 202*b1e83836Smrg [[nodiscard]] 203*b1e83836Smrg constexpr const _Er& 204*b1e83836Smrg error() const & noexcept { return _M_unex; } 205*b1e83836Smrg 206*b1e83836Smrg [[nodiscard]] 207*b1e83836Smrg constexpr _Er& 208*b1e83836Smrg error() & noexcept { return _M_unex; } 209*b1e83836Smrg 210*b1e83836Smrg [[nodiscard]] 211*b1e83836Smrg constexpr const _Er&& 212*b1e83836Smrg error() const && noexcept { return std::move(_M_unex); } 213*b1e83836Smrg 214*b1e83836Smrg [[nodiscard]] 215*b1e83836Smrg constexpr _Er&& 216*b1e83836Smrg error() && noexcept { return std::move(_M_unex); } 217*b1e83836Smrg 218*b1e83836Smrg constexpr void 219*b1e83836Smrg swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Er>) 220*b1e83836Smrg requires is_swappable_v<_Er> 221*b1e83836Smrg { 222*b1e83836Smrg using std::swap; 223*b1e83836Smrg swap(_M_unex, __other._M_unex); 224*b1e83836Smrg } 225*b1e83836Smrg 226*b1e83836Smrg template<typename _Err> 227*b1e83836Smrg [[nodiscard]] 228*b1e83836Smrg friend constexpr bool 229*b1e83836Smrg operator==(const unexpected& __x, const unexpected<_Err>& __y) 230*b1e83836Smrg { return __x._M_unex == __y.error(); } 231*b1e83836Smrg 232*b1e83836Smrg friend constexpr void 233*b1e83836Smrg swap(unexpected& __x, unexpected& __y) noexcept(noexcept(__x.swap(__y))) 234*b1e83836Smrg requires is_swappable_v<_Er> 235*b1e83836Smrg { __x.swap(__y); } 236*b1e83836Smrg 237*b1e83836Smrg private: 238*b1e83836Smrg _Er _M_unex; 239*b1e83836Smrg }; 240*b1e83836Smrg 241*b1e83836Smrg template<typename _Er> unexpected(_Er) -> unexpected<_Er>; 242*b1e83836Smrg 243*b1e83836Smrg/// @cond undoc 244*b1e83836Smrgnamespace __expected 245*b1e83836Smrg{ 246*b1e83836Smrg template<typename _Tp> 247*b1e83836Smrg struct _Guard 248*b1e83836Smrg { 249*b1e83836Smrg static_assert( is_nothrow_move_constructible_v<_Tp> ); 250*b1e83836Smrg 251*b1e83836Smrg constexpr explicit 252*b1e83836Smrg _Guard(_Tp& __x) 253*b1e83836Smrg : _M_guarded(__builtin_addressof(__x)), _M_tmp(std::move(__x)) // nothrow 254*b1e83836Smrg { std::destroy_at(_M_guarded); } 255*b1e83836Smrg 256*b1e83836Smrg constexpr 257*b1e83836Smrg ~_Guard() 258*b1e83836Smrg { 259*b1e83836Smrg if (_M_guarded) [[unlikely]] 260*b1e83836Smrg std::construct_at(_M_guarded, std::move(_M_tmp)); 261*b1e83836Smrg } 262*b1e83836Smrg 263*b1e83836Smrg _Guard(const _Guard&) = delete; 264*b1e83836Smrg _Guard& operator=(const _Guard&) = delete; 265*b1e83836Smrg 266*b1e83836Smrg constexpr _Tp&& 267*b1e83836Smrg release() noexcept 268*b1e83836Smrg { 269*b1e83836Smrg _M_guarded = nullptr; 270*b1e83836Smrg return std::move(_M_tmp); 271*b1e83836Smrg } 272*b1e83836Smrg 273*b1e83836Smrg private: 274*b1e83836Smrg _Tp* _M_guarded; 275*b1e83836Smrg _Tp _M_tmp; 276*b1e83836Smrg }; 277*b1e83836Smrg 278*b1e83836Smrg // reinit-expected helper from [expected.object.assign] 279*b1e83836Smrg template<typename _Tp, typename _Up, typename _Vp> 280*b1e83836Smrg constexpr void 281*b1e83836Smrg __reinit(_Tp* __newval, _Up* __oldval, _Vp&& __arg) 282*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Tp, _Vp>) 283*b1e83836Smrg { 284*b1e83836Smrg if constexpr (is_nothrow_constructible_v<_Tp, _Vp>) 285*b1e83836Smrg { 286*b1e83836Smrg std::destroy_at(__oldval); 287*b1e83836Smrg std::construct_at(__newval, std::forward<_Vp>(__arg)); 288*b1e83836Smrg } 289*b1e83836Smrg else if constexpr (is_nothrow_move_constructible_v<_Tp>) 290*b1e83836Smrg { 291*b1e83836Smrg _Tp __tmp(std::forward<_Vp>(__arg)); // might throw 292*b1e83836Smrg std::destroy_at(__oldval); 293*b1e83836Smrg std::construct_at(__newval, std::move(__tmp)); 294*b1e83836Smrg } 295*b1e83836Smrg else 296*b1e83836Smrg { 297*b1e83836Smrg _Guard<_Up> __guard(*__oldval); 298*b1e83836Smrg std::construct_at(__newval, std::forward<_Vp>(__arg)); // might throw 299*b1e83836Smrg __guard.release(); 300*b1e83836Smrg } 301*b1e83836Smrg } 302*b1e83836Smrg} 303*b1e83836Smrg/// @endcond 304*b1e83836Smrg 305*b1e83836Smrg template<typename _Tp, typename _Er> 306*b1e83836Smrg class expected 307*b1e83836Smrg { 308*b1e83836Smrg static_assert( ! is_reference_v<_Tp> ); 309*b1e83836Smrg static_assert( ! is_function_v<_Tp> ); 310*b1e83836Smrg static_assert( ! is_same_v<remove_cv_t<_Tp>, in_place_t> ); 311*b1e83836Smrg static_assert( ! is_same_v<remove_cv_t<_Tp>, unexpect_t> ); 312*b1e83836Smrg static_assert( ! __expected::__is_unexpected<remove_cv_t<_Tp>> ); 313*b1e83836Smrg static_assert( __expected::__can_be_unexpected<_Er> ); 314*b1e83836Smrg 315*b1e83836Smrg template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>> 316*b1e83836Smrg static constexpr bool __cons_from_expected 317*b1e83836Smrg = __or_v<is_constructible<_Tp, expected<_Up, _Err>&>, 318*b1e83836Smrg is_constructible<_Tp, expected<_Up, _Err>>, 319*b1e83836Smrg is_constructible<_Tp, const expected<_Up, _Err>&>, 320*b1e83836Smrg is_constructible<_Tp, const expected<_Up, _Err>>, 321*b1e83836Smrg is_convertible<expected<_Up, _Err>&, _Tp>, 322*b1e83836Smrg is_convertible<expected<_Up, _Err>, _Tp>, 323*b1e83836Smrg is_convertible<const expected<_Up, _Err>&, _Tp>, 324*b1e83836Smrg is_convertible<const expected<_Up, _Err>, _Tp>, 325*b1e83836Smrg is_constructible<_Unex, expected<_Up, _Err>&>, 326*b1e83836Smrg is_constructible<_Unex, expected<_Up, _Err>>, 327*b1e83836Smrg is_constructible<_Unex, const expected<_Up, _Err>&>, 328*b1e83836Smrg is_constructible<_Unex, const expected<_Up, _Err>> 329*b1e83836Smrg >; 330*b1e83836Smrg 331*b1e83836Smrg template<typename _Up, typename _Err> 332*b1e83836Smrg constexpr static bool __explicit_conv 333*b1e83836Smrg = __or_v<__not_<is_convertible<_Up, _Tp>>, 334*b1e83836Smrg __not_<is_convertible<_Err, _Er>> 335*b1e83836Smrg >; 336*b1e83836Smrg 337*b1e83836Smrg public: 338*b1e83836Smrg using value_type = _Tp; 339*b1e83836Smrg using error_type = _Er; 340*b1e83836Smrg using unexpected_type = unexpected<_Er>; 341*b1e83836Smrg 342*b1e83836Smrg template<typename _Up> 343*b1e83836Smrg using rebind = expected<_Up, error_type>; 344*b1e83836Smrg 345*b1e83836Smrg constexpr 346*b1e83836Smrg expected() 347*b1e83836Smrg noexcept(is_nothrow_default_constructible_v<_Tp>) 348*b1e83836Smrg requires is_default_constructible_v<_Tp> 349*b1e83836Smrg : _M_val(), _M_has_value(true) 350*b1e83836Smrg { } 351*b1e83836Smrg 352*b1e83836Smrg expected(const expected&) = default; 353*b1e83836Smrg 354*b1e83836Smrg constexpr 355*b1e83836Smrg expected(const expected& __x) 356*b1e83836Smrg noexcept(__and_v<is_nothrow_copy_constructible<_Tp>, 357*b1e83836Smrg is_nothrow_copy_constructible<_Er>>) 358*b1e83836Smrg requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Er> 359*b1e83836Smrg && (!is_trivially_copy_constructible_v<_Tp> 360*b1e83836Smrg || !is_trivially_copy_constructible_v<_Er>) 361*b1e83836Smrg : _M_has_value(__x._M_has_value) 362*b1e83836Smrg { 363*b1e83836Smrg if (_M_has_value) 364*b1e83836Smrg std::construct_at(__builtin_addressof(_M_val), __x._M_val); 365*b1e83836Smrg else 366*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), __x._M_unex); 367*b1e83836Smrg } 368*b1e83836Smrg 369*b1e83836Smrg expected(expected&&) = default; 370*b1e83836Smrg 371*b1e83836Smrg constexpr 372*b1e83836Smrg expected(expected&& __x) 373*b1e83836Smrg noexcept(__and_v<is_nothrow_move_constructible<_Tp>, 374*b1e83836Smrg is_nothrow_move_constructible<_Er>>) 375*b1e83836Smrg requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Er> 376*b1e83836Smrg && (!is_trivially_move_constructible_v<_Tp> 377*b1e83836Smrg || !is_trivially_move_constructible_v<_Er>) 378*b1e83836Smrg : _M_has_value(__x._M_has_value) 379*b1e83836Smrg { 380*b1e83836Smrg if (_M_has_value) 381*b1e83836Smrg std::construct_at(__builtin_addressof(_M_val), 382*b1e83836Smrg std::move(__x)._M_val); 383*b1e83836Smrg else 384*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), 385*b1e83836Smrg std::move(__x)._M_unex); 386*b1e83836Smrg } 387*b1e83836Smrg 388*b1e83836Smrg template<typename _Up, typename _Gr> 389*b1e83836Smrg requires is_constructible_v<_Tp, const _Up&> 390*b1e83836Smrg && is_constructible_v<_Er, const _Gr&> 391*b1e83836Smrg && (!__cons_from_expected<_Up, _Gr>) 392*b1e83836Smrg constexpr explicit(__explicit_conv<const _Up&, const _Gr&>) 393*b1e83836Smrg expected(const expected<_Up, _Gr>& __x) 394*b1e83836Smrg noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>, 395*b1e83836Smrg is_nothrow_constructible<_Er, const _Gr&>>) 396*b1e83836Smrg : _M_has_value(__x._M_has_value) 397*b1e83836Smrg { 398*b1e83836Smrg if (_M_has_value) 399*b1e83836Smrg std::construct_at(__builtin_addressof(_M_val), __x._M_val); 400*b1e83836Smrg else 401*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), __x._M_unex); 402*b1e83836Smrg } 403*b1e83836Smrg 404*b1e83836Smrg template<typename _Up, typename _Gr> 405*b1e83836Smrg requires is_constructible_v<_Tp, _Up> 406*b1e83836Smrg && is_constructible_v<_Er, _Gr> 407*b1e83836Smrg && (!__cons_from_expected<_Up, _Gr>) 408*b1e83836Smrg constexpr explicit(__explicit_conv<_Up, _Gr>) 409*b1e83836Smrg expected(expected<_Up, _Gr>&& __x) 410*b1e83836Smrg noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>, 411*b1e83836Smrg is_nothrow_constructible<_Er, _Gr>>) 412*b1e83836Smrg : _M_has_value(__x._M_has_value) 413*b1e83836Smrg { 414*b1e83836Smrg if (_M_has_value) 415*b1e83836Smrg std::construct_at(__builtin_addressof(_M_val), 416*b1e83836Smrg std::move(__x)._M_val); 417*b1e83836Smrg else 418*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), 419*b1e83836Smrg std::move(__x)._M_unex); 420*b1e83836Smrg } 421*b1e83836Smrg 422*b1e83836Smrg template<typename _Up = _Tp> 423*b1e83836Smrg requires (!is_same_v<remove_cvref_t<_Up>, expected>) 424*b1e83836Smrg && (!is_same_v<remove_cvref_t<_Up>, in_place_t>) 425*b1e83836Smrg && (!__expected::__is_unexpected<remove_cvref_t<_Up>>) 426*b1e83836Smrg && is_constructible_v<_Tp, _Up> 427*b1e83836Smrg constexpr explicit(!is_convertible_v<_Up, _Tp>) 428*b1e83836Smrg expected(_Up&& __v) 429*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Tp, _Up>) 430*b1e83836Smrg : _M_val(std::forward<_Up>(__v)), _M_has_value(true) 431*b1e83836Smrg { } 432*b1e83836Smrg 433*b1e83836Smrg template<typename _Gr = _Er> 434*b1e83836Smrg requires is_constructible_v<_Er, const _Gr&> 435*b1e83836Smrg constexpr explicit(!is_convertible_v<const _Gr&, _Er>) 436*b1e83836Smrg expected(const unexpected<_Gr>& __u) 437*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, const _Gr&>) 438*b1e83836Smrg : _M_unex(__u.error()), _M_has_value(false) 439*b1e83836Smrg { } 440*b1e83836Smrg 441*b1e83836Smrg template<typename _Gr = _Er> 442*b1e83836Smrg requires is_constructible_v<_Er, _Gr> 443*b1e83836Smrg constexpr explicit(!is_convertible_v<_Gr, _Er>) 444*b1e83836Smrg expected(unexpected<_Gr>&& __u) 445*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, _Gr>) 446*b1e83836Smrg : _M_unex(std::move(__u).error()), _M_has_value(false) 447*b1e83836Smrg { } 448*b1e83836Smrg 449*b1e83836Smrg template<typename... _Args> 450*b1e83836Smrg requires is_constructible_v<_Tp, _Args...> 451*b1e83836Smrg constexpr explicit 452*b1e83836Smrg expected(in_place_t, _Args&&... __args) 453*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Tp, _Args...>) 454*b1e83836Smrg : _M_val(std::forward<_Args>(__args)...), _M_has_value(true) 455*b1e83836Smrg { } 456*b1e83836Smrg 457*b1e83836Smrg template<typename _Up, typename... _Args> 458*b1e83836Smrg requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...> 459*b1e83836Smrg constexpr explicit 460*b1e83836Smrg expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 461*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, 462*b1e83836Smrg _Args...>) 463*b1e83836Smrg : _M_val(__il, std::forward<_Args>(__args)...), _M_has_value(true) 464*b1e83836Smrg { } 465*b1e83836Smrg 466*b1e83836Smrg template<typename... _Args> 467*b1e83836Smrg requires is_constructible_v<_Er, _Args...> 468*b1e83836Smrg constexpr explicit 469*b1e83836Smrg expected(unexpect_t, _Args&&... __args) 470*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, _Args...>) 471*b1e83836Smrg : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false) 472*b1e83836Smrg { } 473*b1e83836Smrg 474*b1e83836Smrg template<typename _Up, typename... _Args> 475*b1e83836Smrg requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...> 476*b1e83836Smrg constexpr explicit 477*b1e83836Smrg expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) 478*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&, 479*b1e83836Smrg _Args...>) 480*b1e83836Smrg : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false) 481*b1e83836Smrg { } 482*b1e83836Smrg 483*b1e83836Smrg constexpr ~expected() = default; 484*b1e83836Smrg 485*b1e83836Smrg constexpr ~expected() 486*b1e83836Smrg requires (!is_trivially_destructible_v<_Tp>) 487*b1e83836Smrg || (!is_trivially_destructible_v<_Er>) 488*b1e83836Smrg { 489*b1e83836Smrg if (_M_has_value) 490*b1e83836Smrg std::destroy_at(__builtin_addressof(_M_val)); 491*b1e83836Smrg else 492*b1e83836Smrg std::destroy_at(__builtin_addressof(_M_unex)); 493*b1e83836Smrg } 494*b1e83836Smrg 495*b1e83836Smrg // assignment 496*b1e83836Smrg 497*b1e83836Smrg expected& operator=(const expected&) = delete; 498*b1e83836Smrg 499*b1e83836Smrg constexpr expected& 500*b1e83836Smrg operator=(const expected& __x) 501*b1e83836Smrg noexcept(__and_v<is_nothrow_copy_constructible<_Tp>, 502*b1e83836Smrg is_nothrow_copy_constructible<_Er>, 503*b1e83836Smrg is_nothrow_copy_assignable<_Tp>, 504*b1e83836Smrg is_nothrow_copy_assignable<_Er>>) 505*b1e83836Smrg requires is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp> 506*b1e83836Smrg && is_copy_assignable_v<_Er> && is_copy_constructible_v<_Er> 507*b1e83836Smrg && (is_nothrow_move_constructible_v<_Tp> 508*b1e83836Smrg || is_nothrow_move_constructible_v<_Er>) 509*b1e83836Smrg { 510*b1e83836Smrg if (__x._M_has_value) 511*b1e83836Smrg this->_M_assign_val(__x._M_val); 512*b1e83836Smrg else 513*b1e83836Smrg this->_M_assign_unex(__x._M_unex); 514*b1e83836Smrg return *this; 515*b1e83836Smrg } 516*b1e83836Smrg 517*b1e83836Smrg constexpr expected& 518*b1e83836Smrg operator=(expected&& __x) 519*b1e83836Smrg noexcept(__and_v<is_nothrow_move_constructible<_Tp>, 520*b1e83836Smrg is_nothrow_move_constructible<_Er>, 521*b1e83836Smrg is_nothrow_move_assignable<_Tp>, 522*b1e83836Smrg is_nothrow_move_assignable<_Er>>) 523*b1e83836Smrg requires is_move_assignable_v<_Tp> && is_move_constructible_v<_Tp> 524*b1e83836Smrg && is_move_assignable_v<_Er> && is_move_constructible_v<_Er> 525*b1e83836Smrg && (is_nothrow_move_constructible_v<_Tp> 526*b1e83836Smrg || is_nothrow_move_constructible_v<_Er>) 527*b1e83836Smrg { 528*b1e83836Smrg if (__x._M_has_value) 529*b1e83836Smrg _M_assign_val(std::move(__x._M_val)); 530*b1e83836Smrg else 531*b1e83836Smrg _M_assign_unex(std::move(__x._M_unex)); 532*b1e83836Smrg return *this; 533*b1e83836Smrg } 534*b1e83836Smrg 535*b1e83836Smrg template<typename _Up = _Tp> 536*b1e83836Smrg requires (!is_same_v<expected, remove_cvref_t<_Up>>) 537*b1e83836Smrg && (!__expected::__is_unexpected<remove_cvref_t<_Up>>) 538*b1e83836Smrg && is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up> 539*b1e83836Smrg && (is_nothrow_constructible_v<_Tp, _Up> 540*b1e83836Smrg || is_nothrow_move_constructible_v<_Tp> 541*b1e83836Smrg || is_nothrow_move_constructible_v<_Er>) 542*b1e83836Smrg constexpr expected& 543*b1e83836Smrg operator=(_Up&& __v) 544*b1e83836Smrg { 545*b1e83836Smrg _M_assign_val(std::forward<_Up>(__v)); 546*b1e83836Smrg return *this; 547*b1e83836Smrg } 548*b1e83836Smrg 549*b1e83836Smrg template<typename _Gr> 550*b1e83836Smrg requires is_constructible_v<_Er, const _Gr&> 551*b1e83836Smrg && is_assignable_v<_Er&, const _Gr&> 552*b1e83836Smrg && (is_nothrow_constructible_v<_Er, const _Gr&> 553*b1e83836Smrg || is_nothrow_move_constructible_v<_Tp> 554*b1e83836Smrg || is_nothrow_move_constructible_v<_Er>) 555*b1e83836Smrg constexpr expected& 556*b1e83836Smrg operator=(const unexpected<_Gr>& __e) 557*b1e83836Smrg { 558*b1e83836Smrg _M_assign_unex(__e.error()); 559*b1e83836Smrg return *this; 560*b1e83836Smrg } 561*b1e83836Smrg 562*b1e83836Smrg template<typename _Gr> 563*b1e83836Smrg requires is_constructible_v<_Er, _Gr> 564*b1e83836Smrg && is_assignable_v<_Er&, _Gr> 565*b1e83836Smrg && (is_nothrow_constructible_v<_Er, _Gr> 566*b1e83836Smrg || is_nothrow_move_constructible_v<_Tp> 567*b1e83836Smrg || is_nothrow_move_constructible_v<_Er>) 568*b1e83836Smrg constexpr expected& 569*b1e83836Smrg operator=(unexpected<_Gr>&& __e) 570*b1e83836Smrg { 571*b1e83836Smrg _M_assign_unex(std::move(__e).error()); 572*b1e83836Smrg return *this; 573*b1e83836Smrg } 574*b1e83836Smrg 575*b1e83836Smrg // modifiers 576*b1e83836Smrg 577*b1e83836Smrg template<typename... _Args> 578*b1e83836Smrg requires is_nothrow_constructible_v<_Tp, _Args...> 579*b1e83836Smrg constexpr _Tp& 580*b1e83836Smrg emplace(_Args&&... __args) noexcept 581*b1e83836Smrg { 582*b1e83836Smrg if (_M_has_value) 583*b1e83836Smrg std::destroy_at(__builtin_addressof(_M_val)); 584*b1e83836Smrg else 585*b1e83836Smrg { 586*b1e83836Smrg std::destroy_at(__builtin_addressof(_M_unex)); 587*b1e83836Smrg _M_has_value = true; 588*b1e83836Smrg } 589*b1e83836Smrg std::construct_at(__builtin_addressof(_M_val), 590*b1e83836Smrg std::forward<_Args>(__args)...); 591*b1e83836Smrg return _M_val; 592*b1e83836Smrg } 593*b1e83836Smrg 594*b1e83836Smrg template<typename _Up, typename... _Args> 595*b1e83836Smrg requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, 596*b1e83836Smrg _Args...> 597*b1e83836Smrg constexpr _Tp& 598*b1e83836Smrg emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept 599*b1e83836Smrg { 600*b1e83836Smrg if (_M_has_value) 601*b1e83836Smrg std::destroy_at(__builtin_addressof(_M_val)); 602*b1e83836Smrg else 603*b1e83836Smrg { 604*b1e83836Smrg std::destroy_at(__builtin_addressof(_M_unex)); 605*b1e83836Smrg _M_has_value = true; 606*b1e83836Smrg } 607*b1e83836Smrg std::construct_at(__builtin_addressof(_M_val), 608*b1e83836Smrg __il, std::forward<_Args>(__args)...); 609*b1e83836Smrg return _M_val; 610*b1e83836Smrg } 611*b1e83836Smrg 612*b1e83836Smrg // swap 613*b1e83836Smrg constexpr void 614*b1e83836Smrg swap(expected& __x) 615*b1e83836Smrg noexcept(__and_v<is_nothrow_move_constructible<_Tp>, 616*b1e83836Smrg is_nothrow_move_constructible<_Er>, 617*b1e83836Smrg is_nothrow_swappable<_Tp&>, 618*b1e83836Smrg is_nothrow_swappable<_Er&>>) 619*b1e83836Smrg requires is_swappable_v<_Tp> && is_swappable_v<_Er> 620*b1e83836Smrg && is_move_constructible_v<_Tp> 621*b1e83836Smrg && is_move_constructible_v<_Er> 622*b1e83836Smrg && (is_nothrow_move_constructible_v<_Tp> 623*b1e83836Smrg || is_nothrow_move_constructible_v<_Er>) 624*b1e83836Smrg { 625*b1e83836Smrg if (_M_has_value) 626*b1e83836Smrg { 627*b1e83836Smrg if (__x._M_has_value) 628*b1e83836Smrg { 629*b1e83836Smrg using std::swap; 630*b1e83836Smrg swap(_M_val, __x._M_val); 631*b1e83836Smrg } 632*b1e83836Smrg else 633*b1e83836Smrg this->_M_swap_val_unex(__x); 634*b1e83836Smrg } 635*b1e83836Smrg else 636*b1e83836Smrg { 637*b1e83836Smrg if (__x._M_has_value) 638*b1e83836Smrg __x._M_swap_val_unex(*this); 639*b1e83836Smrg else 640*b1e83836Smrg { 641*b1e83836Smrg using std::swap; 642*b1e83836Smrg swap(_M_unex, __x._M_unex); 643*b1e83836Smrg } 644*b1e83836Smrg } 645*b1e83836Smrg } 646*b1e83836Smrg 647*b1e83836Smrg // observers 648*b1e83836Smrg 649*b1e83836Smrg [[nodiscard]] 650*b1e83836Smrg constexpr const _Tp* 651*b1e83836Smrg operator->() const noexcept 652*b1e83836Smrg { 653*b1e83836Smrg __glibcxx_assert(_M_has_value); 654*b1e83836Smrg return __builtin_addressof(_M_val); 655*b1e83836Smrg } 656*b1e83836Smrg 657*b1e83836Smrg [[nodiscard]] 658*b1e83836Smrg constexpr _Tp* 659*b1e83836Smrg operator->() noexcept 660*b1e83836Smrg { 661*b1e83836Smrg __glibcxx_assert(_M_has_value); 662*b1e83836Smrg return __builtin_addressof(_M_val); 663*b1e83836Smrg } 664*b1e83836Smrg 665*b1e83836Smrg [[nodiscard]] 666*b1e83836Smrg constexpr const _Tp& 667*b1e83836Smrg operator*() const & noexcept 668*b1e83836Smrg { 669*b1e83836Smrg __glibcxx_assert(_M_has_value); 670*b1e83836Smrg return _M_val; 671*b1e83836Smrg } 672*b1e83836Smrg 673*b1e83836Smrg [[nodiscard]] 674*b1e83836Smrg constexpr _Tp& 675*b1e83836Smrg operator*() & noexcept 676*b1e83836Smrg { 677*b1e83836Smrg __glibcxx_assert(_M_has_value); 678*b1e83836Smrg return _M_val; 679*b1e83836Smrg } 680*b1e83836Smrg 681*b1e83836Smrg [[nodiscard]] 682*b1e83836Smrg constexpr const _Tp&& 683*b1e83836Smrg operator*() const && noexcept 684*b1e83836Smrg { 685*b1e83836Smrg __glibcxx_assert(_M_has_value); 686*b1e83836Smrg return std::move(_M_val); 687*b1e83836Smrg } 688*b1e83836Smrg 689*b1e83836Smrg [[nodiscard]] 690*b1e83836Smrg constexpr _Tp&& 691*b1e83836Smrg operator*() && noexcept 692*b1e83836Smrg { 693*b1e83836Smrg __glibcxx_assert(_M_has_value); 694*b1e83836Smrg return std::move(_M_val); 695*b1e83836Smrg } 696*b1e83836Smrg 697*b1e83836Smrg [[nodiscard]] 698*b1e83836Smrg constexpr explicit 699*b1e83836Smrg operator bool() const noexcept { return _M_has_value; } 700*b1e83836Smrg 701*b1e83836Smrg [[nodiscard]] 702*b1e83836Smrg constexpr bool has_value() const noexcept { return _M_has_value; } 703*b1e83836Smrg 704*b1e83836Smrg constexpr const _Tp& 705*b1e83836Smrg value() const & 706*b1e83836Smrg { 707*b1e83836Smrg if (_M_has_value) [[likely]] 708*b1e83836Smrg return _M_val; 709*b1e83836Smrg _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex)); 710*b1e83836Smrg } 711*b1e83836Smrg 712*b1e83836Smrg constexpr _Tp& 713*b1e83836Smrg value() & 714*b1e83836Smrg { 715*b1e83836Smrg if (_M_has_value) [[likely]] 716*b1e83836Smrg return _M_val; 717*b1e83836Smrg const auto& __unex = _M_unex; 718*b1e83836Smrg _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(__unex)); 719*b1e83836Smrg } 720*b1e83836Smrg 721*b1e83836Smrg constexpr const _Tp&& 722*b1e83836Smrg value() const && 723*b1e83836Smrg { 724*b1e83836Smrg if (_M_has_value) [[likely]] 725*b1e83836Smrg return std::move(_M_val); 726*b1e83836Smrg _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>( 727*b1e83836Smrg std::move(_M_unex))); 728*b1e83836Smrg } 729*b1e83836Smrg 730*b1e83836Smrg constexpr _Tp&& 731*b1e83836Smrg value() && 732*b1e83836Smrg { 733*b1e83836Smrg if (_M_has_value) [[likely]] 734*b1e83836Smrg return std::move(_M_val); 735*b1e83836Smrg _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>( 736*b1e83836Smrg std::move(_M_unex))); 737*b1e83836Smrg } 738*b1e83836Smrg 739*b1e83836Smrg constexpr const _Er& 740*b1e83836Smrg error() const & noexcept 741*b1e83836Smrg { 742*b1e83836Smrg __glibcxx_assert(!_M_has_value); 743*b1e83836Smrg return _M_unex; 744*b1e83836Smrg } 745*b1e83836Smrg 746*b1e83836Smrg constexpr _Er& 747*b1e83836Smrg error() & noexcept 748*b1e83836Smrg { 749*b1e83836Smrg __glibcxx_assert(!_M_has_value); 750*b1e83836Smrg return _M_unex; 751*b1e83836Smrg } 752*b1e83836Smrg 753*b1e83836Smrg constexpr const _Er&& 754*b1e83836Smrg error() const && noexcept 755*b1e83836Smrg { 756*b1e83836Smrg __glibcxx_assert(!_M_has_value); 757*b1e83836Smrg return std::move(_M_unex); 758*b1e83836Smrg } 759*b1e83836Smrg 760*b1e83836Smrg constexpr _Er&& 761*b1e83836Smrg error() && noexcept 762*b1e83836Smrg { 763*b1e83836Smrg __glibcxx_assert(!_M_has_value); 764*b1e83836Smrg return std::move(_M_unex); 765*b1e83836Smrg } 766*b1e83836Smrg 767*b1e83836Smrg template<typename _Up> 768*b1e83836Smrg constexpr _Tp 769*b1e83836Smrg value_or(_Up&& __v) const & 770*b1e83836Smrg noexcept(__and_v<is_nothrow_copy_constructible<_Tp>, 771*b1e83836Smrg is_nothrow_convertible<_Up, _Tp>>) 772*b1e83836Smrg { 773*b1e83836Smrg static_assert( is_copy_constructible_v<_Tp> ); 774*b1e83836Smrg static_assert( is_convertible_v<_Up, _Tp> ); 775*b1e83836Smrg 776*b1e83836Smrg if (_M_has_value) 777*b1e83836Smrg return _M_val; 778*b1e83836Smrg return static_cast<_Tp>(std::forward<_Up>(__v)); 779*b1e83836Smrg } 780*b1e83836Smrg 781*b1e83836Smrg template<typename _Up> 782*b1e83836Smrg constexpr _Tp 783*b1e83836Smrg value_or(_Up&& __v) && 784*b1e83836Smrg noexcept(__and_v<is_nothrow_move_constructible<_Tp>, 785*b1e83836Smrg is_nothrow_convertible<_Up, _Tp>>) 786*b1e83836Smrg { 787*b1e83836Smrg static_assert( is_move_constructible_v<_Tp> ); 788*b1e83836Smrg static_assert( is_convertible_v<_Up, _Tp> ); 789*b1e83836Smrg 790*b1e83836Smrg if (_M_has_value) 791*b1e83836Smrg return std::move(_M_val); 792*b1e83836Smrg return static_cast<_Tp>(std::forward<_Up>(__v)); 793*b1e83836Smrg } 794*b1e83836Smrg 795*b1e83836Smrg // equality operators 796*b1e83836Smrg 797*b1e83836Smrg template<typename _Up, typename _Er2> 798*b1e83836Smrg requires (!is_void_v<_Up>) 799*b1e83836Smrg friend constexpr bool 800*b1e83836Smrg operator==(const expected& __x, const expected<_Up, _Er2>& __y) 801*b1e83836Smrg // FIXME: noexcept(noexcept(bool(*__x == *__y)) 802*b1e83836Smrg // && noexcept(bool(__x.error() == __y.error()))) 803*b1e83836Smrg { 804*b1e83836Smrg if (__x.has_value()) 805*b1e83836Smrg return __y.has_value() && bool(*__x == *__y); 806*b1e83836Smrg else 807*b1e83836Smrg return !__y.has_value() && bool(__x.error() == __y.error()); 808*b1e83836Smrg } 809*b1e83836Smrg 810*b1e83836Smrg template<typename _Up> 811*b1e83836Smrg friend constexpr bool 812*b1e83836Smrg operator==(const expected& __x, const _Up& __v) 813*b1e83836Smrg // FIXME: noexcept(noexcept(bool(*__x == __v))) 814*b1e83836Smrg { return __x.has_value() && bool(*__x == __v); } 815*b1e83836Smrg 816*b1e83836Smrg template<typename _Er2> 817*b1e83836Smrg friend constexpr bool 818*b1e83836Smrg operator==(const expected& __x, const unexpected<_Er2>& __e) 819*b1e83836Smrg // FIXME: noexcept(noexcept(bool(__x.error() == __e.error()))) 820*b1e83836Smrg { return !__x.has_value() && bool(__x.error() == __e.error()); } 821*b1e83836Smrg 822*b1e83836Smrg friend constexpr void 823*b1e83836Smrg swap(expected& __x, expected& __y) 824*b1e83836Smrg noexcept(noexcept(__x.swap(__y))) 825*b1e83836Smrg requires requires {__x.swap(__y);} 826*b1e83836Smrg { __x.swap(__y); } 827*b1e83836Smrg 828*b1e83836Smrg private: 829*b1e83836Smrg template<typename, typename> friend class expected; 830*b1e83836Smrg 831*b1e83836Smrg template<typename _Vp> 832*b1e83836Smrg constexpr void 833*b1e83836Smrg _M_assign_val(_Vp&& __v) 834*b1e83836Smrg { 835*b1e83836Smrg if (_M_has_value) 836*b1e83836Smrg _M_val = std::forward<_Vp>(__v); 837*b1e83836Smrg else 838*b1e83836Smrg { 839*b1e83836Smrg __expected::__reinit(__builtin_addressof(_M_val), 840*b1e83836Smrg __builtin_addressof(_M_unex), 841*b1e83836Smrg std::forward<_Vp>(__v)); 842*b1e83836Smrg _M_has_value = true; 843*b1e83836Smrg } 844*b1e83836Smrg } 845*b1e83836Smrg 846*b1e83836Smrg template<typename _Vp> 847*b1e83836Smrg constexpr void 848*b1e83836Smrg _M_assign_unex(_Vp&& __v) 849*b1e83836Smrg { 850*b1e83836Smrg if (_M_has_value) 851*b1e83836Smrg { 852*b1e83836Smrg __expected::__reinit(__builtin_addressof(_M_unex), 853*b1e83836Smrg __builtin_addressof(_M_val), 854*b1e83836Smrg std::forward<_Vp>(__v)); 855*b1e83836Smrg _M_has_value = false; 856*b1e83836Smrg } 857*b1e83836Smrg else 858*b1e83836Smrg _M_unex = std::forward<_Vp>(__v); 859*b1e83836Smrg } 860*b1e83836Smrg 861*b1e83836Smrg // Swap two expected objects when only one has a value. 862*b1e83836Smrg // Precondition: this->_M_has_value && !__rhs._M_has_value 863*b1e83836Smrg constexpr void 864*b1e83836Smrg _M_swap_val_unex(expected& __rhs) 865*b1e83836Smrg noexcept(__and_v<is_nothrow_move_constructible<_Er>, 866*b1e83836Smrg is_nothrow_move_constructible<_Tp>>) 867*b1e83836Smrg { 868*b1e83836Smrg if constexpr (is_nothrow_move_constructible_v<_Er>) 869*b1e83836Smrg { 870*b1e83836Smrg __expected::_Guard<_Er> __guard(__rhs._M_unex); 871*b1e83836Smrg std::construct_at(__builtin_addressof(__rhs._M_val), 872*b1e83836Smrg std::move(_M_val)); // might throw 873*b1e83836Smrg __rhs._M_has_value = true; 874*b1e83836Smrg std::destroy_at(__builtin_addressof(_M_val)); 875*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), 876*b1e83836Smrg __guard.release()); 877*b1e83836Smrg _M_has_value = false; 878*b1e83836Smrg } 879*b1e83836Smrg else 880*b1e83836Smrg { 881*b1e83836Smrg __expected::_Guard<_Tp> __guard(_M_val); 882*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), 883*b1e83836Smrg std::move(__rhs._M_unex)); // might throw 884*b1e83836Smrg _M_has_value = false; 885*b1e83836Smrg std::destroy_at(__builtin_addressof(__rhs._M_unex)); 886*b1e83836Smrg std::construct_at(__builtin_addressof(__rhs._M_val), 887*b1e83836Smrg __guard.release()); 888*b1e83836Smrg __rhs._M_has_value = true; 889*b1e83836Smrg } 890*b1e83836Smrg } 891*b1e83836Smrg 892*b1e83836Smrg union { 893*b1e83836Smrg _Tp _M_val; 894*b1e83836Smrg _Er _M_unex; 895*b1e83836Smrg }; 896*b1e83836Smrg 897*b1e83836Smrg bool _M_has_value; 898*b1e83836Smrg }; 899*b1e83836Smrg 900*b1e83836Smrg // Partial specialization for std::expected<cv void, E> 901*b1e83836Smrg template<typename _Tp, typename _Er> requires is_void_v<_Tp> 902*b1e83836Smrg class expected<_Tp, _Er> 903*b1e83836Smrg { 904*b1e83836Smrg static_assert( __expected::__can_be_unexpected<_Er> ); 905*b1e83836Smrg 906*b1e83836Smrg template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>> 907*b1e83836Smrg static constexpr bool __cons_from_expected 908*b1e83836Smrg = __or_v<is_constructible<_Unex, expected<_Up, _Err>&>, 909*b1e83836Smrg is_constructible<_Unex, expected<_Up, _Err>>, 910*b1e83836Smrg is_constructible<_Unex, const expected<_Up, _Err>&>, 911*b1e83836Smrg is_constructible<_Unex, const expected<_Up, _Err>> 912*b1e83836Smrg >; 913*b1e83836Smrg 914*b1e83836Smrg public: 915*b1e83836Smrg using value_type = _Tp; 916*b1e83836Smrg using error_type = _Er; 917*b1e83836Smrg using unexpected_type = unexpected<_Er>; 918*b1e83836Smrg 919*b1e83836Smrg template<typename _Up> 920*b1e83836Smrg using rebind = expected<_Up, error_type>; 921*b1e83836Smrg 922*b1e83836Smrg constexpr 923*b1e83836Smrg expected() noexcept 924*b1e83836Smrg : _M_void(), _M_has_value(true) 925*b1e83836Smrg { } 926*b1e83836Smrg 927*b1e83836Smrg expected(const expected&) = default; 928*b1e83836Smrg 929*b1e83836Smrg constexpr 930*b1e83836Smrg expected(const expected& __x) 931*b1e83836Smrg noexcept(is_nothrow_copy_constructible_v<_Er>) 932*b1e83836Smrg requires is_copy_constructible_v<_Er> 933*b1e83836Smrg && (!is_trivially_copy_constructible_v<_Er>) 934*b1e83836Smrg : _M_void(), _M_has_value(__x._M_has_value) 935*b1e83836Smrg { 936*b1e83836Smrg if (!_M_has_value) 937*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), __x._M_unex); 938*b1e83836Smrg } 939*b1e83836Smrg 940*b1e83836Smrg expected(expected&&) = default; 941*b1e83836Smrg 942*b1e83836Smrg constexpr 943*b1e83836Smrg expected(expected&& __x) 944*b1e83836Smrg noexcept(is_nothrow_move_constructible_v<_Er>) 945*b1e83836Smrg requires is_move_constructible_v<_Er> 946*b1e83836Smrg && (!is_trivially_move_constructible_v<_Er>) 947*b1e83836Smrg : _M_void(), _M_has_value(__x._M_has_value) 948*b1e83836Smrg { 949*b1e83836Smrg if (!_M_has_value) 950*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), 951*b1e83836Smrg std::move(__x)._M_unex); 952*b1e83836Smrg } 953*b1e83836Smrg 954*b1e83836Smrg template<typename _Up, typename _Gr> 955*b1e83836Smrg requires is_void_v<_Up> 956*b1e83836Smrg && is_constructible_v<_Er, const _Gr&> 957*b1e83836Smrg && (!__cons_from_expected<_Up, _Gr>) 958*b1e83836Smrg constexpr explicit(!is_convertible_v<const _Gr&, _Er>) 959*b1e83836Smrg expected(const expected<_Up, _Gr>& __x) 960*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, const _Gr&>) 961*b1e83836Smrg : _M_void(), _M_has_value(__x._M_has_value) 962*b1e83836Smrg { 963*b1e83836Smrg if (!_M_has_value) 964*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), __x._M_unex); 965*b1e83836Smrg } 966*b1e83836Smrg 967*b1e83836Smrg template<typename _Up, typename _Gr> 968*b1e83836Smrg requires is_void_v<_Up> 969*b1e83836Smrg && is_constructible_v<_Er, _Gr> 970*b1e83836Smrg && (!__cons_from_expected<_Up, _Gr>) 971*b1e83836Smrg constexpr explicit(!is_convertible_v<_Gr, _Er>) 972*b1e83836Smrg expected(expected<_Up, _Gr>&& __x) 973*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, _Gr>) 974*b1e83836Smrg : _M_void(), _M_has_value(__x._M_has_value) 975*b1e83836Smrg { 976*b1e83836Smrg if (!_M_has_value) 977*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), 978*b1e83836Smrg std::move(__x)._M_unex); 979*b1e83836Smrg } 980*b1e83836Smrg 981*b1e83836Smrg template<typename _Gr = _Er> 982*b1e83836Smrg requires is_constructible_v<_Er, const _Gr&> 983*b1e83836Smrg constexpr explicit(!is_convertible_v<const _Gr&, _Er>) 984*b1e83836Smrg expected(const unexpected<_Gr>& __u) 985*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, const _Gr&>) 986*b1e83836Smrg : _M_unex(__u.error()), _M_has_value(false) 987*b1e83836Smrg { } 988*b1e83836Smrg 989*b1e83836Smrg template<typename _Gr = _Er> 990*b1e83836Smrg requires is_constructible_v<_Er, _Gr> 991*b1e83836Smrg constexpr explicit(!is_convertible_v<_Gr, _Er>) 992*b1e83836Smrg expected(unexpected<_Gr>&& __u) 993*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, _Gr>) 994*b1e83836Smrg : _M_unex(std::move(__u).error()), _M_has_value(false) 995*b1e83836Smrg { } 996*b1e83836Smrg 997*b1e83836Smrg constexpr explicit 998*b1e83836Smrg expected(in_place_t) noexcept 999*b1e83836Smrg : expected() 1000*b1e83836Smrg { } 1001*b1e83836Smrg 1002*b1e83836Smrg template<typename... _Args> 1003*b1e83836Smrg requires is_constructible_v<_Er, _Args...> 1004*b1e83836Smrg constexpr explicit 1005*b1e83836Smrg expected(unexpect_t, _Args&&... __args) 1006*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, _Args...>) 1007*b1e83836Smrg : _M_unex(std::forward<_Args>(__args)...), _M_has_value(false) 1008*b1e83836Smrg { } 1009*b1e83836Smrg 1010*b1e83836Smrg template<typename _Up, typename... _Args> 1011*b1e83836Smrg requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...> 1012*b1e83836Smrg constexpr explicit 1013*b1e83836Smrg expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) 1014*b1e83836Smrg noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&, 1015*b1e83836Smrg _Args...>) 1016*b1e83836Smrg : _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false) 1017*b1e83836Smrg { } 1018*b1e83836Smrg 1019*b1e83836Smrg constexpr ~expected() = default; 1020*b1e83836Smrg 1021*b1e83836Smrg constexpr ~expected() requires (!is_trivially_destructible_v<_Er>) 1022*b1e83836Smrg { 1023*b1e83836Smrg if (!_M_has_value) 1024*b1e83836Smrg std::destroy_at(__builtin_addressof(_M_unex)); 1025*b1e83836Smrg } 1026*b1e83836Smrg 1027*b1e83836Smrg // assignment 1028*b1e83836Smrg 1029*b1e83836Smrg expected& operator=(const expected&) = delete; 1030*b1e83836Smrg 1031*b1e83836Smrg constexpr expected& 1032*b1e83836Smrg operator=(const expected& __x) 1033*b1e83836Smrg noexcept(__and_v<is_nothrow_copy_constructible<_Er>, 1034*b1e83836Smrg is_nothrow_copy_assignable<_Er>>) 1035*b1e83836Smrg requires is_copy_constructible_v<_Er> 1036*b1e83836Smrg && is_copy_assignable_v<_Er> 1037*b1e83836Smrg { 1038*b1e83836Smrg if (__x._M_has_value) 1039*b1e83836Smrg emplace(); 1040*b1e83836Smrg else 1041*b1e83836Smrg _M_assign_unex(__x._M_unex); 1042*b1e83836Smrg return *this; 1043*b1e83836Smrg } 1044*b1e83836Smrg 1045*b1e83836Smrg constexpr expected& 1046*b1e83836Smrg operator=(expected&& __x) 1047*b1e83836Smrg noexcept(__and_v<is_nothrow_move_constructible<_Er>, 1048*b1e83836Smrg is_nothrow_move_assignable<_Er>>) 1049*b1e83836Smrg requires is_move_constructible_v<_Er> 1050*b1e83836Smrg && is_move_assignable_v<_Er> 1051*b1e83836Smrg { 1052*b1e83836Smrg if (__x._M_has_value) 1053*b1e83836Smrg emplace(); 1054*b1e83836Smrg else 1055*b1e83836Smrg _M_assign_unex(std::move(__x._M_unex)); 1056*b1e83836Smrg return *this; 1057*b1e83836Smrg } 1058*b1e83836Smrg 1059*b1e83836Smrg template<typename _Gr> 1060*b1e83836Smrg requires is_constructible_v<_Er, const _Gr&> 1061*b1e83836Smrg && is_assignable_v<_Er&, const _Gr&> 1062*b1e83836Smrg constexpr expected& 1063*b1e83836Smrg operator=(const unexpected<_Gr>& __e) 1064*b1e83836Smrg { 1065*b1e83836Smrg _M_assign_unex(__e.error()); 1066*b1e83836Smrg return *this; 1067*b1e83836Smrg } 1068*b1e83836Smrg 1069*b1e83836Smrg template<typename _Gr> 1070*b1e83836Smrg requires is_constructible_v<_Er, _Gr> 1071*b1e83836Smrg && is_assignable_v<_Er&, _Gr> 1072*b1e83836Smrg constexpr expected& 1073*b1e83836Smrg operator=(unexpected<_Gr>&& __e) 1074*b1e83836Smrg { 1075*b1e83836Smrg _M_assign_unex(std::move(__e.error())); 1076*b1e83836Smrg return *this; 1077*b1e83836Smrg } 1078*b1e83836Smrg 1079*b1e83836Smrg // modifiers 1080*b1e83836Smrg 1081*b1e83836Smrg constexpr void 1082*b1e83836Smrg emplace() noexcept 1083*b1e83836Smrg { 1084*b1e83836Smrg if (!_M_has_value) 1085*b1e83836Smrg { 1086*b1e83836Smrg std::destroy_at(__builtin_addressof(_M_unex)); 1087*b1e83836Smrg _M_has_value = true; 1088*b1e83836Smrg } 1089*b1e83836Smrg } 1090*b1e83836Smrg 1091*b1e83836Smrg // swap 1092*b1e83836Smrg constexpr void 1093*b1e83836Smrg swap(expected& __x) 1094*b1e83836Smrg noexcept(__and_v<is_nothrow_swappable<_Er&>, 1095*b1e83836Smrg is_nothrow_move_constructible<_Er>>) 1096*b1e83836Smrg requires is_swappable_v<_Er> && is_move_constructible_v<_Er> 1097*b1e83836Smrg { 1098*b1e83836Smrg if (_M_has_value) 1099*b1e83836Smrg { 1100*b1e83836Smrg if (!__x._M_has_value) 1101*b1e83836Smrg { 1102*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), 1103*b1e83836Smrg std::move(__x._M_unex)); // might throw 1104*b1e83836Smrg std::destroy_at(__builtin_addressof(__x._M_unex)); 1105*b1e83836Smrg _M_has_value = false; 1106*b1e83836Smrg __x._M_has_value = true; 1107*b1e83836Smrg } 1108*b1e83836Smrg } 1109*b1e83836Smrg else 1110*b1e83836Smrg { 1111*b1e83836Smrg if (__x._M_has_value) 1112*b1e83836Smrg { 1113*b1e83836Smrg std::construct_at(__builtin_addressof(__x._M_unex), 1114*b1e83836Smrg std::move(_M_unex)); // might throw 1115*b1e83836Smrg std::destroy_at(__builtin_addressof(_M_unex)); 1116*b1e83836Smrg _M_has_value = true; 1117*b1e83836Smrg __x._M_has_value = false; 1118*b1e83836Smrg } 1119*b1e83836Smrg else 1120*b1e83836Smrg { 1121*b1e83836Smrg using std::swap; 1122*b1e83836Smrg swap(_M_unex, __x._M_unex); 1123*b1e83836Smrg } 1124*b1e83836Smrg } 1125*b1e83836Smrg } 1126*b1e83836Smrg 1127*b1e83836Smrg // observers 1128*b1e83836Smrg 1129*b1e83836Smrg [[nodiscard]] 1130*b1e83836Smrg constexpr explicit 1131*b1e83836Smrg operator bool() const noexcept { return _M_has_value; } 1132*b1e83836Smrg 1133*b1e83836Smrg [[nodiscard]] 1134*b1e83836Smrg constexpr bool has_value() const noexcept { return _M_has_value; } 1135*b1e83836Smrg 1136*b1e83836Smrg constexpr void 1137*b1e83836Smrg operator*() const noexcept { __glibcxx_assert(_M_has_value); } 1138*b1e83836Smrg 1139*b1e83836Smrg constexpr void 1140*b1e83836Smrg value() const& 1141*b1e83836Smrg { 1142*b1e83836Smrg if (_M_has_value) [[likely]] 1143*b1e83836Smrg return; 1144*b1e83836Smrg _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex)); 1145*b1e83836Smrg } 1146*b1e83836Smrg 1147*b1e83836Smrg constexpr void 1148*b1e83836Smrg value() && 1149*b1e83836Smrg { 1150*b1e83836Smrg if (_M_has_value) [[likely]] 1151*b1e83836Smrg return; 1152*b1e83836Smrg _GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex))); 1153*b1e83836Smrg } 1154*b1e83836Smrg 1155*b1e83836Smrg constexpr const _Er& 1156*b1e83836Smrg error() const & noexcept 1157*b1e83836Smrg { 1158*b1e83836Smrg __glibcxx_assert(!_M_has_value); 1159*b1e83836Smrg return _M_unex; 1160*b1e83836Smrg } 1161*b1e83836Smrg 1162*b1e83836Smrg constexpr _Er& 1163*b1e83836Smrg error() & noexcept 1164*b1e83836Smrg { 1165*b1e83836Smrg __glibcxx_assert(!_M_has_value); 1166*b1e83836Smrg return _M_unex; 1167*b1e83836Smrg } 1168*b1e83836Smrg 1169*b1e83836Smrg constexpr const _Er&& 1170*b1e83836Smrg error() const && noexcept 1171*b1e83836Smrg { 1172*b1e83836Smrg __glibcxx_assert(!_M_has_value); 1173*b1e83836Smrg return std::move(_M_unex); 1174*b1e83836Smrg } 1175*b1e83836Smrg 1176*b1e83836Smrg constexpr _Er&& 1177*b1e83836Smrg error() && noexcept 1178*b1e83836Smrg { 1179*b1e83836Smrg __glibcxx_assert(!_M_has_value); 1180*b1e83836Smrg return std::move(_M_unex); 1181*b1e83836Smrg } 1182*b1e83836Smrg 1183*b1e83836Smrg // equality operators 1184*b1e83836Smrg 1185*b1e83836Smrg template<typename _Up, typename _Er2> 1186*b1e83836Smrg requires is_void_v<_Up> 1187*b1e83836Smrg friend constexpr bool 1188*b1e83836Smrg operator==(const expected& __x, const expected<_Up, _Er2>& __y) 1189*b1e83836Smrg // FIXME: noexcept(noexcept(bool(__x.error() == __y.error()))) 1190*b1e83836Smrg { 1191*b1e83836Smrg if (__x.has_value()) 1192*b1e83836Smrg return __y.has_value(); 1193*b1e83836Smrg else 1194*b1e83836Smrg return !__y.has_value() && bool(__x.error() == __y.error()); 1195*b1e83836Smrg } 1196*b1e83836Smrg 1197*b1e83836Smrg template<typename _Er2> 1198*b1e83836Smrg friend constexpr bool 1199*b1e83836Smrg operator==(const expected& __x, const unexpected<_Er2>& __e) 1200*b1e83836Smrg // FIXME: noexcept(noexcept(bool(__x.error() == __e.error()))) 1201*b1e83836Smrg { return !__x.has_value() && bool(__x.error() == __e.error()); } 1202*b1e83836Smrg 1203*b1e83836Smrg friend constexpr void 1204*b1e83836Smrg swap(expected& __x, expected& __y) 1205*b1e83836Smrg noexcept(noexcept(__x.swap(__y))) 1206*b1e83836Smrg requires requires { __x.swap(__y); } 1207*b1e83836Smrg { __x.swap(__y); } 1208*b1e83836Smrg 1209*b1e83836Smrg private: 1210*b1e83836Smrg template<typename, typename> friend class expected; 1211*b1e83836Smrg 1212*b1e83836Smrg template<typename _Vp> 1213*b1e83836Smrg constexpr void 1214*b1e83836Smrg _M_assign_unex(_Vp&& __v) 1215*b1e83836Smrg { 1216*b1e83836Smrg if (_M_has_value) 1217*b1e83836Smrg { 1218*b1e83836Smrg std::construct_at(__builtin_addressof(_M_unex), 1219*b1e83836Smrg std::forward<_Vp>(__v)); 1220*b1e83836Smrg _M_has_value = false; 1221*b1e83836Smrg } 1222*b1e83836Smrg else 1223*b1e83836Smrg _M_unex = std::forward<_Vp>(__v); 1224*b1e83836Smrg } 1225*b1e83836Smrg 1226*b1e83836Smrg 1227*b1e83836Smrg union { 1228*b1e83836Smrg struct { } _M_void; 1229*b1e83836Smrg _Er _M_unex; 1230*b1e83836Smrg }; 1231*b1e83836Smrg 1232*b1e83836Smrg bool _M_has_value; 1233*b1e83836Smrg }; 1234*b1e83836Smrg /// @} 1235*b1e83836Smrg 1236*b1e83836Smrg_GLIBCXX_END_NAMESPACE_VERSION 1237*b1e83836Smrg} // namespace std 1238*b1e83836Smrg 1239*b1e83836Smrg#endif // C++23 1240*b1e83836Smrg#endif // _GLIBCXX_EXPECTED 1241