Home | History | Annotate | Line # | Download | only in std
      1 // <expected> -*- C++ -*-
      2 
      3 // Copyright The GNU Toolchain Authors.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file include/expected
     26  *  This is a Standard C++ Library header.
     27  */
     28 
     29 #ifndef _GLIBCXX_EXPECTED
     30 #define _GLIBCXX_EXPECTED
     31 
     32 #pragma GCC system_header
     33 
     34 #define __glibcxx_want_expected
     35 #define __glibcxx_want_freestanding_expected
     36 #include <bits/version.h>
     37 
     38 #ifdef __cpp_lib_expected // C++ >= 23 && __cpp_concepts >= 202002L
     39 #include <initializer_list>
     40 #include <bits/exception.h>	// exception
     41 #include <bits/invoke.h>	// __invoke
     42 #include <bits/stl_construct.h>	// construct_at
     43 #include <bits/utility.h>	// in_place_t
     44 
     45 namespace std _GLIBCXX_VISIBILITY(default)
     46 {
     47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     48 
     49   /**
     50    * @defgroup expected_values Expected values
     51    * @addtogroup utilities
     52    * @since C++23
     53    * @{
     54    */
     55 
     56   /// Discriminated union that holds an expected value or an error value.
     57   /**
     58    * @since C++23
     59    */
     60   template<typename _Tp, typename _Er>
     61     class expected;
     62 
     63   /// Wrapper type used to pass an error value to a `std::expected`.
     64   /**
     65    * @since C++23
     66    */
     67   template<typename _Er>
     68     class unexpected;
     69 
     70   /// Exception thrown by std::expected when the value() is not present.
     71   /**
     72    * @since C++23
     73    */
     74   template<typename _Er>
     75     class bad_expected_access;
     76 
     77   template<>
     78     class bad_expected_access<void> : public exception
     79     {
     80     protected:
     81       bad_expected_access() noexcept { }
     82       bad_expected_access(const bad_expected_access&) = default;
     83       bad_expected_access(bad_expected_access&&) = default;
     84       bad_expected_access& operator=(const bad_expected_access&) = default;
     85       bad_expected_access& operator=(bad_expected_access&&) = default;
     86       ~bad_expected_access() = default;
     87 
     88     public:
     89 
     90       [[nodiscard]]
     91       const char*
     92       what() const noexcept override
     93       { return "bad access to std::expected without expected value"; }
     94     };
     95 
     96   template<typename _Er>
     97     class bad_expected_access : public bad_expected_access<void> {
     98     public:
     99       explicit
    100       bad_expected_access(_Er __e) : _M_unex(std::move(__e)) { }
    101 
    102       // XXX const char* what() const noexcept override;
    103 
    104       [[nodiscard]]
    105       _Er&
    106       error() & noexcept
    107       { return _M_unex; }
    108 
    109       [[nodiscard]]
    110       const _Er&
    111       error() const & noexcept
    112       { return _M_unex; }
    113 
    114       [[nodiscard]]
    115       _Er&&
    116       error() && noexcept
    117       { return std::move(_M_unex); }
    118 
    119       [[nodiscard]]
    120       const _Er&&
    121       error() const && noexcept
    122       { return std::move(_M_unex); }
    123 
    124     private:
    125       _Er _M_unex;
    126     };
    127 
    128   /// Tag type for constructing unexpected values in a std::expected
    129   /**
    130    * @since C++23
    131    */
    132   struct unexpect_t
    133   {
    134     explicit unexpect_t() = default;
    135   };
    136 
    137   /// Tag for constructing unexpected values in a std::expected
    138   /**
    139    * @since C++23
    140    */
    141   inline constexpr unexpect_t unexpect{};
    142 
    143 /// @cond undocumented
    144 namespace __expected
    145 {
    146   template<typename _Tp>
    147     constexpr bool __is_expected = false;
    148   template<typename _Tp, typename _Er>
    149     constexpr bool __is_expected<expected<_Tp, _Er>> = true;
    150 
    151   template<typename _Tp>
    152     constexpr bool __is_unexpected = false;
    153   template<typename _Tp>
    154     constexpr bool __is_unexpected<unexpected<_Tp>> = true;
    155 
    156   template<typename _Fn, typename _Tp>
    157     using __result = remove_cvref_t<invoke_result_t<_Fn&&, _Tp&&>>;
    158   template<typename _Fn, typename _Tp>
    159     using __result_xform = remove_cv_t<invoke_result_t<_Fn&&, _Tp&&>>;
    160   template<typename _Fn>
    161     using __result0 = remove_cvref_t<invoke_result_t<_Fn&&>>;
    162   template<typename _Fn>
    163     using __result0_xform = remove_cv_t<invoke_result_t<_Fn&&>>;
    164 
    165   template<typename _Er>
    166     concept __can_be_unexpected
    167       = is_object_v<_Er> && (!is_array_v<_Er>)
    168 	  && (!__expected::__is_unexpected<_Er>)
    169 	  && (!is_const_v<_Er>) && (!is_volatile_v<_Er>);
    170 
    171   // Tag types for in-place construction from an invocation result.
    172   struct __in_place_inv { };
    173   struct __unexpect_inv { };
    174 }
    175 /// @endcond
    176 
    177   template<typename _Er>
    178     class unexpected
    179     {
    180       static_assert( __expected::__can_be_unexpected<_Er> );
    181 
    182     public:
    183       constexpr unexpected(const unexpected&) = default;
    184       constexpr unexpected(unexpected&&) = default;
    185 
    186       template<typename _Err = _Er>
    187 	requires (!is_same_v<remove_cvref_t<_Err>, unexpected>)
    188 	  && (!is_same_v<remove_cvref_t<_Err>, in_place_t>)
    189 	  && is_constructible_v<_Er, _Err>
    190 	constexpr explicit
    191 	unexpected(_Err&& __e)
    192 	noexcept(is_nothrow_constructible_v<_Er, _Err>)
    193 	: _M_unex(std::forward<_Err>(__e))
    194 	{ }
    195 
    196       template<typename... _Args>
    197 	requires is_constructible_v<_Er, _Args...>
    198 	constexpr explicit
    199 	unexpected(in_place_t, _Args&&... __args)
    200 	noexcept(is_nothrow_constructible_v<_Er, _Args...>)
    201 	: _M_unex(std::forward<_Args>(__args)...)
    202 	{ }
    203 
    204       template<typename _Up, typename... _Args>
    205 	requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
    206 	constexpr explicit
    207 	unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
    208 	noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
    209 					    _Args...>)
    210 	: _M_unex(__il, std::forward<_Args>(__args)...)
    211 	{ }
    212 
    213       constexpr unexpected& operator=(const unexpected&) = default;
    214       constexpr unexpected& operator=(unexpected&&) = default;
    215 
    216 
    217       [[nodiscard]]
    218       constexpr const _Er&
    219       error() const & noexcept { return _M_unex; }
    220 
    221       [[nodiscard]]
    222       constexpr _Er&
    223       error() & noexcept { return _M_unex; }
    224 
    225       [[nodiscard]]
    226       constexpr const _Er&&
    227       error() const && noexcept { return std::move(_M_unex); }
    228 
    229       [[nodiscard]]
    230       constexpr _Er&&
    231       error() && noexcept { return std::move(_M_unex); }
    232 
    233       constexpr void
    234       swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Er>)
    235       requires is_swappable_v<_Er>
    236       {
    237 	using std::swap;
    238 	swap(_M_unex, __other._M_unex);
    239       }
    240 
    241       template<typename _Err>
    242 	[[nodiscard]]
    243 	friend constexpr bool
    244 	operator==(const unexpected& __x, const unexpected<_Err>& __y)
    245 	{ return __x._M_unex == __y.error(); }
    246 
    247       friend constexpr void
    248       swap(unexpected& __x, unexpected& __y) noexcept(noexcept(__x.swap(__y)))
    249       requires is_swappable_v<_Er>
    250       { __x.swap(__y); }
    251 
    252     private:
    253       _Er _M_unex;
    254     };
    255 
    256   template<typename _Er> unexpected(_Er) -> unexpected<_Er>;
    257 
    258 /// @cond undocumented
    259 namespace __expected
    260 {
    261   template<typename _Tp>
    262     struct _Guard
    263     {
    264       static_assert( is_nothrow_move_constructible_v<_Tp> );
    265 
    266       constexpr explicit
    267       _Guard(_Tp& __x)
    268       : _M_guarded(__builtin_addressof(__x)), _M_tmp(std::move(__x)) // nothrow
    269       { std::destroy_at(_M_guarded); }
    270 
    271       constexpr
    272       ~_Guard()
    273       {
    274 	if (_M_guarded) [[unlikely]]
    275 	  std::construct_at(_M_guarded, std::move(_M_tmp));
    276       }
    277 
    278       _Guard(const _Guard&) = delete;
    279       _Guard& operator=(const _Guard&) = delete;
    280 
    281       constexpr _Tp&&
    282       release() noexcept
    283       {
    284 	_M_guarded = nullptr;
    285 	return std::move(_M_tmp);
    286       }
    287 
    288     private:
    289       _Tp* _M_guarded;
    290       _Tp _M_tmp;
    291     };
    292 
    293   // reinit-expected helper from [expected.object.assign]
    294   template<typename _Tp, typename _Up, typename _Vp>
    295     constexpr void
    296     __reinit(_Tp* __newval, _Up* __oldval, _Vp&& __arg)
    297     noexcept(is_nothrow_constructible_v<_Tp, _Vp>)
    298     {
    299       if constexpr (is_nothrow_constructible_v<_Tp, _Vp>)
    300 	{
    301 	  std::destroy_at(__oldval);
    302 	  std::construct_at(__newval, std::forward<_Vp>(__arg));
    303 	}
    304       else if constexpr (is_nothrow_move_constructible_v<_Tp>)
    305 	{
    306 	  _Tp __tmp(std::forward<_Vp>(__arg)); // might throw
    307 	  std::destroy_at(__oldval);
    308 	  std::construct_at(__newval, std::move(__tmp));
    309 	}
    310       else
    311 	{
    312 	  _Guard<_Up> __guard(*__oldval);
    313 	  std::construct_at(__newval, std::forward<_Vp>(__arg)); // might throw
    314 	  __guard.release();
    315 	}
    316     }
    317 }
    318 /// @endcond
    319 
    320   template<typename _Tp, typename _Er>
    321     class expected
    322     {
    323       static_assert( ! is_reference_v<_Tp> );
    324       static_assert( ! is_function_v<_Tp> );
    325       static_assert( ! is_same_v<remove_cv_t<_Tp>, in_place_t> );
    326       static_assert( ! is_same_v<remove_cv_t<_Tp>, unexpect_t> );
    327       static_assert( ! __expected::__is_unexpected<remove_cv_t<_Tp>> );
    328       static_assert( __expected::__can_be_unexpected<_Er> );
    329 
    330       template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
    331 	static constexpr bool __cons_from_expected
    332 	  = __or_v<is_constructible<_Tp, expected<_Up, _Err>&>,
    333 		   is_constructible<_Tp, expected<_Up, _Err>>,
    334 		   is_constructible<_Tp, const expected<_Up, _Err>&>,
    335 		   is_constructible<_Tp, const expected<_Up, _Err>>,
    336 		   is_convertible<expected<_Up, _Err>&, _Tp>,
    337 		   is_convertible<expected<_Up, _Err>, _Tp>,
    338 		   is_convertible<const expected<_Up, _Err>&, _Tp>,
    339 		   is_convertible<const expected<_Up, _Err>, _Tp>,
    340 		   is_constructible<_Unex, expected<_Up, _Err>&>,
    341 		   is_constructible<_Unex, expected<_Up, _Err>>,
    342 		   is_constructible<_Unex, const expected<_Up, _Err>&>,
    343 		   is_constructible<_Unex, const expected<_Up, _Err>>
    344 		  >;
    345 
    346       template<typename _Up, typename _Err>
    347 	constexpr static bool __explicit_conv
    348 	  = __or_v<__not_<is_convertible<_Up, _Tp>>,
    349 		   __not_<is_convertible<_Err, _Er>>
    350 		  >;
    351 
    352       template<typename _Up>
    353 	static constexpr bool __same_val
    354 	  = is_same_v<typename _Up::value_type, _Tp>;
    355 
    356       template<typename _Up>
    357 	static constexpr bool __same_err
    358 	  = is_same_v<typename _Up::error_type, _Er>;
    359 
    360     public:
    361       using value_type = _Tp;
    362       using error_type = _Er;
    363       using unexpected_type = unexpected<_Er>;
    364 
    365       template<typename _Up>
    366 	using rebind = expected<_Up, error_type>;
    367 
    368       constexpr
    369       expected()
    370       noexcept(is_nothrow_default_constructible_v<_Tp>)
    371       requires is_default_constructible_v<_Tp>
    372       : _M_val(), _M_has_value(true)
    373       { }
    374 
    375       expected(const expected&) = default;
    376 
    377       constexpr
    378       expected(const expected& __x)
    379       noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
    380 		       is_nothrow_copy_constructible<_Er>>)
    381       requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Er>
    382       && (!is_trivially_copy_constructible_v<_Tp>
    383 	  || !is_trivially_copy_constructible_v<_Er>)
    384       : _M_has_value(__x._M_has_value)
    385       {
    386 	if (_M_has_value)
    387 	  std::construct_at(__builtin_addressof(_M_val), __x._M_val);
    388 	else
    389 	  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
    390       }
    391 
    392       expected(expected&&) = default;
    393 
    394       constexpr
    395       expected(expected&& __x)
    396       noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
    397 		       is_nothrow_move_constructible<_Er>>)
    398       requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Er>
    399       && (!is_trivially_move_constructible_v<_Tp>
    400 	  || !is_trivially_move_constructible_v<_Er>)
    401       : _M_has_value(__x._M_has_value)
    402       {
    403 	if (_M_has_value)
    404 	  std::construct_at(__builtin_addressof(_M_val),
    405 			    std::move(__x)._M_val);
    406 	else
    407 	  std::construct_at(__builtin_addressof(_M_unex),
    408 			    std::move(__x)._M_unex);
    409       }
    410 
    411       template<typename _Up, typename _Gr>
    412 	requires is_constructible_v<_Tp, const _Up&>
    413 	      && is_constructible_v<_Er, const _Gr&>
    414 	      && (!__cons_from_expected<_Up, _Gr>)
    415 	constexpr explicit(__explicit_conv<const _Up&, const _Gr&>)
    416 	expected(const expected<_Up, _Gr>& __x)
    417 	noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
    418 			 is_nothrow_constructible<_Er, const _Gr&>>)
    419 	: _M_has_value(__x._M_has_value)
    420 	{
    421 	  if (_M_has_value)
    422 	    std::construct_at(__builtin_addressof(_M_val), __x._M_val);
    423 	  else
    424 	    std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
    425 	}
    426 
    427       template<typename _Up, typename _Gr>
    428 	requires is_constructible_v<_Tp, _Up>
    429 	      && is_constructible_v<_Er, _Gr>
    430 	      && (!__cons_from_expected<_Up, _Gr>)
    431 	constexpr explicit(__explicit_conv<_Up, _Gr>)
    432 	expected(expected<_Up, _Gr>&& __x)
    433 	noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
    434 			 is_nothrow_constructible<_Er, _Gr>>)
    435 	: _M_has_value(__x._M_has_value)
    436 	{
    437 	  if (_M_has_value)
    438 	    std::construct_at(__builtin_addressof(_M_val),
    439 			      std::move(__x)._M_val);
    440 	  else
    441 	    std::construct_at(__builtin_addressof(_M_unex),
    442 			      std::move(__x)._M_unex);
    443 	}
    444 
    445       template<typename _Up = _Tp>
    446 	requires (!is_same_v<remove_cvref_t<_Up>, expected>)
    447 	  && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
    448 	  && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
    449 	  && is_constructible_v<_Tp, _Up>
    450 	constexpr explicit(!is_convertible_v<_Up, _Tp>)
    451 	expected(_Up&& __v)
    452 	noexcept(is_nothrow_constructible_v<_Tp, _Up>)
    453 	: _M_val(std::forward<_Up>(__v)), _M_has_value(true)
    454 	{ }
    455 
    456       template<typename _Gr = _Er>
    457 	requires is_constructible_v<_Er, const _Gr&>
    458 	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
    459 	expected(const unexpected<_Gr>& __u)
    460 	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
    461 	: _M_unex(__u.error()), _M_has_value(false)
    462 	{ }
    463 
    464       template<typename _Gr = _Er>
    465 	requires is_constructible_v<_Er, _Gr>
    466 	constexpr explicit(!is_convertible_v<_Gr, _Er>)
    467 	expected(unexpected<_Gr>&& __u)
    468 	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
    469 	: _M_unex(std::move(__u).error()), _M_has_value(false)
    470 	{ }
    471 
    472       template<typename... _Args>
    473 	requires is_constructible_v<_Tp, _Args...>
    474 	constexpr explicit
    475 	expected(in_place_t, _Args&&... __args)
    476 	noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
    477 	: _M_val(std::forward<_Args>(__args)...), _M_has_value(true)
    478 	{ }
    479 
    480       template<typename _Up, typename... _Args>
    481 	requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
    482 	constexpr explicit
    483 	expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
    484 	noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
    485 					    _Args...>)
    486 	: _M_val(__il, std::forward<_Args>(__args)...), _M_has_value(true)
    487 	{ }
    488 
    489       template<typename... _Args>
    490 	requires is_constructible_v<_Er, _Args...>
    491 	constexpr explicit
    492 	expected(unexpect_t, _Args&&... __args)
    493 	noexcept(is_nothrow_constructible_v<_Er, _Args...>)
    494 	: _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
    495 	{ }
    496 
    497       template<typename _Up, typename... _Args>
    498 	requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
    499 	constexpr explicit
    500 	expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
    501 	noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
    502 					    _Args...>)
    503 	: _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
    504 	{ }
    505 
    506       constexpr ~expected() = default;
    507 
    508       constexpr ~expected()
    509       requires (!is_trivially_destructible_v<_Tp>)
    510 	    || (!is_trivially_destructible_v<_Er>)
    511       {
    512 	if (_M_has_value)
    513 	  std::destroy_at(__builtin_addressof(_M_val));
    514 	else
    515 	  std::destroy_at(__builtin_addressof(_M_unex));
    516       }
    517 
    518       // assignment
    519 
    520       expected& operator=(const expected&) = delete;
    521 
    522       constexpr expected&
    523       operator=(const expected& __x)
    524       noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
    525 		       is_nothrow_copy_constructible<_Er>,
    526 		       is_nothrow_copy_assignable<_Tp>,
    527 		       is_nothrow_copy_assignable<_Er>>)
    528       requires is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp>
    529 	    && is_copy_assignable_v<_Er> && is_copy_constructible_v<_Er>
    530 	    && (is_nothrow_move_constructible_v<_Tp>
    531 		|| is_nothrow_move_constructible_v<_Er>)
    532       {
    533 	if (__x._M_has_value)
    534 	  this->_M_assign_val(__x._M_val);
    535 	else
    536 	  this->_M_assign_unex(__x._M_unex);
    537 	return *this;
    538       }
    539 
    540       constexpr expected&
    541       operator=(expected&& __x)
    542       noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
    543 		       is_nothrow_move_constructible<_Er>,
    544 		       is_nothrow_move_assignable<_Tp>,
    545 		       is_nothrow_move_assignable<_Er>>)
    546       requires is_move_assignable_v<_Tp> && is_move_constructible_v<_Tp>
    547 	    && is_move_assignable_v<_Er> && is_move_constructible_v<_Er>
    548 	    && (is_nothrow_move_constructible_v<_Tp>
    549 		|| is_nothrow_move_constructible_v<_Er>)
    550       {
    551 	if (__x._M_has_value)
    552 	  _M_assign_val(std::move(__x._M_val));
    553 	else
    554 	  _M_assign_unex(std::move(__x._M_unex));
    555 	return *this;
    556       }
    557 
    558       template<typename _Up = _Tp>
    559 	requires (!is_same_v<expected, remove_cvref_t<_Up>>)
    560 	      && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
    561 	      && is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up>
    562 	      && (is_nothrow_constructible_v<_Tp, _Up>
    563 		  || is_nothrow_move_constructible_v<_Tp>
    564 		  || is_nothrow_move_constructible_v<_Er>)
    565 	constexpr expected&
    566 	operator=(_Up&& __v)
    567 	{
    568 	  _M_assign_val(std::forward<_Up>(__v));
    569 	  return *this;
    570 	}
    571 
    572       template<typename _Gr>
    573 	requires is_constructible_v<_Er, const _Gr&>
    574 	      && is_assignable_v<_Er&, const _Gr&>
    575 	      && (is_nothrow_constructible_v<_Er, const _Gr&>
    576 		  || is_nothrow_move_constructible_v<_Tp>
    577 		  || is_nothrow_move_constructible_v<_Er>)
    578 	constexpr expected&
    579 	operator=(const unexpected<_Gr>& __e)
    580 	{
    581 	  _M_assign_unex(__e.error());
    582 	  return *this;
    583 	}
    584 
    585       template<typename _Gr>
    586 	requires is_constructible_v<_Er, _Gr>
    587 	      && is_assignable_v<_Er&, _Gr>
    588 	      && (is_nothrow_constructible_v<_Er, _Gr>
    589 		  || is_nothrow_move_constructible_v<_Tp>
    590 		  || is_nothrow_move_constructible_v<_Er>)
    591 	constexpr expected&
    592 	operator=(unexpected<_Gr>&& __e)
    593 	{
    594 	  _M_assign_unex(std::move(__e).error());
    595 	  return *this;
    596 	}
    597 
    598       // modifiers
    599 
    600       template<typename... _Args>
    601 	requires is_nothrow_constructible_v<_Tp, _Args...>
    602 	constexpr _Tp&
    603 	emplace(_Args&&... __args) noexcept
    604 	{
    605 	  if (_M_has_value)
    606 	    std::destroy_at(__builtin_addressof(_M_val));
    607 	  else
    608 	    {
    609 	      std::destroy_at(__builtin_addressof(_M_unex));
    610 	      _M_has_value = true;
    611 	    }
    612 	  std::construct_at(__builtin_addressof(_M_val),
    613 			    std::forward<_Args>(__args)...);
    614 	  return _M_val;
    615 	}
    616 
    617       template<typename _Up, typename... _Args>
    618 	requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
    619 					    _Args...>
    620 	constexpr _Tp&
    621 	emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept
    622 	{
    623 	  if (_M_has_value)
    624 	    std::destroy_at(__builtin_addressof(_M_val));
    625 	  else
    626 	    {
    627 	      std::destroy_at(__builtin_addressof(_M_unex));
    628 	      _M_has_value = true;
    629 	    }
    630 	  std::construct_at(__builtin_addressof(_M_val),
    631 			    __il, std::forward<_Args>(__args)...);
    632 	  return _M_val;
    633 	}
    634 
    635       // swap
    636       constexpr void
    637       swap(expected& __x)
    638       noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
    639 		       is_nothrow_move_constructible<_Er>,
    640 		       is_nothrow_swappable<_Tp&>,
    641 		       is_nothrow_swappable<_Er&>>)
    642       requires is_swappable_v<_Tp> && is_swappable_v<_Er>
    643 	    && is_move_constructible_v<_Tp>
    644 	    && is_move_constructible_v<_Er>
    645 	    && (is_nothrow_move_constructible_v<_Tp>
    646 		|| is_nothrow_move_constructible_v<_Er>)
    647       {
    648 	if (_M_has_value)
    649 	  {
    650 	    if (__x._M_has_value)
    651 	      {
    652 		using std::swap;
    653 		swap(_M_val, __x._M_val);
    654 	      }
    655 	    else
    656 	      this->_M_swap_val_unex(__x);
    657 	  }
    658 	else
    659 	  {
    660 	    if (__x._M_has_value)
    661 	      __x._M_swap_val_unex(*this);
    662 	    else
    663 	      {
    664 		using std::swap;
    665 		swap(_M_unex, __x._M_unex);
    666 	      }
    667 	  }
    668       }
    669 
    670       // observers
    671 
    672       [[nodiscard]]
    673       constexpr const _Tp*
    674       operator->() const noexcept
    675       {
    676 	__glibcxx_assert(_M_has_value);
    677 	return __builtin_addressof(_M_val);
    678       }
    679 
    680       [[nodiscard]]
    681       constexpr _Tp*
    682       operator->() noexcept
    683       {
    684 	__glibcxx_assert(_M_has_value);
    685 	return __builtin_addressof(_M_val);
    686       }
    687 
    688       [[nodiscard]]
    689       constexpr const _Tp&
    690       operator*() const & noexcept
    691       {
    692 	__glibcxx_assert(_M_has_value);
    693 	return _M_val;
    694       }
    695 
    696       [[nodiscard]]
    697       constexpr _Tp&
    698       operator*() & noexcept
    699       {
    700 	__glibcxx_assert(_M_has_value);
    701 	return _M_val;
    702       }
    703 
    704       [[nodiscard]]
    705       constexpr const _Tp&&
    706       operator*() const && noexcept
    707       {
    708 	__glibcxx_assert(_M_has_value);
    709 	return std::move(_M_val);
    710       }
    711 
    712       [[nodiscard]]
    713       constexpr _Tp&&
    714       operator*() && noexcept
    715       {
    716 	__glibcxx_assert(_M_has_value);
    717 	return std::move(_M_val);
    718       }
    719 
    720       [[nodiscard]]
    721       constexpr explicit
    722       operator bool() const noexcept { return _M_has_value; }
    723 
    724       [[nodiscard]]
    725       constexpr bool has_value() const noexcept { return _M_has_value; }
    726 
    727       constexpr const _Tp&
    728       value() const &
    729       {
    730 	if (_M_has_value) [[likely]]
    731 	  return _M_val;
    732 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
    733       }
    734 
    735       constexpr _Tp&
    736       value() &
    737       {
    738 	if (_M_has_value) [[likely]]
    739 	  return _M_val;
    740 	const auto& __unex = _M_unex;
    741 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(__unex));
    742       }
    743 
    744       constexpr const _Tp&&
    745       value() const &&
    746       {
    747 	if (_M_has_value) [[likely]]
    748 	  return std::move(_M_val);
    749 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
    750       }
    751 
    752       constexpr _Tp&&
    753       value() &&
    754       {
    755 	if (_M_has_value) [[likely]]
    756 	  return std::move(_M_val);
    757 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
    758       }
    759 
    760       constexpr const _Er&
    761       error() const & noexcept
    762       {
    763 	__glibcxx_assert(!_M_has_value);
    764 	return _M_unex;
    765       }
    766 
    767       constexpr _Er&
    768       error() & noexcept
    769       {
    770 	__glibcxx_assert(!_M_has_value);
    771 	return _M_unex;
    772       }
    773 
    774       constexpr const _Er&&
    775       error() const && noexcept
    776       {
    777 	__glibcxx_assert(!_M_has_value);
    778 	return std::move(_M_unex);
    779       }
    780 
    781       constexpr _Er&&
    782       error() && noexcept
    783       {
    784 	__glibcxx_assert(!_M_has_value);
    785 	return std::move(_M_unex);
    786       }
    787 
    788       template<typename _Up>
    789 	constexpr _Tp
    790 	value_or(_Up&& __v) const &
    791 	noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
    792 			 is_nothrow_convertible<_Up, _Tp>>)
    793 	{
    794 	  static_assert( is_copy_constructible_v<_Tp> );
    795 	  static_assert( is_convertible_v<_Up, _Tp> );
    796 
    797 	  if (_M_has_value)
    798 	    return _M_val;
    799 	  return static_cast<_Tp>(std::forward<_Up>(__v));
    800 	}
    801 
    802       template<typename _Up>
    803 	constexpr _Tp
    804 	value_or(_Up&& __v) &&
    805 	noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
    806 			 is_nothrow_convertible<_Up, _Tp>>)
    807 	{
    808 	  static_assert( is_move_constructible_v<_Tp> );
    809 	  static_assert( is_convertible_v<_Up, _Tp> );
    810 
    811 	  if (_M_has_value)
    812 	    return std::move(_M_val);
    813 	  return static_cast<_Tp>(std::forward<_Up>(__v));
    814 	}
    815 
    816       template<typename _Gr = _Er>
    817 	constexpr _Er
    818 	error_or(_Gr&& __e) const&
    819 	{
    820 	  static_assert( is_copy_constructible_v<_Er> );
    821 	  static_assert( is_convertible_v<_Gr, _Er> );
    822 
    823 	  if (_M_has_value)
    824 	    return std::forward<_Gr>(__e);
    825 	  return _M_unex;
    826 	}
    827 
    828       template<typename _Gr = _Er>
    829 	constexpr _Er
    830 	error_or(_Gr&& __e) &&
    831 	{
    832 	  static_assert( is_move_constructible_v<_Er> );
    833 	  static_assert( is_convertible_v<_Gr, _Er> );
    834 
    835 	  if (_M_has_value)
    836 	    return std::forward<_Gr>(__e);
    837 	  return std::move(_M_unex);
    838 	}
    839 
    840       // monadic operations
    841 
    842       template<typename _Fn> requires is_constructible_v<_Er, _Er&>
    843 	constexpr auto
    844 	and_then(_Fn&& __f) &
    845 	{
    846 	  using _Up = __expected::__result<_Fn, _Tp&>;
    847 	  static_assert(__expected::__is_expected<_Up>,
    848 			"the function passed to std::expected<T, E>::and_then "
    849 			"must return a std::expected");
    850 	  static_assert(is_same_v<typename _Up::error_type, _Er>,
    851 			"the function passed to std::expected<T, E>::and_then "
    852 			"must return a std::expected with the same error_type");
    853 
    854 	  if (has_value())
    855 	    return std::__invoke(std::forward<_Fn>(__f), _M_val);
    856 	  else
    857 	    return _Up(unexpect, _M_unex);
    858 	}
    859 
    860       template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
    861 	constexpr auto
    862 	and_then(_Fn&& __f) const &
    863 	{
    864 	  using _Up = __expected::__result<_Fn, const _Tp&>;
    865 	  static_assert(__expected::__is_expected<_Up>,
    866 			"the function passed to std::expected<T, E>::and_then "
    867 			"must return a std::expected");
    868 	  static_assert(is_same_v<typename _Up::error_type, _Er>,
    869 			"the function passed to std::expected<T, E>::and_then "
    870 			"must return a std::expected with the same error_type");
    871 
    872 	  if (has_value())
    873 	    return std::__invoke(std::forward<_Fn>(__f), _M_val);
    874 	  else
    875 	    return _Up(unexpect, _M_unex);
    876 	}
    877 
    878       template<typename _Fn> requires is_constructible_v<_Er, _Er>
    879 	constexpr auto
    880 	and_then(_Fn&& __f) &&
    881 	{
    882 	  using _Up = __expected::__result<_Fn, _Tp&&>;
    883 	  static_assert(__expected::__is_expected<_Up>,
    884 			"the function passed to std::expected<T, E>::and_then "
    885 			"must return a std::expected");
    886 	  static_assert(is_same_v<typename _Up::error_type, _Er>,
    887 			"the function passed to std::expected<T, E>::and_then "
    888 			"must return a std::expected with the same error_type");
    889 
    890 	  if (has_value())
    891 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
    892 	  else
    893 	    return _Up(unexpect, std::move(_M_unex));
    894 	}
    895 
    896 
    897       template<typename _Fn> requires is_constructible_v<_Er, const _Er>
    898 	constexpr auto
    899 	and_then(_Fn&& __f) const &&
    900 	{
    901 	  using _Up = __expected::__result<_Fn, const _Tp&&>;
    902 	  static_assert(__expected::__is_expected<_Up>,
    903 			"the function passed to std::expected<T, E>::and_then "
    904 			"must return a std::expected");
    905 	  static_assert(is_same_v<typename _Up::error_type, _Er>,
    906 			"the function passed to std::expected<T, E>::and_then "
    907 			"must return a std::expected with the same error_type");
    908 
    909 	  if (has_value())
    910 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
    911 	  else
    912 	    return _Up(unexpect, std::move(_M_unex));
    913 	}
    914 
    915       template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
    916 	constexpr auto
    917 	or_else(_Fn&& __f) &
    918 	{
    919 	  using _Gr = __expected::__result<_Fn, _Er&>;
    920 	  static_assert(__expected::__is_expected<_Gr>,
    921 			"the function passed to std::expected<T, E>::or_else "
    922 			"must return a std::expected");
    923 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
    924 			"the function passed to std::expected<T, E>::or_else "
    925 			"must return a std::expected with the same value_type");
    926 
    927 	  if (has_value())
    928 	    return _Gr(in_place, _M_val);
    929 	  else
    930 	    return std::__invoke(std::forward<_Fn>(__f), _M_unex);
    931 	}
    932 
    933       template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
    934 	constexpr auto
    935 	or_else(_Fn&& __f) const &
    936 	{
    937 	  using _Gr = __expected::__result<_Fn, const _Er&>;
    938 	  static_assert(__expected::__is_expected<_Gr>,
    939 			"the function passed to std::expected<T, E>::or_else "
    940 			"must return a std::expected");
    941 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
    942 			"the function passed to std::expected<T, E>::or_else "
    943 			"must return a std::expected with the same value_type");
    944 
    945 	  if (has_value())
    946 	    return _Gr(in_place, _M_val);
    947 	  else
    948 	    return std::__invoke(std::forward<_Fn>(__f), _M_unex);
    949 	}
    950 
    951 
    952       template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
    953 	constexpr auto
    954 	or_else(_Fn&& __f) &&
    955 	{
    956 	  using _Gr = __expected::__result<_Fn, _Er&&>;
    957 	  static_assert(__expected::__is_expected<_Gr>,
    958 			"the function passed to std::expected<T, E>::or_else "
    959 			"must return a std::expected");
    960 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
    961 			"the function passed to std::expected<T, E>::or_else "
    962 			"must return a std::expected with the same value_type");
    963 
    964 	  if (has_value())
    965 	    return _Gr(in_place, std::move(_M_val));
    966 	  else
    967 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
    968 	}
    969 
    970       template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
    971 	constexpr auto
    972 	or_else(_Fn&& __f) const &&
    973 	{
    974 	  using _Gr = __expected::__result<_Fn, const _Er&&>;
    975 	  static_assert(__expected::__is_expected<_Gr>,
    976 			"the function passed to std::expected<T, E>::or_else "
    977 			"must return a std::expected");
    978 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
    979 			"the function passed to std::expected<T, E>::or_else "
    980 			"must return a std::expected with the same value_type");
    981 
    982 	  if (has_value())
    983 	    return _Gr(in_place, std::move(_M_val));
    984 	  else
    985 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
    986 	}
    987 
    988       template<typename _Fn> requires is_constructible_v<_Er, _Er&>
    989 	constexpr auto
    990 	transform(_Fn&& __f) &
    991 	{
    992 	  using _Up = __expected::__result_xform<_Fn, _Tp&>;
    993 	  using _Res = expected<_Up, _Er>;
    994 
    995 	  if (has_value())
    996 	    return _Res(__in_place_inv{}, [&]() {
    997 			  return std::__invoke(std::forward<_Fn>(__f),
    998 					       _M_val);
    999 			});
   1000 	  else
   1001 	    return _Res(unexpect, _M_unex);
   1002 	}
   1003 
   1004       template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
   1005 	constexpr auto
   1006 	transform(_Fn&& __f) const &
   1007 	{
   1008 	  using _Up = __expected::__result_xform<_Fn, const _Tp&>;
   1009 	  using _Res = expected<_Up, _Er>;
   1010 
   1011 	  if (has_value())
   1012 	    return _Res(__in_place_inv{}, [&]() {
   1013 			  return std::__invoke(std::forward<_Fn>(__f),
   1014 					       _M_val);
   1015 			});
   1016 	  else
   1017 	    return _Res(unexpect, _M_unex);
   1018 	}
   1019 
   1020       template<typename _Fn> requires is_constructible_v<_Er, _Er>
   1021 	constexpr auto
   1022 	transform(_Fn&& __f) &&
   1023 	{
   1024 	  using _Up = __expected::__result_xform<_Fn, _Tp>;
   1025 	  using _Res = expected<_Up, _Er>;
   1026 
   1027 	  if (has_value())
   1028 	    return _Res(__in_place_inv{}, [&]() {
   1029 			  return std::__invoke(std::forward<_Fn>(__f),
   1030 					       std::move(_M_val));
   1031 			});
   1032 	  else
   1033 	    return _Res(unexpect, std::move(_M_unex));
   1034 	}
   1035 
   1036       template<typename _Fn> requires is_constructible_v<_Er, const _Er>
   1037 	constexpr auto
   1038 	transform(_Fn&& __f) const &&
   1039 	{
   1040 	  using _Up = __expected::__result_xform<_Fn, const _Tp>;
   1041 	  using _Res = expected<_Up, _Er>;
   1042 
   1043 	  if (has_value())
   1044 	    return _Res(__in_place_inv{}, [&]() {
   1045 			  return std::__invoke(std::forward<_Fn>(__f),
   1046 					       std::move(_M_val));
   1047 			});
   1048 	  else
   1049 	    return _Res(unexpect, std::move(_M_unex));
   1050 	}
   1051 
   1052       template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
   1053 	constexpr auto
   1054 	transform_error(_Fn&& __f) &
   1055 	{
   1056 	  using _Gr = __expected::__result_xform<_Fn, _Er&>;
   1057 	  using _Res = expected<_Tp, _Gr>;
   1058 
   1059 	  if (has_value())
   1060 	    return _Res(in_place, _M_val);
   1061 	  else
   1062 	    return _Res(__unexpect_inv{}, [&]() {
   1063 			  return std::__invoke(std::forward<_Fn>(__f),
   1064 					       _M_unex);
   1065 			});
   1066 	}
   1067 
   1068       template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
   1069 	constexpr auto
   1070 	transform_error(_Fn&& __f) const &
   1071 	{
   1072 	  using _Gr = __expected::__result_xform<_Fn, const _Er&>;
   1073 	  using _Res = expected<_Tp, _Gr>;
   1074 
   1075 	  if (has_value())
   1076 	    return _Res(in_place, _M_val);
   1077 	  else
   1078 	    return _Res(__unexpect_inv{}, [&]() {
   1079 			  return std::__invoke(std::forward<_Fn>(__f),
   1080 					       _M_unex);
   1081 			});
   1082 	}
   1083 
   1084       template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
   1085 	constexpr auto
   1086 	transform_error(_Fn&& __f) &&
   1087 	{
   1088 	  using _Gr = __expected::__result_xform<_Fn, _Er&&>;
   1089 	  using _Res = expected<_Tp, _Gr>;
   1090 
   1091 	  if (has_value())
   1092 	    return _Res(in_place, std::move(_M_val));
   1093 	  else
   1094 	    return _Res(__unexpect_inv{}, [&]() {
   1095 			  return std::__invoke(std::forward<_Fn>(__f),
   1096 					       std::move(_M_unex));
   1097 			});
   1098 	}
   1099 
   1100       template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
   1101 	constexpr auto
   1102 	transform_error(_Fn&& __f) const &&
   1103 	{
   1104 	  using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
   1105 	  using _Res = expected<_Tp, _Gr>;
   1106 
   1107 	  if (has_value())
   1108 	    return _Res(in_place, std::move(_M_val));
   1109 	  else
   1110 	    return _Res(__unexpect_inv{}, [&]() {
   1111 			  return std::__invoke(std::forward<_Fn>(__f),
   1112 					       std::move(_M_unex));
   1113 			});
   1114 	}
   1115 
   1116       // equality operators
   1117 
   1118       template<typename _Up, typename _Er2>
   1119 	requires (!is_void_v<_Up>)
   1120 	friend constexpr bool
   1121 	operator==(const expected& __x, const expected<_Up, _Er2>& __y)
   1122 	// FIXME: noexcept(noexcept(bool(*__x == *__y))
   1123 		  // && noexcept(bool(__x.error() == __y.error())))
   1124 	{
   1125 	  if (__x.has_value())
   1126 	    return __y.has_value() && bool(*__x == *__y);
   1127 	  else
   1128 	    return !__y.has_value() && bool(__x.error() == __y.error());
   1129 	}
   1130 
   1131       template<typename _Up>
   1132 	friend constexpr bool
   1133 	operator==(const expected& __x, const _Up& __v)
   1134 	// FIXME: noexcept(noexcept(bool(*__x == __v)))
   1135 	{ return __x.has_value() && bool(*__x == __v); }
   1136 
   1137       template<typename _Er2>
   1138 	friend constexpr bool
   1139 	operator==(const expected& __x, const unexpected<_Er2>& __e)
   1140 	// FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
   1141 	{ return !__x.has_value() && bool(__x.error() == __e.error()); }
   1142 
   1143       friend constexpr void
   1144       swap(expected& __x, expected& __y)
   1145       noexcept(noexcept(__x.swap(__y)))
   1146       requires requires {__x.swap(__y);}
   1147       { __x.swap(__y); }
   1148 
   1149     private:
   1150       template<typename, typename> friend class expected;
   1151 
   1152       template<typename _Vp>
   1153 	constexpr void
   1154 	_M_assign_val(_Vp&& __v)
   1155 	{
   1156 	  if (_M_has_value)
   1157 	    _M_val = std::forward<_Vp>(__v);
   1158 	  else
   1159 	    {
   1160 	      __expected::__reinit(__builtin_addressof(_M_val),
   1161 				   __builtin_addressof(_M_unex),
   1162 				   std::forward<_Vp>(__v));
   1163 	      _M_has_value = true;
   1164 	    }
   1165 	}
   1166 
   1167       template<typename _Vp>
   1168 	constexpr void
   1169 	_M_assign_unex(_Vp&& __v)
   1170 	{
   1171 	  if (_M_has_value)
   1172 	    {
   1173 	      __expected::__reinit(__builtin_addressof(_M_unex),
   1174 				   __builtin_addressof(_M_val),
   1175 				   std::forward<_Vp>(__v));
   1176 	      _M_has_value = false;
   1177 	    }
   1178 	  else
   1179 	    _M_unex = std::forward<_Vp>(__v);
   1180 	}
   1181 
   1182       // Swap two expected objects when only one has a value.
   1183       // Precondition: this->_M_has_value && !__rhs._M_has_value
   1184       constexpr void
   1185       _M_swap_val_unex(expected& __rhs)
   1186       noexcept(__and_v<is_nothrow_move_constructible<_Er>,
   1187 		       is_nothrow_move_constructible<_Tp>>)
   1188       {
   1189 	if constexpr (is_nothrow_move_constructible_v<_Er>)
   1190 	  {
   1191 	    __expected::_Guard<_Er> __guard(__rhs._M_unex);
   1192 	    std::construct_at(__builtin_addressof(__rhs._M_val),
   1193 			      std::move(_M_val)); // might throw
   1194 	    __rhs._M_has_value = true;
   1195 	    std::destroy_at(__builtin_addressof(_M_val));
   1196 	    std::construct_at(__builtin_addressof(_M_unex),
   1197 			      __guard.release());
   1198 	    _M_has_value = false;
   1199 	  }
   1200 	else
   1201 	  {
   1202 	    __expected::_Guard<_Tp> __guard(_M_val);
   1203 	    std::construct_at(__builtin_addressof(_M_unex),
   1204 			      std::move(__rhs._M_unex)); // might throw
   1205 	    _M_has_value = false;
   1206 	    std::destroy_at(__builtin_addressof(__rhs._M_unex));
   1207 	    std::construct_at(__builtin_addressof(__rhs._M_val),
   1208 			      __guard.release());
   1209 	    __rhs._M_has_value = true;
   1210 	  }
   1211       }
   1212 
   1213       using __in_place_inv = __expected::__in_place_inv;
   1214       using __unexpect_inv = __expected::__unexpect_inv;
   1215 
   1216       template<typename _Fn>
   1217 	explicit constexpr
   1218 	expected(__in_place_inv, _Fn&& __fn)
   1219 	: _M_val(std::forward<_Fn>(__fn)()), _M_has_value(true)
   1220 	{ }
   1221 
   1222       template<typename _Fn>
   1223 	explicit constexpr
   1224 	expected(__unexpect_inv, _Fn&& __fn)
   1225 	: _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
   1226 	{ }
   1227 
   1228       union {
   1229 	_Tp _M_val;
   1230 	_Er _M_unex;
   1231       };
   1232 
   1233       bool _M_has_value;
   1234     };
   1235 
   1236   // Partial specialization for std::expected<cv void, E>
   1237   template<typename _Tp, typename _Er> requires is_void_v<_Tp>
   1238     class expected<_Tp, _Er>
   1239     {
   1240       static_assert( __expected::__can_be_unexpected<_Er> );
   1241 
   1242       template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
   1243 	static constexpr bool __cons_from_expected
   1244 	  = __or_v<is_constructible<_Unex, expected<_Up, _Err>&>,
   1245 		   is_constructible<_Unex, expected<_Up, _Err>>,
   1246 		   is_constructible<_Unex, const expected<_Up, _Err>&>,
   1247 		   is_constructible<_Unex, const expected<_Up, _Err>>
   1248 		  >;
   1249 
   1250       template<typename _Up>
   1251 	static constexpr bool __same_val
   1252 	  = is_same_v<typename _Up::value_type, _Tp>;
   1253 
   1254       template<typename _Up>
   1255 	static constexpr bool __same_err
   1256 	  = is_same_v<typename _Up::error_type, _Er>;
   1257 
   1258     public:
   1259       using value_type = _Tp;
   1260       using error_type = _Er;
   1261       using unexpected_type = unexpected<_Er>;
   1262 
   1263       template<typename _Up>
   1264 	using rebind = expected<_Up, error_type>;
   1265 
   1266       constexpr
   1267       expected() noexcept
   1268       : _M_void(), _M_has_value(true)
   1269       { }
   1270 
   1271       expected(const expected&) = default;
   1272 
   1273       constexpr
   1274       expected(const expected& __x)
   1275       noexcept(is_nothrow_copy_constructible_v<_Er>)
   1276       requires is_copy_constructible_v<_Er>
   1277 	    && (!is_trivially_copy_constructible_v<_Er>)
   1278       : _M_void(), _M_has_value(__x._M_has_value)
   1279       {
   1280 	if (!_M_has_value)
   1281 	  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
   1282       }
   1283 
   1284       expected(expected&&) = default;
   1285 
   1286       constexpr
   1287       expected(expected&& __x)
   1288       noexcept(is_nothrow_move_constructible_v<_Er>)
   1289       requires is_move_constructible_v<_Er>
   1290 	    && (!is_trivially_move_constructible_v<_Er>)
   1291       : _M_void(), _M_has_value(__x._M_has_value)
   1292       {
   1293 	if (!_M_has_value)
   1294 	  std::construct_at(__builtin_addressof(_M_unex),
   1295 			    std::move(__x)._M_unex);
   1296       }
   1297 
   1298       template<typename _Up, typename _Gr>
   1299 	requires is_void_v<_Up>
   1300 	      && is_constructible_v<_Er, const _Gr&>
   1301 	      && (!__cons_from_expected<_Up, _Gr>)
   1302 	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
   1303 	expected(const expected<_Up, _Gr>& __x)
   1304 	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
   1305 	: _M_void(), _M_has_value(__x._M_has_value)
   1306 	{
   1307 	  if (!_M_has_value)
   1308 	    std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
   1309 	}
   1310 
   1311       template<typename _Up, typename _Gr>
   1312 	requires is_void_v<_Up>
   1313 	      && is_constructible_v<_Er, _Gr>
   1314 	      && (!__cons_from_expected<_Up, _Gr>)
   1315 	constexpr explicit(!is_convertible_v<_Gr, _Er>)
   1316 	expected(expected<_Up, _Gr>&& __x)
   1317 	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
   1318 	: _M_void(), _M_has_value(__x._M_has_value)
   1319 	{
   1320 	  if (!_M_has_value)
   1321 	    std::construct_at(__builtin_addressof(_M_unex),
   1322 			      std::move(__x)._M_unex);
   1323 	}
   1324 
   1325       template<typename _Gr = _Er>
   1326 	requires is_constructible_v<_Er, const _Gr&>
   1327 	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
   1328 	expected(const unexpected<_Gr>& __u)
   1329 	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
   1330 	: _M_unex(__u.error()), _M_has_value(false)
   1331 	{ }
   1332 
   1333       template<typename _Gr = _Er>
   1334 	requires is_constructible_v<_Er, _Gr>
   1335 	constexpr explicit(!is_convertible_v<_Gr, _Er>)
   1336 	expected(unexpected<_Gr>&& __u)
   1337 	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
   1338 	: _M_unex(std::move(__u).error()), _M_has_value(false)
   1339 	{ }
   1340 
   1341       constexpr explicit
   1342       expected(in_place_t) noexcept
   1343       : expected()
   1344       { }
   1345 
   1346       template<typename... _Args>
   1347 	requires is_constructible_v<_Er, _Args...>
   1348 	constexpr explicit
   1349 	expected(unexpect_t, _Args&&... __args)
   1350 	noexcept(is_nothrow_constructible_v<_Er, _Args...>)
   1351 	: _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
   1352 	{ }
   1353 
   1354       template<typename _Up, typename... _Args>
   1355 	requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
   1356 	constexpr explicit
   1357 	expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
   1358 	noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
   1359 					    _Args...>)
   1360 	: _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
   1361 	{ }
   1362 
   1363       constexpr ~expected() = default;
   1364 
   1365       constexpr ~expected() requires (!is_trivially_destructible_v<_Er>)
   1366       {
   1367 	if (!_M_has_value)
   1368 	  std::destroy_at(__builtin_addressof(_M_unex));
   1369       }
   1370 
   1371       // assignment
   1372 
   1373       expected& operator=(const expected&) = delete;
   1374 
   1375       constexpr expected&
   1376       operator=(const expected& __x)
   1377       noexcept(__and_v<is_nothrow_copy_constructible<_Er>,
   1378 		       is_nothrow_copy_assignable<_Er>>)
   1379       requires is_copy_constructible_v<_Er>
   1380 	    && is_copy_assignable_v<_Er>
   1381       {
   1382 	if (__x._M_has_value)
   1383 	  emplace();
   1384 	else
   1385 	  _M_assign_unex(__x._M_unex);
   1386 	return *this;
   1387       }
   1388 
   1389       constexpr expected&
   1390       operator=(expected&& __x)
   1391       noexcept(__and_v<is_nothrow_move_constructible<_Er>,
   1392 		       is_nothrow_move_assignable<_Er>>)
   1393       requires is_move_constructible_v<_Er>
   1394 	    && is_move_assignable_v<_Er>
   1395       {
   1396 	if (__x._M_has_value)
   1397 	  emplace();
   1398 	else
   1399 	  _M_assign_unex(std::move(__x._M_unex));
   1400 	return *this;
   1401       }
   1402 
   1403       template<typename _Gr>
   1404 	requires is_constructible_v<_Er, const _Gr&>
   1405 	      && is_assignable_v<_Er&, const _Gr&>
   1406 	constexpr expected&
   1407 	operator=(const unexpected<_Gr>& __e)
   1408 	{
   1409 	  _M_assign_unex(__e.error());
   1410 	  return *this;
   1411 	}
   1412 
   1413       template<typename _Gr>
   1414 	requires is_constructible_v<_Er, _Gr>
   1415 	      && is_assignable_v<_Er&, _Gr>
   1416 	constexpr expected&
   1417 	operator=(unexpected<_Gr>&& __e)
   1418 	{
   1419 	  _M_assign_unex(std::move(__e.error()));
   1420 	  return *this;
   1421 	}
   1422 
   1423       // modifiers
   1424 
   1425       constexpr void
   1426       emplace() noexcept
   1427       {
   1428 	if (!_M_has_value)
   1429 	  {
   1430 	    std::destroy_at(__builtin_addressof(_M_unex));
   1431 	    _M_has_value = true;
   1432 	  }
   1433       }
   1434 
   1435       // swap
   1436       constexpr void
   1437       swap(expected& __x)
   1438       noexcept(__and_v<is_nothrow_swappable<_Er&>,
   1439 		       is_nothrow_move_constructible<_Er>>)
   1440       requires is_swappable_v<_Er> && is_move_constructible_v<_Er>
   1441       {
   1442 	if (_M_has_value)
   1443 	  {
   1444 	    if (!__x._M_has_value)
   1445 	      {
   1446 		std::construct_at(__builtin_addressof(_M_unex),
   1447 				  std::move(__x._M_unex)); // might throw
   1448 		std::destroy_at(__builtin_addressof(__x._M_unex));
   1449 		_M_has_value = false;
   1450 		__x._M_has_value = true;
   1451 	      }
   1452 	  }
   1453 	else
   1454 	  {
   1455 	    if (__x._M_has_value)
   1456 	      {
   1457 		std::construct_at(__builtin_addressof(__x._M_unex),
   1458 				  std::move(_M_unex)); // might throw
   1459 		std::destroy_at(__builtin_addressof(_M_unex));
   1460 		_M_has_value = true;
   1461 		__x._M_has_value = false;
   1462 	      }
   1463 	    else
   1464 	      {
   1465 		using std::swap;
   1466 		swap(_M_unex, __x._M_unex);
   1467 	      }
   1468 	  }
   1469       }
   1470 
   1471       // observers
   1472 
   1473       [[nodiscard]]
   1474       constexpr explicit
   1475       operator bool() const noexcept { return _M_has_value; }
   1476 
   1477       [[nodiscard]]
   1478       constexpr bool has_value() const noexcept { return _M_has_value; }
   1479 
   1480       constexpr void
   1481       operator*() const noexcept { __glibcxx_assert(_M_has_value); }
   1482 
   1483       constexpr void
   1484       value() const&
   1485       {
   1486 	if (_M_has_value) [[likely]]
   1487 	  return;
   1488 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
   1489       }
   1490 
   1491       constexpr void
   1492       value() &&
   1493       {
   1494 	if (_M_has_value) [[likely]]
   1495 	  return;
   1496 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
   1497       }
   1498 
   1499       constexpr const _Er&
   1500       error() const & noexcept
   1501       {
   1502 	__glibcxx_assert(!_M_has_value);
   1503 	return _M_unex;
   1504       }
   1505 
   1506       constexpr _Er&
   1507       error() & noexcept
   1508       {
   1509 	__glibcxx_assert(!_M_has_value);
   1510 	return _M_unex;
   1511       }
   1512 
   1513       constexpr const _Er&&
   1514       error() const && noexcept
   1515       {
   1516 	__glibcxx_assert(!_M_has_value);
   1517 	return std::move(_M_unex);
   1518       }
   1519 
   1520       constexpr _Er&&
   1521       error() && noexcept
   1522       {
   1523 	__glibcxx_assert(!_M_has_value);
   1524 	return std::move(_M_unex);
   1525       }
   1526 
   1527       template<typename _Gr = _Er>
   1528 	constexpr _Er
   1529 	error_or(_Gr&& __e) const&
   1530 	{
   1531 	  static_assert( is_copy_constructible_v<_Er> );
   1532 	  static_assert( is_convertible_v<_Gr, _Er> );
   1533 
   1534 	  if (_M_has_value)
   1535 	    return std::forward<_Gr>(__e);
   1536 	  return _M_unex;
   1537 	}
   1538 
   1539       template<typename _Gr = _Er>
   1540 	constexpr _Er
   1541 	error_or(_Gr&& __e) &&
   1542 	{
   1543 	  static_assert( is_move_constructible_v<_Er> );
   1544 	  static_assert( is_convertible_v<_Gr, _Er> );
   1545 
   1546 	  if (_M_has_value)
   1547 	    return std::forward<_Gr>(__e);
   1548 	  return std::move(_M_unex);
   1549 	}
   1550 
   1551       // monadic operations
   1552 
   1553       template<typename _Fn> requires is_constructible_v<_Er, _Er&>
   1554 	constexpr auto
   1555 	and_then(_Fn&& __f) &
   1556 	{
   1557 	  using _Up = __expected::__result0<_Fn>;
   1558 	  static_assert(__expected::__is_expected<_Up>);
   1559 	  static_assert(is_same_v<typename _Up::error_type, _Er>);
   1560 
   1561 	  if (has_value())
   1562 	    return std::__invoke(std::forward<_Fn>(__f));
   1563 	  else
   1564 	    return _Up(unexpect, _M_unex);
   1565 	}
   1566 
   1567      template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
   1568 	constexpr auto
   1569 	and_then(_Fn&& __f) const &
   1570 	{
   1571 	  using _Up = __expected::__result0<_Fn>;
   1572 	  static_assert(__expected::__is_expected<_Up>);
   1573 	  static_assert(is_same_v<typename _Up::error_type, _Er>);
   1574 
   1575 	  if (has_value())
   1576 	    return std::__invoke(std::forward<_Fn>(__f));
   1577 	  else
   1578 	    return _Up(unexpect, _M_unex);
   1579 	}
   1580 
   1581       template<typename _Fn> requires is_constructible_v<_Er, _Er>
   1582 	constexpr auto
   1583 	and_then(_Fn&& __f) &&
   1584 	{
   1585 	  using _Up = __expected::__result0<_Fn>;
   1586 	  static_assert(__expected::__is_expected<_Up>);
   1587 	  static_assert(is_same_v<typename _Up::error_type, _Er>);
   1588 
   1589 	  if (has_value())
   1590 	    return std::__invoke(std::forward<_Fn>(__f));
   1591 	  else
   1592 	    return _Up(unexpect, std::move(_M_unex));
   1593 	}
   1594 
   1595        template<typename _Fn> requires is_constructible_v<_Er, const _Er>
   1596 	constexpr auto
   1597 	and_then(_Fn&& __f) const &&
   1598 	{
   1599 	  using _Up = __expected::__result0<_Fn>;
   1600 	  static_assert(__expected::__is_expected<_Up>);
   1601 	  static_assert(is_same_v<typename _Up::error_type, _Er>);
   1602 
   1603 	  if (has_value())
   1604 	    return std::__invoke(std::forward<_Fn>(__f));
   1605 	  else
   1606 	    return _Up(unexpect, std::move(_M_unex));
   1607 	}
   1608 
   1609       template<typename _Fn>
   1610 	constexpr auto
   1611 	or_else(_Fn&& __f) &
   1612 	{
   1613 	  using _Gr = __expected::__result<_Fn, _Er&>;
   1614 	  static_assert(__expected::__is_expected<_Gr>);
   1615 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
   1616 
   1617 	  if (has_value())
   1618 	    return _Gr();
   1619 	  else
   1620 	    return std::__invoke(std::forward<_Fn>(__f), _M_unex);
   1621 	}
   1622 
   1623       template<typename _Fn>
   1624 	constexpr auto
   1625 	or_else(_Fn&& __f) const &
   1626 	{
   1627 	  using _Gr = __expected::__result<_Fn, const _Er&>;
   1628 	  static_assert(__expected::__is_expected<_Gr>);
   1629 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
   1630 
   1631 	  if (has_value())
   1632 	    return _Gr();
   1633 	  else
   1634 	    return std::__invoke(std::forward<_Fn>(__f), _M_unex);
   1635 	}
   1636 
   1637       template<typename _Fn>
   1638 	constexpr auto
   1639 	or_else(_Fn&& __f) &&
   1640 	{
   1641 	  using _Gr = __expected::__result<_Fn, _Er&&>;
   1642 	  static_assert(__expected::__is_expected<_Gr>);
   1643 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
   1644 
   1645 	  if (has_value())
   1646 	    return _Gr();
   1647 	  else
   1648 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
   1649 	}
   1650 
   1651       template<typename _Fn>
   1652 	constexpr auto
   1653 	or_else(_Fn&& __f) const &&
   1654 	{
   1655 	  using _Gr = __expected::__result<_Fn, const _Er&&>;
   1656 	  static_assert(__expected::__is_expected<_Gr>);
   1657 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
   1658 
   1659 	  if (has_value())
   1660 	    return _Gr();
   1661 	  else
   1662 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
   1663 	}
   1664 
   1665       template<typename _Fn> requires is_constructible_v<_Er, _Er&>
   1666 	constexpr auto
   1667 	transform(_Fn&& __f) &
   1668 	{
   1669 	  using _Up = __expected::__result0_xform<_Fn>;
   1670 	  using _Res = expected<_Up, _Er>;
   1671 
   1672 	  if (has_value())
   1673 	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
   1674 	  else
   1675 	    return _Res(unexpect, _M_unex);
   1676 	}
   1677 
   1678       template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
   1679 	constexpr auto
   1680 	transform(_Fn&& __f) const &
   1681 	{
   1682 	  using _Up = __expected::__result0_xform<_Fn>;
   1683 	  using _Res = expected<_Up, _Er>;
   1684 
   1685 	  if (has_value())
   1686 	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
   1687 	  else
   1688 	    return _Res(unexpect, _M_unex);
   1689 	}
   1690 
   1691       template<typename _Fn> requires is_constructible_v<_Er, _Er>
   1692 	constexpr auto
   1693 	transform(_Fn&& __f) &&
   1694 	{
   1695 	  using _Up = __expected::__result0_xform<_Fn>;
   1696 	  using _Res = expected<_Up, _Er>;
   1697 
   1698 	  if (has_value())
   1699 	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
   1700 	  else
   1701 	    return _Res(unexpect, std::move(_M_unex));
   1702 	}
   1703 
   1704       template<typename _Fn> requires is_constructible_v<_Er, const _Er>
   1705 	constexpr auto
   1706 	transform(_Fn&& __f) const &&
   1707 	{
   1708 	  using _Up = __expected::__result0_xform<_Fn>;
   1709 	  using _Res = expected<_Up, _Er>;
   1710 
   1711 	  if (has_value())
   1712 	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
   1713 	  else
   1714 	    return _Res(unexpect, std::move(_M_unex));
   1715 	}
   1716 
   1717       template<typename _Fn>
   1718 	constexpr auto
   1719 	transform_error(_Fn&& __f) &
   1720 	{
   1721 	  using _Gr = __expected::__result_xform<_Fn, _Er&>;
   1722 	  using _Res = expected<_Tp, _Gr>;
   1723 
   1724 	  if (has_value())
   1725 	    return _Res();
   1726 	  else
   1727 	    return _Res(__unexpect_inv{}, [&]() {
   1728 			  return std::__invoke(std::forward<_Fn>(__f),
   1729 					       _M_unex);
   1730 			});
   1731 	}
   1732 
   1733       template<typename _Fn>
   1734 	constexpr auto
   1735 	transform_error(_Fn&& __f) const &
   1736 	{
   1737 	  using _Gr = __expected::__result_xform<_Fn, const _Er&>;
   1738 	  using _Res = expected<_Tp, _Gr>;
   1739 
   1740 	  if (has_value())
   1741 	    return _Res();
   1742 	  else
   1743 	    return _Res(__unexpect_inv{}, [&]() {
   1744 			  return std::__invoke(std::forward<_Fn>(__f),
   1745 					       _M_unex);
   1746 			});
   1747 	}
   1748 
   1749       template<typename _Fn>
   1750 	constexpr auto
   1751 	transform_error(_Fn&& __f) &&
   1752 	{
   1753 	  using _Gr = __expected::__result_xform<_Fn, _Er&&>;
   1754 	  using _Res = expected<_Tp, _Gr>;
   1755 
   1756 	  if (has_value())
   1757 	    return _Res();
   1758 	  else
   1759 	    return _Res(__unexpect_inv{}, [&]() {
   1760 			  return std::__invoke(std::forward<_Fn>(__f),
   1761 					       std::move(_M_unex));
   1762 			});
   1763 	}
   1764 
   1765       template<typename _Fn>
   1766 	constexpr auto
   1767 	transform_error(_Fn&& __f) const &&
   1768 	{
   1769 	  using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
   1770 	  using _Res = expected<_Tp, _Gr>;
   1771 
   1772 	  if (has_value())
   1773 	    return _Res();
   1774 	  else
   1775 	    return _Res(__unexpect_inv{}, [&]() {
   1776 			  return std::__invoke(std::forward<_Fn>(__f),
   1777 					       std::move(_M_unex));
   1778 			});
   1779 	}
   1780 
   1781       // equality operators
   1782 
   1783       template<typename _Up, typename _Er2>
   1784 	requires is_void_v<_Up>
   1785 	friend constexpr bool
   1786 	operator==(const expected& __x, const expected<_Up, _Er2>& __y)
   1787 	// FIXME: noexcept(noexcept(bool(__x.error() == __y.error())))
   1788 	{
   1789 	  if (__x.has_value())
   1790 	    return __y.has_value();
   1791 	  else
   1792 	    return !__y.has_value() && bool(__x.error() == __y.error());
   1793 	}
   1794 
   1795       template<typename _Er2>
   1796 	friend constexpr bool
   1797 	operator==(const expected& __x, const unexpected<_Er2>& __e)
   1798 	// FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
   1799 	{ return !__x.has_value() && bool(__x.error() == __e.error()); }
   1800 
   1801       friend constexpr void
   1802       swap(expected& __x, expected& __y)
   1803       noexcept(noexcept(__x.swap(__y)))
   1804       requires requires { __x.swap(__y); }
   1805       { __x.swap(__y); }
   1806 
   1807     private:
   1808       template<typename, typename> friend class expected;
   1809 
   1810       template<typename _Vp>
   1811 	constexpr void
   1812 	_M_assign_unex(_Vp&& __v)
   1813 	{
   1814 	  if (_M_has_value)
   1815 	    {
   1816 	      std::construct_at(__builtin_addressof(_M_unex),
   1817 				std::forward<_Vp>(__v));
   1818 	      _M_has_value = false;
   1819 	    }
   1820 	  else
   1821 	    _M_unex = std::forward<_Vp>(__v);
   1822 	}
   1823 
   1824       using __in_place_inv = __expected::__in_place_inv;
   1825       using __unexpect_inv = __expected::__unexpect_inv;
   1826 
   1827       template<typename _Fn>
   1828 	explicit constexpr
   1829 	expected(__in_place_inv, _Fn&& __fn)
   1830 	: _M_void(), _M_has_value(true)
   1831 	{ std::forward<_Fn>(__fn)(); }
   1832 
   1833       template<typename _Fn>
   1834 	explicit constexpr
   1835 	expected(__unexpect_inv, _Fn&& __fn)
   1836 	: _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
   1837 	{ }
   1838 
   1839       union {
   1840 	struct { } _M_void;
   1841 	_Er _M_unex;
   1842       };
   1843 
   1844       bool _M_has_value;
   1845     };
   1846   /// @}
   1847 
   1848 _GLIBCXX_END_NAMESPACE_VERSION
   1849 } // namespace std
   1850 
   1851 #endif // __cpp_lib_expected
   1852 #endif // _GLIBCXX_EXPECTED
   1853