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   // _GLIBCXX_RESOLVE_LIB_DEFECTS
    319   // 3836. std::expected<bool, E1> conversion constructor
    320   // expected(const expected<U, G>&) should take precedence over
    321   // expected(U&&) with operator bool
    322 
    323   // If T is cv bool, remove_cvref_t<U> is not a specialization of expected.
    324   template<typename _Tp, typename _Up>
    325     concept __not_constructing_bool_from_expected
    326       = ! is_same_v<remove_cv_t<_Tp>, bool>
    327 	  || ! __is_expected<remove_cvref_t<_Up>>;
    328 }
    329 /// @endcond
    330 
    331   template<typename _Tp, typename _Er>
    332     class expected
    333     {
    334       static_assert( ! is_reference_v<_Tp> );
    335       static_assert( ! is_function_v<_Tp> );
    336       static_assert( ! is_same_v<remove_cv_t<_Tp>, in_place_t> );
    337       static_assert( ! is_same_v<remove_cv_t<_Tp>, unexpect_t> );
    338       static_assert( ! __expected::__is_unexpected<remove_cv_t<_Tp>> );
    339       static_assert( __expected::__can_be_unexpected<_Er> );
    340 
    341       // If T is not cv bool, converts-from-any-cvref<T, expected<U, G>> and
    342       // is_constructible<unexpected<E>, cv expected<U, G> ref-qual> are false.
    343       template<typename _Up, typename _Gr, typename _Unex = unexpected<_Er>,
    344 	       typename = remove_cv_t<_Tp>>
    345 	static constexpr bool __cons_from_expected
    346 	  = __or_v<is_constructible<_Tp, expected<_Up, _Gr>&>,
    347 		   is_constructible<_Tp, expected<_Up, _Gr>>,
    348 		   is_constructible<_Tp, const expected<_Up, _Gr>&>,
    349 		   is_constructible<_Tp, const expected<_Up, _Gr>>,
    350 		   is_convertible<expected<_Up, _Gr>&, _Tp>,
    351 		   is_convertible<expected<_Up, _Gr>, _Tp>,
    352 		   is_convertible<const expected<_Up, _Gr>&, _Tp>,
    353 		   is_convertible<const expected<_Up, _Gr>, _Tp>,
    354 		   is_constructible<_Unex, expected<_Up, _Gr>&>,
    355 		   is_constructible<_Unex, expected<_Up, _Gr>>,
    356 		   is_constructible<_Unex, const expected<_Up, _Gr>&>,
    357 		   is_constructible<_Unex, const expected<_Up, _Gr>>
    358 		  >;
    359 
    360       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    361       // If t is cv bool, we know it can be constructed from expected<U, G>,
    362       // but we don't want to cause the expected(U&&) constructor to be used,
    363       // so we only check the is_constructible<unexpected<E>, ...> cases.
    364       template<typename _Up, typename _Gr, typename _Unex>
    365 	static constexpr bool __cons_from_expected<_Up, _Gr, _Unex, bool>
    366 	  = __or_v<is_constructible<_Unex, expected<_Up, _Gr>&>,
    367 		   is_constructible<_Unex, expected<_Up, _Gr>>,
    368 		   is_constructible<_Unex, const expected<_Up, _Gr>&>,
    369 		   is_constructible<_Unex, const expected<_Up, _Gr>>
    370 		  >;
    371 
    372       template<typename _Up, typename _Gr>
    373 	constexpr static bool __explicit_conv
    374 	  = __or_v<__not_<is_convertible<_Up, _Tp>>,
    375 		   __not_<is_convertible<_Gr, _Er>>
    376 		  >;
    377 
    378       template<typename _Up>
    379 	static constexpr bool __same_val
    380 	  = is_same_v<typename _Up::value_type, _Tp>;
    381 
    382       template<typename _Up>
    383 	static constexpr bool __same_err
    384 	  = is_same_v<typename _Up::error_type, _Er>;
    385 
    386     public:
    387       using value_type = _Tp;
    388       using error_type = _Er;
    389       using unexpected_type = unexpected<_Er>;
    390 
    391       template<typename _Up>
    392 	using rebind = expected<_Up, error_type>;
    393 
    394       constexpr
    395       expected()
    396       noexcept(is_nothrow_default_constructible_v<_Tp>)
    397       requires is_default_constructible_v<_Tp>
    398       : _M_val(), _M_has_value(true)
    399       { }
    400 
    401       expected(const expected&) = default;
    402 
    403       constexpr
    404       expected(const expected& __x)
    405       noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
    406 		       is_nothrow_copy_constructible<_Er>>)
    407       requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Er>
    408       && (!is_trivially_copy_constructible_v<_Tp>
    409 	  || !is_trivially_copy_constructible_v<_Er>)
    410       : _M_has_value(__x._M_has_value)
    411       {
    412 	if (_M_has_value)
    413 	  std::construct_at(__builtin_addressof(_M_val), __x._M_val);
    414 	else
    415 	  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
    416       }
    417 
    418       expected(expected&&) = default;
    419 
    420       constexpr
    421       expected(expected&& __x)
    422       noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
    423 		       is_nothrow_move_constructible<_Er>>)
    424       requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Er>
    425       && (!is_trivially_move_constructible_v<_Tp>
    426 	  || !is_trivially_move_constructible_v<_Er>)
    427       : _M_has_value(__x._M_has_value)
    428       {
    429 	if (_M_has_value)
    430 	  std::construct_at(__builtin_addressof(_M_val),
    431 			    std::move(__x)._M_val);
    432 	else
    433 	  std::construct_at(__builtin_addressof(_M_unex),
    434 			    std::move(__x)._M_unex);
    435       }
    436 
    437       template<typename _Up, typename _Gr>
    438 	requires is_constructible_v<_Tp, const _Up&>
    439 	      && is_constructible_v<_Er, const _Gr&>
    440 	      && (!__cons_from_expected<_Up, _Gr>)
    441 	constexpr explicit(__explicit_conv<const _Up&, const _Gr&>)
    442 	expected(const expected<_Up, _Gr>& __x)
    443 	noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
    444 			 is_nothrow_constructible<_Er, const _Gr&>>)
    445 	: _M_has_value(__x._M_has_value)
    446 	{
    447 	  if (_M_has_value)
    448 	    std::construct_at(__builtin_addressof(_M_val), __x._M_val);
    449 	  else
    450 	    std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
    451 	}
    452 
    453       template<typename _Up, typename _Gr>
    454 	requires is_constructible_v<_Tp, _Up>
    455 	      && is_constructible_v<_Er, _Gr>
    456 	      && (!__cons_from_expected<_Up, _Gr>)
    457 	constexpr explicit(__explicit_conv<_Up, _Gr>)
    458 	expected(expected<_Up, _Gr>&& __x)
    459 	noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
    460 			 is_nothrow_constructible<_Er, _Gr>>)
    461 	: _M_has_value(__x._M_has_value)
    462 	{
    463 	  if (_M_has_value)
    464 	    std::construct_at(__builtin_addressof(_M_val),
    465 			      std::move(__x)._M_val);
    466 	  else
    467 	    std::construct_at(__builtin_addressof(_M_unex),
    468 			      std::move(__x)._M_unex);
    469 	}
    470 
    471       template<typename _Up = _Tp>
    472 	requires (!is_same_v<remove_cvref_t<_Up>, expected>)
    473 	  && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
    474 	  && (!is_same_v<remove_cvref_t<_Up>, unexpect_t>)
    475 	  && is_constructible_v<_Tp, _Up>
    476 	  && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
    477 	  && __expected::__not_constructing_bool_from_expected<_Tp, _Up>
    478 	constexpr explicit(!is_convertible_v<_Up, _Tp>)
    479 	expected(_Up&& __v)
    480 	noexcept(is_nothrow_constructible_v<_Tp, _Up>)
    481 	: _M_val(std::forward<_Up>(__v)), _M_has_value(true)
    482 	{ }
    483 
    484       template<typename _Gr = _Er>
    485 	requires is_constructible_v<_Er, const _Gr&>
    486 	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
    487 	expected(const unexpected<_Gr>& __u)
    488 	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
    489 	: _M_unex(__u.error()), _M_has_value(false)
    490 	{ }
    491 
    492       template<typename _Gr = _Er>
    493 	requires is_constructible_v<_Er, _Gr>
    494 	constexpr explicit(!is_convertible_v<_Gr, _Er>)
    495 	expected(unexpected<_Gr>&& __u)
    496 	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
    497 	: _M_unex(std::move(__u).error()), _M_has_value(false)
    498 	{ }
    499 
    500       template<typename... _Args>
    501 	requires is_constructible_v<_Tp, _Args...>
    502 	constexpr explicit
    503 	expected(in_place_t, _Args&&... __args)
    504 	noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
    505 	: _M_val(std::forward<_Args>(__args)...), _M_has_value(true)
    506 	{ }
    507 
    508       template<typename _Up, typename... _Args>
    509 	requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
    510 	constexpr explicit
    511 	expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
    512 	noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
    513 					    _Args...>)
    514 	: _M_val(__il, std::forward<_Args>(__args)...), _M_has_value(true)
    515 	{ }
    516 
    517       template<typename... _Args>
    518 	requires is_constructible_v<_Er, _Args...>
    519 	constexpr explicit
    520 	expected(unexpect_t, _Args&&... __args)
    521 	noexcept(is_nothrow_constructible_v<_Er, _Args...>)
    522 	: _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
    523 	{ }
    524 
    525       template<typename _Up, typename... _Args>
    526 	requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
    527 	constexpr explicit
    528 	expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
    529 	noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
    530 					    _Args...>)
    531 	: _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
    532 	{ }
    533 
    534       constexpr ~expected() = default;
    535 
    536       constexpr ~expected()
    537       requires (!is_trivially_destructible_v<_Tp>)
    538 	    || (!is_trivially_destructible_v<_Er>)
    539       {
    540 	if (_M_has_value)
    541 	  std::destroy_at(__builtin_addressof(_M_val));
    542 	else
    543 	  std::destroy_at(__builtin_addressof(_M_unex));
    544       }
    545 
    546       // assignment
    547 
    548       expected& operator=(const expected&) = delete;
    549 
    550       constexpr expected&
    551       operator=(const expected& __x)
    552       noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
    553 		       is_nothrow_copy_constructible<_Er>,
    554 		       is_nothrow_copy_assignable<_Tp>,
    555 		       is_nothrow_copy_assignable<_Er>>)
    556       requires is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp>
    557 	    && is_copy_assignable_v<_Er> && is_copy_constructible_v<_Er>
    558 	    && (is_nothrow_move_constructible_v<_Tp>
    559 		|| is_nothrow_move_constructible_v<_Er>)
    560       {
    561 	if (__x._M_has_value)
    562 	  this->_M_assign_val(__x._M_val);
    563 	else
    564 	  this->_M_assign_unex(__x._M_unex);
    565 	return *this;
    566       }
    567 
    568       constexpr expected&
    569       operator=(expected&& __x)
    570       noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
    571 		       is_nothrow_move_constructible<_Er>,
    572 		       is_nothrow_move_assignable<_Tp>,
    573 		       is_nothrow_move_assignable<_Er>>)
    574       requires is_move_assignable_v<_Tp> && is_move_constructible_v<_Tp>
    575 	    && is_move_assignable_v<_Er> && is_move_constructible_v<_Er>
    576 	    && (is_nothrow_move_constructible_v<_Tp>
    577 		|| is_nothrow_move_constructible_v<_Er>)
    578       {
    579 	if (__x._M_has_value)
    580 	  _M_assign_val(std::move(__x._M_val));
    581 	else
    582 	  _M_assign_unex(std::move(__x._M_unex));
    583 	return *this;
    584       }
    585 
    586       template<typename _Up = _Tp>
    587 	requires (!is_same_v<expected, remove_cvref_t<_Up>>)
    588 	      && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
    589 	      && is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up>
    590 	      && (is_nothrow_constructible_v<_Tp, _Up>
    591 		  || is_nothrow_move_constructible_v<_Tp>
    592 		  || is_nothrow_move_constructible_v<_Er>)
    593 	constexpr expected&
    594 	operator=(_Up&& __v)
    595 	{
    596 	  _M_assign_val(std::forward<_Up>(__v));
    597 	  return *this;
    598 	}
    599 
    600       template<typename _Gr>
    601 	requires is_constructible_v<_Er, const _Gr&>
    602 	      && is_assignable_v<_Er&, const _Gr&>
    603 	      && (is_nothrow_constructible_v<_Er, const _Gr&>
    604 		  || is_nothrow_move_constructible_v<_Tp>
    605 		  || is_nothrow_move_constructible_v<_Er>)
    606 	constexpr expected&
    607 	operator=(const unexpected<_Gr>& __e)
    608 	{
    609 	  _M_assign_unex(__e.error());
    610 	  return *this;
    611 	}
    612 
    613       template<typename _Gr>
    614 	requires is_constructible_v<_Er, _Gr>
    615 	      && is_assignable_v<_Er&, _Gr>
    616 	      && (is_nothrow_constructible_v<_Er, _Gr>
    617 		  || is_nothrow_move_constructible_v<_Tp>
    618 		  || is_nothrow_move_constructible_v<_Er>)
    619 	constexpr expected&
    620 	operator=(unexpected<_Gr>&& __e)
    621 	{
    622 	  _M_assign_unex(std::move(__e).error());
    623 	  return *this;
    624 	}
    625 
    626       // modifiers
    627 
    628       template<typename... _Args>
    629 	requires is_nothrow_constructible_v<_Tp, _Args...>
    630 	constexpr _Tp&
    631 	emplace(_Args&&... __args) noexcept
    632 	{
    633 	  if (_M_has_value)
    634 	    std::destroy_at(__builtin_addressof(_M_val));
    635 	  else
    636 	    {
    637 	      std::destroy_at(__builtin_addressof(_M_unex));
    638 	      _M_has_value = true;
    639 	    }
    640 	  std::construct_at(__builtin_addressof(_M_val),
    641 			    std::forward<_Args>(__args)...);
    642 	  return _M_val;
    643 	}
    644 
    645       template<typename _Up, typename... _Args>
    646 	requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
    647 					    _Args...>
    648 	constexpr _Tp&
    649 	emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept
    650 	{
    651 	  if (_M_has_value)
    652 	    std::destroy_at(__builtin_addressof(_M_val));
    653 	  else
    654 	    {
    655 	      std::destroy_at(__builtin_addressof(_M_unex));
    656 	      _M_has_value = true;
    657 	    }
    658 	  std::construct_at(__builtin_addressof(_M_val),
    659 			    __il, std::forward<_Args>(__args)...);
    660 	  return _M_val;
    661 	}
    662 
    663       // swap
    664       constexpr void
    665       swap(expected& __x)
    666       noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
    667 		       is_nothrow_move_constructible<_Er>,
    668 		       is_nothrow_swappable<_Tp&>,
    669 		       is_nothrow_swappable<_Er&>>)
    670       requires is_swappable_v<_Tp> && is_swappable_v<_Er>
    671 	    && is_move_constructible_v<_Tp>
    672 	    && is_move_constructible_v<_Er>
    673 	    && (is_nothrow_move_constructible_v<_Tp>
    674 		|| is_nothrow_move_constructible_v<_Er>)
    675       {
    676 	if (_M_has_value)
    677 	  {
    678 	    if (__x._M_has_value)
    679 	      {
    680 		using std::swap;
    681 		swap(_M_val, __x._M_val);
    682 	      }
    683 	    else
    684 	      this->_M_swap_val_unex(__x);
    685 	  }
    686 	else
    687 	  {
    688 	    if (__x._M_has_value)
    689 	      __x._M_swap_val_unex(*this);
    690 	    else
    691 	      {
    692 		using std::swap;
    693 		swap(_M_unex, __x._M_unex);
    694 	      }
    695 	  }
    696       }
    697 
    698       // observers
    699 
    700       [[nodiscard]]
    701       constexpr const _Tp*
    702       operator->() const noexcept
    703       {
    704 	__glibcxx_assert(_M_has_value);
    705 	return __builtin_addressof(_M_val);
    706       }
    707 
    708       [[nodiscard]]
    709       constexpr _Tp*
    710       operator->() noexcept
    711       {
    712 	__glibcxx_assert(_M_has_value);
    713 	return __builtin_addressof(_M_val);
    714       }
    715 
    716       [[nodiscard]]
    717       constexpr const _Tp&
    718       operator*() const & noexcept
    719       {
    720 	__glibcxx_assert(_M_has_value);
    721 	return _M_val;
    722       }
    723 
    724       [[nodiscard]]
    725       constexpr _Tp&
    726       operator*() & noexcept
    727       {
    728 	__glibcxx_assert(_M_has_value);
    729 	return _M_val;
    730       }
    731 
    732       [[nodiscard]]
    733       constexpr const _Tp&&
    734       operator*() const && noexcept
    735       {
    736 	__glibcxx_assert(_M_has_value);
    737 	return std::move(_M_val);
    738       }
    739 
    740       [[nodiscard]]
    741       constexpr _Tp&&
    742       operator*() && noexcept
    743       {
    744 	__glibcxx_assert(_M_has_value);
    745 	return std::move(_M_val);
    746       }
    747 
    748       [[nodiscard]]
    749       constexpr explicit
    750       operator bool() const noexcept { return _M_has_value; }
    751 
    752       [[nodiscard]]
    753       constexpr bool has_value() const noexcept { return _M_has_value; }
    754 
    755       constexpr const _Tp&
    756       value() const &
    757       {
    758 	if (_M_has_value) [[likely]]
    759 	  return _M_val;
    760 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
    761       }
    762 
    763       constexpr _Tp&
    764       value() &
    765       {
    766 	if (_M_has_value) [[likely]]
    767 	  return _M_val;
    768 	const auto& __unex = _M_unex;
    769 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(__unex));
    770       }
    771 
    772       constexpr const _Tp&&
    773       value() const &&
    774       {
    775 	if (_M_has_value) [[likely]]
    776 	  return std::move(_M_val);
    777 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
    778       }
    779 
    780       constexpr _Tp&&
    781       value() &&
    782       {
    783 	if (_M_has_value) [[likely]]
    784 	  return std::move(_M_val);
    785 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
    786       }
    787 
    788       constexpr const _Er&
    789       error() const & noexcept
    790       {
    791 	__glibcxx_assert(!_M_has_value);
    792 	return _M_unex;
    793       }
    794 
    795       constexpr _Er&
    796       error() & noexcept
    797       {
    798 	__glibcxx_assert(!_M_has_value);
    799 	return _M_unex;
    800       }
    801 
    802       constexpr const _Er&&
    803       error() const && noexcept
    804       {
    805 	__glibcxx_assert(!_M_has_value);
    806 	return std::move(_M_unex);
    807       }
    808 
    809       constexpr _Er&&
    810       error() && noexcept
    811       {
    812 	__glibcxx_assert(!_M_has_value);
    813 	return std::move(_M_unex);
    814       }
    815 
    816       template<typename _Up>
    817 	constexpr _Tp
    818 	value_or(_Up&& __v) const &
    819 	noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
    820 			 is_nothrow_convertible<_Up, _Tp>>)
    821 	{
    822 	  static_assert( is_copy_constructible_v<_Tp> );
    823 	  static_assert( is_convertible_v<_Up, _Tp> );
    824 
    825 	  if (_M_has_value)
    826 	    return _M_val;
    827 	  return static_cast<_Tp>(std::forward<_Up>(__v));
    828 	}
    829 
    830       template<typename _Up>
    831 	constexpr _Tp
    832 	value_or(_Up&& __v) &&
    833 	noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
    834 			 is_nothrow_convertible<_Up, _Tp>>)
    835 	{
    836 	  static_assert( is_move_constructible_v<_Tp> );
    837 	  static_assert( is_convertible_v<_Up, _Tp> );
    838 
    839 	  if (_M_has_value)
    840 	    return std::move(_M_val);
    841 	  return static_cast<_Tp>(std::forward<_Up>(__v));
    842 	}
    843 
    844       template<typename _Gr = _Er>
    845 	constexpr _Er
    846 	error_or(_Gr&& __e) const&
    847 	{
    848 	  static_assert( is_copy_constructible_v<_Er> );
    849 	  static_assert( is_convertible_v<_Gr, _Er> );
    850 
    851 	  if (_M_has_value)
    852 	    return std::forward<_Gr>(__e);
    853 	  return _M_unex;
    854 	}
    855 
    856       template<typename _Gr = _Er>
    857 	constexpr _Er
    858 	error_or(_Gr&& __e) &&
    859 	{
    860 	  static_assert( is_move_constructible_v<_Er> );
    861 	  static_assert( is_convertible_v<_Gr, _Er> );
    862 
    863 	  if (_M_has_value)
    864 	    return std::forward<_Gr>(__e);
    865 	  return std::move(_M_unex);
    866 	}
    867 
    868       // monadic operations
    869 
    870       template<typename _Fn> requires is_constructible_v<_Er, _Er&>
    871 	constexpr auto
    872 	and_then(_Fn&& __f) &
    873 	{
    874 	  using _Up = __expected::__result<_Fn, _Tp&>;
    875 	  static_assert(__expected::__is_expected<_Up>,
    876 			"the function passed to std::expected<T, E>::and_then "
    877 			"must return a std::expected");
    878 	  static_assert(is_same_v<typename _Up::error_type, _Er>,
    879 			"the function passed to std::expected<T, E>::and_then "
    880 			"must return a std::expected with the same error_type");
    881 
    882 	  if (has_value())
    883 	    return std::__invoke(std::forward<_Fn>(__f), _M_val);
    884 	  else
    885 	    return _Up(unexpect, _M_unex);
    886 	}
    887 
    888       template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
    889 	constexpr auto
    890 	and_then(_Fn&& __f) const &
    891 	{
    892 	  using _Up = __expected::__result<_Fn, const _Tp&>;
    893 	  static_assert(__expected::__is_expected<_Up>,
    894 			"the function passed to std::expected<T, E>::and_then "
    895 			"must return a std::expected");
    896 	  static_assert(is_same_v<typename _Up::error_type, _Er>,
    897 			"the function passed to std::expected<T, E>::and_then "
    898 			"must return a std::expected with the same error_type");
    899 
    900 	  if (has_value())
    901 	    return std::__invoke(std::forward<_Fn>(__f), _M_val);
    902 	  else
    903 	    return _Up(unexpect, _M_unex);
    904 	}
    905 
    906       template<typename _Fn> requires is_constructible_v<_Er, _Er>
    907 	constexpr auto
    908 	and_then(_Fn&& __f) &&
    909 	{
    910 	  using _Up = __expected::__result<_Fn, _Tp&&>;
    911 	  static_assert(__expected::__is_expected<_Up>,
    912 			"the function passed to std::expected<T, E>::and_then "
    913 			"must return a std::expected");
    914 	  static_assert(is_same_v<typename _Up::error_type, _Er>,
    915 			"the function passed to std::expected<T, E>::and_then "
    916 			"must return a std::expected with the same error_type");
    917 
    918 	  if (has_value())
    919 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
    920 	  else
    921 	    return _Up(unexpect, std::move(_M_unex));
    922 	}
    923 
    924 
    925       template<typename _Fn> requires is_constructible_v<_Er, const _Er>
    926 	constexpr auto
    927 	and_then(_Fn&& __f) const &&
    928 	{
    929 	  using _Up = __expected::__result<_Fn, const _Tp&&>;
    930 	  static_assert(__expected::__is_expected<_Up>,
    931 			"the function passed to std::expected<T, E>::and_then "
    932 			"must return a std::expected");
    933 	  static_assert(is_same_v<typename _Up::error_type, _Er>,
    934 			"the function passed to std::expected<T, E>::and_then "
    935 			"must return a std::expected with the same error_type");
    936 
    937 	  if (has_value())
    938 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
    939 	  else
    940 	    return _Up(unexpect, std::move(_M_unex));
    941 	}
    942 
    943       template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
    944 	constexpr auto
    945 	or_else(_Fn&& __f) &
    946 	{
    947 	  using _Gr = __expected::__result<_Fn, _Er&>;
    948 	  static_assert(__expected::__is_expected<_Gr>,
    949 			"the function passed to std::expected<T, E>::or_else "
    950 			"must return a std::expected");
    951 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
    952 			"the function passed to std::expected<T, E>::or_else "
    953 			"must return a std::expected with the same value_type");
    954 
    955 	  if (has_value())
    956 	    return _Gr(in_place, _M_val);
    957 	  else
    958 	    return std::__invoke(std::forward<_Fn>(__f), _M_unex);
    959 	}
    960 
    961       template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
    962 	constexpr auto
    963 	or_else(_Fn&& __f) const &
    964 	{
    965 	  using _Gr = __expected::__result<_Fn, const _Er&>;
    966 	  static_assert(__expected::__is_expected<_Gr>,
    967 			"the function passed to std::expected<T, E>::or_else "
    968 			"must return a std::expected");
    969 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
    970 			"the function passed to std::expected<T, E>::or_else "
    971 			"must return a std::expected with the same value_type");
    972 
    973 	  if (has_value())
    974 	    return _Gr(in_place, _M_val);
    975 	  else
    976 	    return std::__invoke(std::forward<_Fn>(__f), _M_unex);
    977 	}
    978 
    979 
    980       template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
    981 	constexpr auto
    982 	or_else(_Fn&& __f) &&
    983 	{
    984 	  using _Gr = __expected::__result<_Fn, _Er&&>;
    985 	  static_assert(__expected::__is_expected<_Gr>,
    986 			"the function passed to std::expected<T, E>::or_else "
    987 			"must return a std::expected");
    988 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
    989 			"the function passed to std::expected<T, E>::or_else "
    990 			"must return a std::expected with the same value_type");
    991 
    992 	  if (has_value())
    993 	    return _Gr(in_place, std::move(_M_val));
    994 	  else
    995 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
    996 	}
    997 
    998       template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
    999 	constexpr auto
   1000 	or_else(_Fn&& __f) const &&
   1001 	{
   1002 	  using _Gr = __expected::__result<_Fn, const _Er&&>;
   1003 	  static_assert(__expected::__is_expected<_Gr>,
   1004 			"the function passed to std::expected<T, E>::or_else "
   1005 			"must return a std::expected");
   1006 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
   1007 			"the function passed to std::expected<T, E>::or_else "
   1008 			"must return a std::expected with the same value_type");
   1009 
   1010 	  if (has_value())
   1011 	    return _Gr(in_place, std::move(_M_val));
   1012 	  else
   1013 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
   1014 	}
   1015 
   1016       template<typename _Fn> requires is_constructible_v<_Er, _Er&>
   1017 	constexpr auto
   1018 	transform(_Fn&& __f) &
   1019 	{
   1020 	  using _Up = __expected::__result_xform<_Fn, _Tp&>;
   1021 	  using _Res = expected<_Up, _Er>;
   1022 
   1023 	  if (has_value())
   1024 	    return _Res(__in_place_inv{}, [&]() {
   1025 			  return std::__invoke(std::forward<_Fn>(__f),
   1026 					       _M_val);
   1027 			});
   1028 	  else
   1029 	    return _Res(unexpect, _M_unex);
   1030 	}
   1031 
   1032       template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
   1033 	constexpr auto
   1034 	transform(_Fn&& __f) const &
   1035 	{
   1036 	  using _Up = __expected::__result_xform<_Fn, const _Tp&>;
   1037 	  using _Res = expected<_Up, _Er>;
   1038 
   1039 	  if (has_value())
   1040 	    return _Res(__in_place_inv{}, [&]() {
   1041 			  return std::__invoke(std::forward<_Fn>(__f),
   1042 					       _M_val);
   1043 			});
   1044 	  else
   1045 	    return _Res(unexpect, _M_unex);
   1046 	}
   1047 
   1048       template<typename _Fn> requires is_constructible_v<_Er, _Er>
   1049 	constexpr auto
   1050 	transform(_Fn&& __f) &&
   1051 	{
   1052 	  using _Up = __expected::__result_xform<_Fn, _Tp>;
   1053 	  using _Res = expected<_Up, _Er>;
   1054 
   1055 	  if (has_value())
   1056 	    return _Res(__in_place_inv{}, [&]() {
   1057 			  return std::__invoke(std::forward<_Fn>(__f),
   1058 					       std::move(_M_val));
   1059 			});
   1060 	  else
   1061 	    return _Res(unexpect, std::move(_M_unex));
   1062 	}
   1063 
   1064       template<typename _Fn> requires is_constructible_v<_Er, const _Er>
   1065 	constexpr auto
   1066 	transform(_Fn&& __f) const &&
   1067 	{
   1068 	  using _Up = __expected::__result_xform<_Fn, const _Tp>;
   1069 	  using _Res = expected<_Up, _Er>;
   1070 
   1071 	  if (has_value())
   1072 	    return _Res(__in_place_inv{}, [&]() {
   1073 			  return std::__invoke(std::forward<_Fn>(__f),
   1074 					       std::move(_M_val));
   1075 			});
   1076 	  else
   1077 	    return _Res(unexpect, std::move(_M_unex));
   1078 	}
   1079 
   1080       template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
   1081 	constexpr auto
   1082 	transform_error(_Fn&& __f) &
   1083 	{
   1084 	  using _Gr = __expected::__result_xform<_Fn, _Er&>;
   1085 	  using _Res = expected<_Tp, _Gr>;
   1086 
   1087 	  if (has_value())
   1088 	    return _Res(in_place, _M_val);
   1089 	  else
   1090 	    return _Res(__unexpect_inv{}, [&]() {
   1091 			  return std::__invoke(std::forward<_Fn>(__f),
   1092 					       _M_unex);
   1093 			});
   1094 	}
   1095 
   1096       template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
   1097 	constexpr auto
   1098 	transform_error(_Fn&& __f) const &
   1099 	{
   1100 	  using _Gr = __expected::__result_xform<_Fn, const _Er&>;
   1101 	  using _Res = expected<_Tp, _Gr>;
   1102 
   1103 	  if (has_value())
   1104 	    return _Res(in_place, _M_val);
   1105 	  else
   1106 	    return _Res(__unexpect_inv{}, [&]() {
   1107 			  return std::__invoke(std::forward<_Fn>(__f),
   1108 					       _M_unex);
   1109 			});
   1110 	}
   1111 
   1112       template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
   1113 	constexpr auto
   1114 	transform_error(_Fn&& __f) &&
   1115 	{
   1116 	  using _Gr = __expected::__result_xform<_Fn, _Er&&>;
   1117 	  using _Res = expected<_Tp, _Gr>;
   1118 
   1119 	  if (has_value())
   1120 	    return _Res(in_place, std::move(_M_val));
   1121 	  else
   1122 	    return _Res(__unexpect_inv{}, [&]() {
   1123 			  return std::__invoke(std::forward<_Fn>(__f),
   1124 					       std::move(_M_unex));
   1125 			});
   1126 	}
   1127 
   1128       template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
   1129 	constexpr auto
   1130 	transform_error(_Fn&& __f) const &&
   1131 	{
   1132 	  using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
   1133 	  using _Res = expected<_Tp, _Gr>;
   1134 
   1135 	  if (has_value())
   1136 	    return _Res(in_place, std::move(_M_val));
   1137 	  else
   1138 	    return _Res(__unexpect_inv{}, [&]() {
   1139 			  return std::__invoke(std::forward<_Fn>(__f),
   1140 					       std::move(_M_unex));
   1141 			});
   1142 	}
   1143 
   1144       // equality operators
   1145 
   1146       template<typename _Up, typename _Er2>
   1147 	requires (!is_void_v<_Up>)
   1148 	friend constexpr bool
   1149 	operator==(const expected& __x, const expected<_Up, _Er2>& __y)
   1150 	// FIXME: noexcept(noexcept(bool(*__x == *__y))
   1151 		  // && noexcept(bool(__x.error() == __y.error())))
   1152 	{
   1153 	  if (__x.has_value())
   1154 	    return __y.has_value() && bool(*__x == *__y);
   1155 	  else
   1156 	    return !__y.has_value() && bool(__x.error() == __y.error());
   1157 	}
   1158 
   1159       template<typename _Up>
   1160 	friend constexpr bool
   1161 	operator==(const expected& __x, const _Up& __v)
   1162 	// FIXME: noexcept(noexcept(bool(*__x == __v)))
   1163 	{ return __x.has_value() && bool(*__x == __v); }
   1164 
   1165       template<typename _Er2>
   1166 	friend constexpr bool
   1167 	operator==(const expected& __x, const unexpected<_Er2>& __e)
   1168 	// FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
   1169 	{ return !__x.has_value() && bool(__x.error() == __e.error()); }
   1170 
   1171       friend constexpr void
   1172       swap(expected& __x, expected& __y)
   1173       noexcept(noexcept(__x.swap(__y)))
   1174       requires requires {__x.swap(__y);}
   1175       { __x.swap(__y); }
   1176 
   1177     private:
   1178       template<typename, typename> friend class expected;
   1179 
   1180       template<typename _Vp>
   1181 	constexpr void
   1182 	_M_assign_val(_Vp&& __v)
   1183 	{
   1184 	  if (_M_has_value)
   1185 	    _M_val = std::forward<_Vp>(__v);
   1186 	  else
   1187 	    {
   1188 	      __expected::__reinit(__builtin_addressof(_M_val),
   1189 				   __builtin_addressof(_M_unex),
   1190 				   std::forward<_Vp>(__v));
   1191 	      _M_has_value = true;
   1192 	    }
   1193 	}
   1194 
   1195       template<typename _Vp>
   1196 	constexpr void
   1197 	_M_assign_unex(_Vp&& __v)
   1198 	{
   1199 	  if (_M_has_value)
   1200 	    {
   1201 	      __expected::__reinit(__builtin_addressof(_M_unex),
   1202 				   __builtin_addressof(_M_val),
   1203 				   std::forward<_Vp>(__v));
   1204 	      _M_has_value = false;
   1205 	    }
   1206 	  else
   1207 	    _M_unex = std::forward<_Vp>(__v);
   1208 	}
   1209 
   1210       // Swap two expected objects when only one has a value.
   1211       // Precondition: this->_M_has_value && !__rhs._M_has_value
   1212       constexpr void
   1213       _M_swap_val_unex(expected& __rhs)
   1214       noexcept(__and_v<is_nothrow_move_constructible<_Er>,
   1215 		       is_nothrow_move_constructible<_Tp>>)
   1216       {
   1217 	if constexpr (is_nothrow_move_constructible_v<_Er>)
   1218 	  {
   1219 	    __expected::_Guard<_Er> __guard(__rhs._M_unex);
   1220 	    std::construct_at(__builtin_addressof(__rhs._M_val),
   1221 			      std::move(_M_val)); // might throw
   1222 	    __rhs._M_has_value = true;
   1223 	    std::destroy_at(__builtin_addressof(_M_val));
   1224 	    std::construct_at(__builtin_addressof(_M_unex),
   1225 			      __guard.release());
   1226 	    _M_has_value = false;
   1227 	  }
   1228 	else
   1229 	  {
   1230 	    __expected::_Guard<_Tp> __guard(_M_val);
   1231 	    std::construct_at(__builtin_addressof(_M_unex),
   1232 			      std::move(__rhs._M_unex)); // might throw
   1233 	    _M_has_value = false;
   1234 	    std::destroy_at(__builtin_addressof(__rhs._M_unex));
   1235 	    std::construct_at(__builtin_addressof(__rhs._M_val),
   1236 			      __guard.release());
   1237 	    __rhs._M_has_value = true;
   1238 	  }
   1239       }
   1240 
   1241       using __in_place_inv = __expected::__in_place_inv;
   1242       using __unexpect_inv = __expected::__unexpect_inv;
   1243 
   1244       template<typename _Fn>
   1245 	explicit constexpr
   1246 	expected(__in_place_inv, _Fn&& __fn)
   1247 	: _M_val(std::forward<_Fn>(__fn)()), _M_has_value(true)
   1248 	{ }
   1249 
   1250       template<typename _Fn>
   1251 	explicit constexpr
   1252 	expected(__unexpect_inv, _Fn&& __fn)
   1253 	: _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
   1254 	{ }
   1255 
   1256       union {
   1257 	_Tp _M_val;
   1258 	_Er _M_unex;
   1259       };
   1260 
   1261       bool _M_has_value;
   1262     };
   1263 
   1264   // Partial specialization for std::expected<cv void, E>
   1265   template<typename _Tp, typename _Er> requires is_void_v<_Tp>
   1266     class expected<_Tp, _Er>
   1267     {
   1268       static_assert( __expected::__can_be_unexpected<_Er> );
   1269 
   1270       template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
   1271 	static constexpr bool __cons_from_expected
   1272 	  = __or_v<is_constructible<_Unex, expected<_Up, _Err>&>,
   1273 		   is_constructible<_Unex, expected<_Up, _Err>>,
   1274 		   is_constructible<_Unex, const expected<_Up, _Err>&>,
   1275 		   is_constructible<_Unex, const expected<_Up, _Err>>
   1276 		  >;
   1277 
   1278       template<typename _Up>
   1279 	static constexpr bool __same_val
   1280 	  = is_same_v<typename _Up::value_type, _Tp>;
   1281 
   1282       template<typename _Up>
   1283 	static constexpr bool __same_err
   1284 	  = is_same_v<typename _Up::error_type, _Er>;
   1285 
   1286     public:
   1287       using value_type = _Tp;
   1288       using error_type = _Er;
   1289       using unexpected_type = unexpected<_Er>;
   1290 
   1291       template<typename _Up>
   1292 	using rebind = expected<_Up, error_type>;
   1293 
   1294       constexpr
   1295       expected() noexcept
   1296       : _M_void(), _M_has_value(true)
   1297       { }
   1298 
   1299       expected(const expected&) = default;
   1300 
   1301       constexpr
   1302       expected(const expected& __x)
   1303       noexcept(is_nothrow_copy_constructible_v<_Er>)
   1304       requires is_copy_constructible_v<_Er>
   1305 	    && (!is_trivially_copy_constructible_v<_Er>)
   1306       : _M_void(), _M_has_value(__x._M_has_value)
   1307       {
   1308 	if (!_M_has_value)
   1309 	  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
   1310       }
   1311 
   1312       expected(expected&&) = default;
   1313 
   1314       constexpr
   1315       expected(expected&& __x)
   1316       noexcept(is_nothrow_move_constructible_v<_Er>)
   1317       requires is_move_constructible_v<_Er>
   1318 	    && (!is_trivially_move_constructible_v<_Er>)
   1319       : _M_void(), _M_has_value(__x._M_has_value)
   1320       {
   1321 	if (!_M_has_value)
   1322 	  std::construct_at(__builtin_addressof(_M_unex),
   1323 			    std::move(__x)._M_unex);
   1324       }
   1325 
   1326       template<typename _Up, typename _Gr>
   1327 	requires is_void_v<_Up>
   1328 	      && is_constructible_v<_Er, const _Gr&>
   1329 	      && (!__cons_from_expected<_Up, _Gr>)
   1330 	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
   1331 	expected(const expected<_Up, _Gr>& __x)
   1332 	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
   1333 	: _M_void(), _M_has_value(__x._M_has_value)
   1334 	{
   1335 	  if (!_M_has_value)
   1336 	    std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
   1337 	}
   1338 
   1339       template<typename _Up, typename _Gr>
   1340 	requires is_void_v<_Up>
   1341 	      && is_constructible_v<_Er, _Gr>
   1342 	      && (!__cons_from_expected<_Up, _Gr>)
   1343 	constexpr explicit(!is_convertible_v<_Gr, _Er>)
   1344 	expected(expected<_Up, _Gr>&& __x)
   1345 	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
   1346 	: _M_void(), _M_has_value(__x._M_has_value)
   1347 	{
   1348 	  if (!_M_has_value)
   1349 	    std::construct_at(__builtin_addressof(_M_unex),
   1350 			      std::move(__x)._M_unex);
   1351 	}
   1352 
   1353       template<typename _Gr = _Er>
   1354 	requires is_constructible_v<_Er, const _Gr&>
   1355 	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
   1356 	expected(const unexpected<_Gr>& __u)
   1357 	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
   1358 	: _M_unex(__u.error()), _M_has_value(false)
   1359 	{ }
   1360 
   1361       template<typename _Gr = _Er>
   1362 	requires is_constructible_v<_Er, _Gr>
   1363 	constexpr explicit(!is_convertible_v<_Gr, _Er>)
   1364 	expected(unexpected<_Gr>&& __u)
   1365 	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
   1366 	: _M_unex(std::move(__u).error()), _M_has_value(false)
   1367 	{ }
   1368 
   1369       constexpr explicit
   1370       expected(in_place_t) noexcept
   1371       : expected()
   1372       { }
   1373 
   1374       template<typename... _Args>
   1375 	requires is_constructible_v<_Er, _Args...>
   1376 	constexpr explicit
   1377 	expected(unexpect_t, _Args&&... __args)
   1378 	noexcept(is_nothrow_constructible_v<_Er, _Args...>)
   1379 	: _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
   1380 	{ }
   1381 
   1382       template<typename _Up, typename... _Args>
   1383 	requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
   1384 	constexpr explicit
   1385 	expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
   1386 	noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
   1387 					    _Args...>)
   1388 	: _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
   1389 	{ }
   1390 
   1391       constexpr ~expected() = default;
   1392 
   1393       constexpr ~expected() requires (!is_trivially_destructible_v<_Er>)
   1394       {
   1395 	if (!_M_has_value)
   1396 	  std::destroy_at(__builtin_addressof(_M_unex));
   1397       }
   1398 
   1399       // assignment
   1400 
   1401       expected& operator=(const expected&) = delete;
   1402 
   1403       constexpr expected&
   1404       operator=(const expected& __x)
   1405       noexcept(__and_v<is_nothrow_copy_constructible<_Er>,
   1406 		       is_nothrow_copy_assignable<_Er>>)
   1407       requires is_copy_constructible_v<_Er>
   1408 	    && is_copy_assignable_v<_Er>
   1409       {
   1410 	if (__x._M_has_value)
   1411 	  emplace();
   1412 	else
   1413 	  _M_assign_unex(__x._M_unex);
   1414 	return *this;
   1415       }
   1416 
   1417       constexpr expected&
   1418       operator=(expected&& __x)
   1419       noexcept(__and_v<is_nothrow_move_constructible<_Er>,
   1420 		       is_nothrow_move_assignable<_Er>>)
   1421       requires is_move_constructible_v<_Er>
   1422 	    && is_move_assignable_v<_Er>
   1423       {
   1424 	if (__x._M_has_value)
   1425 	  emplace();
   1426 	else
   1427 	  _M_assign_unex(std::move(__x._M_unex));
   1428 	return *this;
   1429       }
   1430 
   1431       template<typename _Gr>
   1432 	requires is_constructible_v<_Er, const _Gr&>
   1433 	      && is_assignable_v<_Er&, const _Gr&>
   1434 	constexpr expected&
   1435 	operator=(const unexpected<_Gr>& __e)
   1436 	{
   1437 	  _M_assign_unex(__e.error());
   1438 	  return *this;
   1439 	}
   1440 
   1441       template<typename _Gr>
   1442 	requires is_constructible_v<_Er, _Gr>
   1443 	      && is_assignable_v<_Er&, _Gr>
   1444 	constexpr expected&
   1445 	operator=(unexpected<_Gr>&& __e)
   1446 	{
   1447 	  _M_assign_unex(std::move(__e.error()));
   1448 	  return *this;
   1449 	}
   1450 
   1451       // modifiers
   1452 
   1453       constexpr void
   1454       emplace() noexcept
   1455       {
   1456 	if (!_M_has_value)
   1457 	  {
   1458 	    std::destroy_at(__builtin_addressof(_M_unex));
   1459 	    _M_has_value = true;
   1460 	  }
   1461       }
   1462 
   1463       // swap
   1464       constexpr void
   1465       swap(expected& __x)
   1466       noexcept(__and_v<is_nothrow_swappable<_Er&>,
   1467 		       is_nothrow_move_constructible<_Er>>)
   1468       requires is_swappable_v<_Er> && is_move_constructible_v<_Er>
   1469       {
   1470 	if (_M_has_value)
   1471 	  {
   1472 	    if (!__x._M_has_value)
   1473 	      {
   1474 		std::construct_at(__builtin_addressof(_M_unex),
   1475 				  std::move(__x._M_unex)); // might throw
   1476 		std::destroy_at(__builtin_addressof(__x._M_unex));
   1477 		_M_has_value = false;
   1478 		__x._M_has_value = true;
   1479 	      }
   1480 	  }
   1481 	else
   1482 	  {
   1483 	    if (__x._M_has_value)
   1484 	      {
   1485 		std::construct_at(__builtin_addressof(__x._M_unex),
   1486 				  std::move(_M_unex)); // might throw
   1487 		std::destroy_at(__builtin_addressof(_M_unex));
   1488 		_M_has_value = true;
   1489 		__x._M_has_value = false;
   1490 	      }
   1491 	    else
   1492 	      {
   1493 		using std::swap;
   1494 		swap(_M_unex, __x._M_unex);
   1495 	      }
   1496 	  }
   1497       }
   1498 
   1499       // observers
   1500 
   1501       [[nodiscard]]
   1502       constexpr explicit
   1503       operator bool() const noexcept { return _M_has_value; }
   1504 
   1505       [[nodiscard]]
   1506       constexpr bool has_value() const noexcept { return _M_has_value; }
   1507 
   1508       constexpr void
   1509       operator*() const noexcept { __glibcxx_assert(_M_has_value); }
   1510 
   1511       constexpr void
   1512       value() const&
   1513       {
   1514 	if (_M_has_value) [[likely]]
   1515 	  return;
   1516 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
   1517       }
   1518 
   1519       constexpr void
   1520       value() &&
   1521       {
   1522 	if (_M_has_value) [[likely]]
   1523 	  return;
   1524 	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
   1525       }
   1526 
   1527       constexpr const _Er&
   1528       error() const & noexcept
   1529       {
   1530 	__glibcxx_assert(!_M_has_value);
   1531 	return _M_unex;
   1532       }
   1533 
   1534       constexpr _Er&
   1535       error() & noexcept
   1536       {
   1537 	__glibcxx_assert(!_M_has_value);
   1538 	return _M_unex;
   1539       }
   1540 
   1541       constexpr const _Er&&
   1542       error() const && noexcept
   1543       {
   1544 	__glibcxx_assert(!_M_has_value);
   1545 	return std::move(_M_unex);
   1546       }
   1547 
   1548       constexpr _Er&&
   1549       error() && noexcept
   1550       {
   1551 	__glibcxx_assert(!_M_has_value);
   1552 	return std::move(_M_unex);
   1553       }
   1554 
   1555       template<typename _Gr = _Er>
   1556 	constexpr _Er
   1557 	error_or(_Gr&& __e) const&
   1558 	{
   1559 	  static_assert( is_copy_constructible_v<_Er> );
   1560 	  static_assert( is_convertible_v<_Gr, _Er> );
   1561 
   1562 	  if (_M_has_value)
   1563 	    return std::forward<_Gr>(__e);
   1564 	  return _M_unex;
   1565 	}
   1566 
   1567       template<typename _Gr = _Er>
   1568 	constexpr _Er
   1569 	error_or(_Gr&& __e) &&
   1570 	{
   1571 	  static_assert( is_move_constructible_v<_Er> );
   1572 	  static_assert( is_convertible_v<_Gr, _Er> );
   1573 
   1574 	  if (_M_has_value)
   1575 	    return std::forward<_Gr>(__e);
   1576 	  return std::move(_M_unex);
   1577 	}
   1578 
   1579       // monadic operations
   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, _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, _M_unex);
   1607 	}
   1608 
   1609       template<typename _Fn> requires is_constructible_v<_Er, _Er>
   1610 	constexpr auto
   1611 	and_then(_Fn&& __f) &&
   1612 	{
   1613 	  using _Up = __expected::__result0<_Fn>;
   1614 	  static_assert(__expected::__is_expected<_Up>);
   1615 	  static_assert(is_same_v<typename _Up::error_type, _Er>);
   1616 
   1617 	  if (has_value())
   1618 	    return std::__invoke(std::forward<_Fn>(__f));
   1619 	  else
   1620 	    return _Up(unexpect, std::move(_M_unex));
   1621 	}
   1622 
   1623        template<typename _Fn> requires is_constructible_v<_Er, const _Er>
   1624 	constexpr auto
   1625 	and_then(_Fn&& __f) const &&
   1626 	{
   1627 	  using _Up = __expected::__result0<_Fn>;
   1628 	  static_assert(__expected::__is_expected<_Up>);
   1629 	  static_assert(is_same_v<typename _Up::error_type, _Er>);
   1630 
   1631 	  if (has_value())
   1632 	    return std::__invoke(std::forward<_Fn>(__f));
   1633 	  else
   1634 	    return _Up(unexpect, std::move(_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), _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), _M_unex);
   1663 	}
   1664 
   1665       template<typename _Fn>
   1666 	constexpr auto
   1667 	or_else(_Fn&& __f) &&
   1668 	{
   1669 	  using _Gr = __expected::__result<_Fn, _Er&&>;
   1670 	  static_assert(__expected::__is_expected<_Gr>);
   1671 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
   1672 
   1673 	  if (has_value())
   1674 	    return _Gr();
   1675 	  else
   1676 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
   1677 	}
   1678 
   1679       template<typename _Fn>
   1680 	constexpr auto
   1681 	or_else(_Fn&& __f) const &&
   1682 	{
   1683 	  using _Gr = __expected::__result<_Fn, const _Er&&>;
   1684 	  static_assert(__expected::__is_expected<_Gr>);
   1685 	  static_assert(is_same_v<typename _Gr::value_type, _Tp>);
   1686 
   1687 	  if (has_value())
   1688 	    return _Gr();
   1689 	  else
   1690 	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
   1691 	}
   1692 
   1693       template<typename _Fn> requires is_constructible_v<_Er, _Er&>
   1694 	constexpr auto
   1695 	transform(_Fn&& __f) &
   1696 	{
   1697 	  using _Up = __expected::__result0_xform<_Fn>;
   1698 	  using _Res = expected<_Up, _Er>;
   1699 
   1700 	  if (has_value())
   1701 	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
   1702 	  else
   1703 	    return _Res(unexpect, _M_unex);
   1704 	}
   1705 
   1706       template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
   1707 	constexpr auto
   1708 	transform(_Fn&& __f) const &
   1709 	{
   1710 	  using _Up = __expected::__result0_xform<_Fn>;
   1711 	  using _Res = expected<_Up, _Er>;
   1712 
   1713 	  if (has_value())
   1714 	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
   1715 	  else
   1716 	    return _Res(unexpect, _M_unex);
   1717 	}
   1718 
   1719       template<typename _Fn> requires is_constructible_v<_Er, _Er>
   1720 	constexpr auto
   1721 	transform(_Fn&& __f) &&
   1722 	{
   1723 	  using _Up = __expected::__result0_xform<_Fn>;
   1724 	  using _Res = expected<_Up, _Er>;
   1725 
   1726 	  if (has_value())
   1727 	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
   1728 	  else
   1729 	    return _Res(unexpect, std::move(_M_unex));
   1730 	}
   1731 
   1732       template<typename _Fn> requires is_constructible_v<_Er, const _Er>
   1733 	constexpr auto
   1734 	transform(_Fn&& __f) const &&
   1735 	{
   1736 	  using _Up = __expected::__result0_xform<_Fn>;
   1737 	  using _Res = expected<_Up, _Er>;
   1738 
   1739 	  if (has_value())
   1740 	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
   1741 	  else
   1742 	    return _Res(unexpect, std::move(_M_unex));
   1743 	}
   1744 
   1745       template<typename _Fn>
   1746 	constexpr auto
   1747 	transform_error(_Fn&& __f) &
   1748 	{
   1749 	  using _Gr = __expected::__result_xform<_Fn, _Er&>;
   1750 	  using _Res = expected<_Tp, _Gr>;
   1751 
   1752 	  if (has_value())
   1753 	    return _Res();
   1754 	  else
   1755 	    return _Res(__unexpect_inv{}, [&]() {
   1756 			  return std::__invoke(std::forward<_Fn>(__f),
   1757 					       _M_unex);
   1758 			});
   1759 	}
   1760 
   1761       template<typename _Fn>
   1762 	constexpr auto
   1763 	transform_error(_Fn&& __f) const &
   1764 	{
   1765 	  using _Gr = __expected::__result_xform<_Fn, const _Er&>;
   1766 	  using _Res = expected<_Tp, _Gr>;
   1767 
   1768 	  if (has_value())
   1769 	    return _Res();
   1770 	  else
   1771 	    return _Res(__unexpect_inv{}, [&]() {
   1772 			  return std::__invoke(std::forward<_Fn>(__f),
   1773 					       _M_unex);
   1774 			});
   1775 	}
   1776 
   1777       template<typename _Fn>
   1778 	constexpr auto
   1779 	transform_error(_Fn&& __f) &&
   1780 	{
   1781 	  using _Gr = __expected::__result_xform<_Fn, _Er&&>;
   1782 	  using _Res = expected<_Tp, _Gr>;
   1783 
   1784 	  if (has_value())
   1785 	    return _Res();
   1786 	  else
   1787 	    return _Res(__unexpect_inv{}, [&]() {
   1788 			  return std::__invoke(std::forward<_Fn>(__f),
   1789 					       std::move(_M_unex));
   1790 			});
   1791 	}
   1792 
   1793       template<typename _Fn>
   1794 	constexpr auto
   1795 	transform_error(_Fn&& __f) const &&
   1796 	{
   1797 	  using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
   1798 	  using _Res = expected<_Tp, _Gr>;
   1799 
   1800 	  if (has_value())
   1801 	    return _Res();
   1802 	  else
   1803 	    return _Res(__unexpect_inv{}, [&]() {
   1804 			  return std::__invoke(std::forward<_Fn>(__f),
   1805 					       std::move(_M_unex));
   1806 			});
   1807 	}
   1808 
   1809       // equality operators
   1810 
   1811       template<typename _Up, typename _Er2>
   1812 	requires is_void_v<_Up>
   1813 	friend constexpr bool
   1814 	operator==(const expected& __x, const expected<_Up, _Er2>& __y)
   1815 	// FIXME: noexcept(noexcept(bool(__x.error() == __y.error())))
   1816 	{
   1817 	  if (__x.has_value())
   1818 	    return __y.has_value();
   1819 	  else
   1820 	    return !__y.has_value() && bool(__x.error() == __y.error());
   1821 	}
   1822 
   1823       template<typename _Er2>
   1824 	friend constexpr bool
   1825 	operator==(const expected& __x, const unexpected<_Er2>& __e)
   1826 	// FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
   1827 	{ return !__x.has_value() && bool(__x.error() == __e.error()); }
   1828 
   1829       friend constexpr void
   1830       swap(expected& __x, expected& __y)
   1831       noexcept(noexcept(__x.swap(__y)))
   1832       requires requires { __x.swap(__y); }
   1833       { __x.swap(__y); }
   1834 
   1835     private:
   1836       template<typename, typename> friend class expected;
   1837 
   1838       template<typename _Vp>
   1839 	constexpr void
   1840 	_M_assign_unex(_Vp&& __v)
   1841 	{
   1842 	  if (_M_has_value)
   1843 	    {
   1844 	      std::construct_at(__builtin_addressof(_M_unex),
   1845 				std::forward<_Vp>(__v));
   1846 	      _M_has_value = false;
   1847 	    }
   1848 	  else
   1849 	    _M_unex = std::forward<_Vp>(__v);
   1850 	}
   1851 
   1852       using __in_place_inv = __expected::__in_place_inv;
   1853       using __unexpect_inv = __expected::__unexpect_inv;
   1854 
   1855       template<typename _Fn>
   1856 	explicit constexpr
   1857 	expected(__in_place_inv, _Fn&& __fn)
   1858 	: _M_void(), _M_has_value(true)
   1859 	{ std::forward<_Fn>(__fn)(); }
   1860 
   1861       template<typename _Fn>
   1862 	explicit constexpr
   1863 	expected(__unexpect_inv, _Fn&& __fn)
   1864 	: _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
   1865 	{ }
   1866 
   1867       union {
   1868 	struct { } _M_void;
   1869 	_Er _M_unex;
   1870       };
   1871 
   1872       bool _M_has_value;
   1873     };
   1874   /// @}
   1875 
   1876 _GLIBCXX_END_NAMESPACE_VERSION
   1877 } // namespace std
   1878 
   1879 #endif // __cpp_lib_expected
   1880 #endif // _GLIBCXX_EXPECTED
   1881