// <expected> -*- C++ -*-

// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file include/expected
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_EXPECTED
#define _GLIBCXX_EXPECTED

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#define __glibcxx_want_expected
#define __glibcxx_want_freestanding_expected
#define __glibcxx_want_constrained_equality
#define __glibcxx_want_constexpr_exceptions
#include <bits/version.h>

#ifdef __cpp_lib_expected // C++ >= 23 && __cpp_concepts >= 202002L
#include <initializer_list>
#include <bits/exception.h>	// exception
#include <bits/invoke.h>	// __invoke
#include <bits/stl_construct.h>	// construct_at
#include <bits/utility.h>	// in_place_t

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   * @defgroup expected_values Expected values
   * @addtogroup utilities
   * @since C++23
   * @{
   */

  /// Discriminated union that holds an expected value or an error value.
  /**
   * @since C++23
   */
  template<typename _Tp, typename _Er>
    class expected;

  /// Wrapper type used to pass an error value to a `std::expected`.
  /**
   * @since C++23
   */
  template<typename _Er>
    class unexpected;

  /// Exception thrown by std::expected when the value() is not present.
  /**
   * @since C++23
   */
  template<typename _Er>
    class bad_expected_access;

#if __cpp_lib_constexpr_exceptions >= 202502L
#define _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS constexpr
#else
#define _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
#endif

  template<>
    class bad_expected_access<void> : public exception
    {
    protected:
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS bad_expected_access() noexcept { }
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
      bad_expected_access(const bad_expected_access&) noexcept = default;
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
      bad_expected_access(bad_expected_access&&) noexcept = default;
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
      bad_expected_access& operator=(const bad_expected_access&) noexcept = default;
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
      bad_expected_access& operator=(bad_expected_access&&) noexcept = default;
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS
      ~bad_expected_access() = default;

    public:

      [[nodiscard]]
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS const char*
      what() const noexcept override
      { return "bad access to std::expected without expected value"; }
    };

  template<typename _Er>
    class bad_expected_access : public bad_expected_access<void> {
    public:
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS explicit
      bad_expected_access(_Er __e) : _M_unex(std::move(__e)) { }

      // XXX const char* what() const noexcept override;

      [[nodiscard]]
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS _Er&
      error() & noexcept
      { return _M_unex; }

      [[nodiscard]]
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS const _Er&
      error() const & noexcept
      { return _M_unex; }

      [[nodiscard]]
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS _Er&&
      error() && noexcept
      { return std::move(_M_unex); }

      [[nodiscard]]
      _GLIBCXX_CONSTEXPR_BAD_EXPECTED_ACCESS const _Er&&
      error() const && noexcept
      { return std::move(_M_unex); }

    private:
      _Er _M_unex;
    };

  /// Tag type for constructing unexpected values in a std::expected
  /**
   * @since C++23
   */
  struct unexpect_t
  {
    explicit unexpect_t() = default;
  };

  /// Tag for constructing unexpected values in a std::expected
  /**
   * @since C++23
   */
  inline constexpr unexpect_t unexpect{};

/// @cond undocumented
namespace __expected
{
  template<typename _Tp>
    constexpr bool __is_expected = false;
  template<typename _Tp, typename _Er>
    constexpr bool __is_expected<expected<_Tp, _Er>> = true;

  template<typename _Tp>
    constexpr bool __is_unexpected = false;
  template<typename _Tp>
    constexpr bool __is_unexpected<unexpected<_Tp>> = true;

  template<typename _Fn, typename _Tp>
    using __result = remove_cvref_t<invoke_result_t<_Fn&&, _Tp&&>>;
  template<typename _Fn, typename _Tp>
    using __result_xform = remove_cv_t<invoke_result_t<_Fn&&, _Tp&&>>;
  template<typename _Fn>
    using __result0 = remove_cvref_t<invoke_result_t<_Fn&&>>;
  template<typename _Fn>
    using __result0_xform = remove_cv_t<invoke_result_t<_Fn&&>>;

  template<typename _Er>
    concept __can_be_unexpected
      = is_object_v<_Er> && (!is_array_v<_Er>)
	  && (!__expected::__is_unexpected<_Er>)
	  && (!is_const_v<_Er>) && (!is_volatile_v<_Er>);

  // Tag types for in-place construction from an invocation result.
  struct __in_place_inv { };
  struct __unexpect_inv { };
}
/// @endcond

  template<typename _Er>
    class unexpected
    {
      static_assert( __expected::__can_be_unexpected<_Er> );

    public:
      constexpr unexpected(const unexpected&) = default;
      constexpr unexpected(unexpected&&) = default;

      template<typename _Err = _Er>
	requires (!is_same_v<remove_cvref_t<_Err>, unexpected>)
	  && (!is_same_v<remove_cvref_t<_Err>, in_place_t>)
	  && is_constructible_v<_Er, _Err>
	constexpr explicit
	unexpected(_Err&& __e)
	noexcept(is_nothrow_constructible_v<_Er, _Err>)
	: _M_unex(std::forward<_Err>(__e))
	{ }

      template<typename... _Args>
	requires is_constructible_v<_Er, _Args...>
	constexpr explicit
	unexpected(in_place_t, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Er, _Args...>)
	: _M_unex(std::forward<_Args>(__args)...)
	{ }

      template<typename _Up, typename... _Args>
	requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
	constexpr explicit
	unexpected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
					    _Args...>)
	: _M_unex(__il, std::forward<_Args>(__args)...)
	{ }

      constexpr unexpected& operator=(const unexpected&) = default;
      constexpr unexpected& operator=(unexpected&&) = default;


      [[nodiscard]]
      constexpr const _Er&
      error() const & noexcept { return _M_unex; }

      [[nodiscard]]
      constexpr _Er&
      error() & noexcept { return _M_unex; }

      [[nodiscard]]
      constexpr const _Er&&
      error() const && noexcept { return std::move(_M_unex); }

      [[nodiscard]]
      constexpr _Er&&
      error() && noexcept { return std::move(_M_unex); }

      constexpr void
      swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Er>)
      requires is_swappable_v<_Er>
      {
	using std::swap;
	swap(_M_unex, __other._M_unex);
      }

      template<typename _Err>
	[[nodiscard]]
	friend constexpr bool
	operator==(const unexpected& __x, const unexpected<_Err>& __y)
	{ return __x._M_unex == __y.error(); }

      friend constexpr void
      swap(unexpected& __x, unexpected& __y) noexcept(noexcept(__x.swap(__y)))
      requires is_swappable_v<_Er>
      { __x.swap(__y); }

    private:
      _Er _M_unex;
    };

  template<typename _Er> unexpected(_Er) -> unexpected<_Er>;

/// @cond undocumented
namespace __expected
{
  template<typename _Tp>
    struct _Guard
    {
      static_assert( is_nothrow_move_constructible_v<_Tp> );

      constexpr explicit
      _Guard(_Tp& __x)
      : _M_guarded(__builtin_addressof(__x)), _M_tmp(std::move(__x)) // nothrow
      { std::destroy_at(_M_guarded); }

      constexpr
      ~_Guard()
      {
	if (_M_guarded) [[unlikely]]
	  std::construct_at(_M_guarded, std::move(_M_tmp));
      }

      _Guard(const _Guard&) = delete;
      _Guard& operator=(const _Guard&) = delete;

      constexpr _Tp&&
      release() noexcept
      {
	_M_guarded = nullptr;
	return std::move(_M_tmp);
      }

    private:
      _Tp* _M_guarded;
      _Tp _M_tmp;
    };

  // reinit-expected helper from [expected.object.assign]
  template<typename _Tp, typename _Up, typename _Vp>
    constexpr void
    __reinit(_Tp* __newval, _Up* __oldval, _Vp&& __arg)
    noexcept(is_nothrow_constructible_v<_Tp, _Vp>)
    {
      if constexpr (is_nothrow_constructible_v<_Tp, _Vp>)
	{
	  std::destroy_at(__oldval);
	  std::construct_at(__newval, std::forward<_Vp>(__arg));
	}
      else if constexpr (is_nothrow_move_constructible_v<_Tp>)
	{
	  _Tp __tmp(std::forward<_Vp>(__arg)); // might throw
	  std::destroy_at(__oldval);
	  std::construct_at(__newval, std::move(__tmp));
	}
      else
	{
	  _Guard<_Up> __guard(*__oldval);
	  std::construct_at(__newval, std::forward<_Vp>(__arg)); // might throw
	  __guard.release();
	}
    }

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 3836. std::expected<bool, E1> conversion constructor
  // expected(const expected<U, G>&) should take precedence over
  // expected(U&&) with operator bool

  // If T is cv bool, remove_cvref_t<U> is not a specialization of expected.
  template<typename _Tp, typename _Up>
    concept __not_constructing_bool_from_expected
      = ! is_same_v<remove_cv_t<_Tp>, bool>
	  || ! __is_expected<remove_cvref_t<_Up>>;
}
/// @endcond

  template<typename _Tp, typename _Er>
    class expected
    {
      static_assert( ! is_reference_v<_Tp> );
      static_assert( ! is_function_v<_Tp> );
      static_assert( ! is_same_v<remove_cv_t<_Tp>, in_place_t> );
      static_assert( ! is_same_v<remove_cv_t<_Tp>, unexpect_t> );
      static_assert( ! __expected::__is_unexpected<remove_cv_t<_Tp>> );
      static_assert( __expected::__can_be_unexpected<_Er> );

      // If T is not cv bool, converts-from-any-cvref<T, expected<U, G>> and
      // is_constructible<unexpected<E>, cv expected<U, G> ref-qual> are false.
      template<typename _Up, typename _Gr, typename _Unex = unexpected<_Er>,
	       typename = remove_cv_t<_Tp>>
	static constexpr bool __cons_from_expected
	  = __or_v<is_constructible<_Tp, expected<_Up, _Gr>&>,
		   is_constructible<_Tp, expected<_Up, _Gr>>,
		   is_constructible<_Tp, const expected<_Up, _Gr>&>,
		   is_constructible<_Tp, const expected<_Up, _Gr>>,
		   is_convertible<expected<_Up, _Gr>&, _Tp>,
		   is_convertible<expected<_Up, _Gr>, _Tp>,
		   is_convertible<const expected<_Up, _Gr>&, _Tp>,
		   is_convertible<const expected<_Up, _Gr>, _Tp>,
		   is_constructible<_Unex, expected<_Up, _Gr>&>,
		   is_constructible<_Unex, expected<_Up, _Gr>>,
		   is_constructible<_Unex, const expected<_Up, _Gr>&>,
		   is_constructible<_Unex, const expected<_Up, _Gr>>
		  >;

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // If t is cv bool, we know it can be constructed from expected<U, G>,
      // but we don't want to cause the expected(U&&) constructor to be used,
      // so we only check the is_constructible<unexpected<E>, ...> cases.
      template<typename _Up, typename _Gr, typename _Unex>
	static constexpr bool __cons_from_expected<_Up, _Gr, _Unex, bool>
	  = __or_v<is_constructible<_Unex, expected<_Up, _Gr>&>,
		   is_constructible<_Unex, expected<_Up, _Gr>>,
		   is_constructible<_Unex, const expected<_Up, _Gr>&>,
		   is_constructible<_Unex, const expected<_Up, _Gr>>
		  >;

      template<typename _Up, typename _Gr>
	constexpr static bool __explicit_conv
	  = __or_v<__not_<is_convertible<_Up, _Tp>>,
		   __not_<is_convertible<_Gr, _Er>>
		  >;

      template<typename _Up>
	static constexpr bool __same_val
	  = is_same_v<typename _Up::value_type, _Tp>;

      template<typename _Up>
	static constexpr bool __same_err
	  = is_same_v<typename _Up::error_type, _Er>;

    public:
      using value_type = _Tp;
      using error_type = _Er;
      using unexpected_type = unexpected<_Er>;

      template<typename _Up>
	using rebind = expected<_Up, error_type>;

      constexpr
      expected()
      noexcept(is_nothrow_default_constructible_v<_Tp>)
      requires is_default_constructible_v<_Tp>
      : _M_val(), _M_has_value(true)
      { }

      expected(const expected&) = default;

      constexpr
      expected(const expected& __x)
      noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
		       is_nothrow_copy_constructible<_Er>>)
      requires is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Er>
      && (!is_trivially_copy_constructible_v<_Tp>
	  || !is_trivially_copy_constructible_v<_Er>)
      : _M_has_value(__x._M_has_value)
      {
	if (_M_has_value)
	  std::construct_at(__builtin_addressof(_M_val), __x._M_val);
	else
	  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
      }

      expected(expected&&) = default;

      constexpr
      expected(expected&& __x)
      noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
		       is_nothrow_move_constructible<_Er>>)
      requires is_move_constructible_v<_Tp> && is_move_constructible_v<_Er>
      && (!is_trivially_move_constructible_v<_Tp>
	  || !is_trivially_move_constructible_v<_Er>)
      : _M_has_value(__x._M_has_value)
      {
	if (_M_has_value)
	  std::construct_at(__builtin_addressof(_M_val),
			    std::move(__x)._M_val);
	else
	  std::construct_at(__builtin_addressof(_M_unex),
			    std::move(__x)._M_unex);
      }

      template<typename _Up, typename _Gr>
	requires is_constructible_v<_Tp, const _Up&>
	      && is_constructible_v<_Er, const _Gr&>
	      && (!__cons_from_expected<_Up, _Gr>)
	constexpr explicit(__explicit_conv<const _Up&, const _Gr&>)
	expected(const expected<_Up, _Gr>& __x)
	noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
			 is_nothrow_constructible<_Er, const _Gr&>>)
	: _M_has_value(__x._M_has_value)
	{
	  if (_M_has_value)
	    std::construct_at(__builtin_addressof(_M_val), __x._M_val);
	  else
	    std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
	}

      template<typename _Up, typename _Gr>
	requires is_constructible_v<_Tp, _Up>
	      && is_constructible_v<_Er, _Gr>
	      && (!__cons_from_expected<_Up, _Gr>)
	constexpr explicit(__explicit_conv<_Up, _Gr>)
	expected(expected<_Up, _Gr>&& __x)
	noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
			 is_nothrow_constructible<_Er, _Gr>>)
	: _M_has_value(__x._M_has_value)
	{
	  if (_M_has_value)
	    std::construct_at(__builtin_addressof(_M_val),
			      std::move(__x)._M_val);
	  else
	    std::construct_at(__builtin_addressof(_M_unex),
			      std::move(__x)._M_unex);
	}

      template<typename _Up = remove_cv_t<_Tp>>
	requires (!is_same_v<remove_cvref_t<_Up>, expected>)
	  && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
	  && (!is_same_v<remove_cvref_t<_Up>, unexpect_t>)
	  && is_constructible_v<_Tp, _Up>
	  && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
	  && __expected::__not_constructing_bool_from_expected<_Tp, _Up>
	constexpr explicit(!is_convertible_v<_Up, _Tp>)
	expected(_Up&& __v)
	noexcept(is_nothrow_constructible_v<_Tp, _Up>)
	: _M_val(std::forward<_Up>(__v)), _M_has_value(true)
	{ }

      template<typename _Gr = _Er>
	requires is_constructible_v<_Er, const _Gr&>
	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
	expected(const unexpected<_Gr>& __u)
	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
	: _M_unex(__u.error()), _M_has_value(false)
	{ }

      template<typename _Gr = _Er>
	requires is_constructible_v<_Er, _Gr>
	constexpr explicit(!is_convertible_v<_Gr, _Er>)
	expected(unexpected<_Gr>&& __u)
	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
	: _M_unex(std::move(__u).error()), _M_has_value(false)
	{ }

      template<typename... _Args>
	requires is_constructible_v<_Tp, _Args...>
	constexpr explicit
	expected(in_place_t, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
	: _M_val(std::forward<_Args>(__args)...), _M_has_value(true)
	{ }

      template<typename _Up, typename... _Args>
	requires is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
	constexpr explicit
	expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
					    _Args...>)
	: _M_val(__il, std::forward<_Args>(__args)...), _M_has_value(true)
	{ }

      template<typename... _Args>
	requires is_constructible_v<_Er, _Args...>
	constexpr explicit
	expected(unexpect_t, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Er, _Args...>)
	: _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
	{ }

      template<typename _Up, typename... _Args>
	requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
	constexpr explicit
	expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
					    _Args...>)
	: _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
	{ }

      constexpr ~expected() = default;

      constexpr ~expected()
      requires (!is_trivially_destructible_v<_Tp>)
	    || (!is_trivially_destructible_v<_Er>)
      {
	if (_M_has_value)
	  std::destroy_at(__builtin_addressof(_M_val));
	else
	  std::destroy_at(__builtin_addressof(_M_unex));
      }

      // assignment

      expected& operator=(const expected&) = delete;

      constexpr expected&
      operator=(const expected& __x)
      noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
		       is_nothrow_copy_constructible<_Er>,
		       is_nothrow_copy_assignable<_Tp>,
		       is_nothrow_copy_assignable<_Er>>)
      requires is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp>
	    && is_copy_assignable_v<_Er> && is_copy_constructible_v<_Er>
	    && (is_nothrow_move_constructible_v<_Tp>
		|| is_nothrow_move_constructible_v<_Er>)
      {
	if (__x._M_has_value)
	  this->_M_assign_val(__x._M_val);
	else
	  this->_M_assign_unex(__x._M_unex);
	return *this;
      }

      constexpr expected&
      operator=(expected&& __x)
      noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
		       is_nothrow_move_constructible<_Er>,
		       is_nothrow_move_assignable<_Tp>,
		       is_nothrow_move_assignable<_Er>>)
      requires is_move_assignable_v<_Tp> && is_move_constructible_v<_Tp>
	    && is_move_assignable_v<_Er> && is_move_constructible_v<_Er>
	    && (is_nothrow_move_constructible_v<_Tp>
		|| is_nothrow_move_constructible_v<_Er>)
      {
	if (__x._M_has_value)
	  _M_assign_val(std::move(__x._M_val));
	else
	  _M_assign_unex(std::move(__x._M_unex));
	return *this;
      }

      template<typename _Up = remove_cv_t<_Tp>>
	requires (!is_same_v<expected, remove_cvref_t<_Up>>)
	      && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
	      && is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up>
	      && (is_nothrow_constructible_v<_Tp, _Up>
		  || is_nothrow_move_constructible_v<_Tp>
		  || is_nothrow_move_constructible_v<_Er>)
	constexpr expected&
	operator=(_Up&& __v)
	{
	  _M_assign_val(std::forward<_Up>(__v));
	  return *this;
	}

      template<typename _Gr>
	requires is_constructible_v<_Er, const _Gr&>
	      && is_assignable_v<_Er&, const _Gr&>
	      && (is_nothrow_constructible_v<_Er, const _Gr&>
		  || is_nothrow_move_constructible_v<_Tp>
		  || is_nothrow_move_constructible_v<_Er>)
	constexpr expected&
	operator=(const unexpected<_Gr>& __e)
	{
	  _M_assign_unex(__e.error());
	  return *this;
	}

      template<typename _Gr>
	requires is_constructible_v<_Er, _Gr>
	      && is_assignable_v<_Er&, _Gr>
	      && (is_nothrow_constructible_v<_Er, _Gr>
		  || is_nothrow_move_constructible_v<_Tp>
		  || is_nothrow_move_constructible_v<_Er>)
	constexpr expected&
	operator=(unexpected<_Gr>&& __e)
	{
	  _M_assign_unex(std::move(__e).error());
	  return *this;
	}

      // modifiers

      template<typename... _Args>
	requires is_nothrow_constructible_v<_Tp, _Args...>
	constexpr _Tp&
	emplace(_Args&&... __args) noexcept
	{
	  if (_M_has_value)
	    std::destroy_at(__builtin_addressof(_M_val));
	  else
	    {
	      std::destroy_at(__builtin_addressof(_M_unex));
	      _M_has_value = true;
	    }
	  std::construct_at(__builtin_addressof(_M_val),
			    std::forward<_Args>(__args)...);
	  return _M_val;
	}

      template<typename _Up, typename... _Args>
	requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
					    _Args...>
	constexpr _Tp&
	emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept
	{
	  if (_M_has_value)
	    std::destroy_at(__builtin_addressof(_M_val));
	  else
	    {
	      std::destroy_at(__builtin_addressof(_M_unex));
	      _M_has_value = true;
	    }
	  std::construct_at(__builtin_addressof(_M_val),
			    __il, std::forward<_Args>(__args)...);
	  return _M_val;
	}

      // swap
      constexpr void
      swap(expected& __x)
      noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
		       is_nothrow_move_constructible<_Er>,
		       is_nothrow_swappable<_Tp&>,
		       is_nothrow_swappable<_Er&>>)
      requires is_swappable_v<_Tp> && is_swappable_v<_Er>
	    && is_move_constructible_v<_Tp>
	    && is_move_constructible_v<_Er>
	    && (is_nothrow_move_constructible_v<_Tp>
		|| is_nothrow_move_constructible_v<_Er>)
      {
	if (_M_has_value)
	  {
	    if (__x._M_has_value)
	      {
		using std::swap;
		swap(_M_val, __x._M_val);
	      }
	    else
	      this->_M_swap_val_unex(__x);
	  }
	else
	  {
	    if (__x._M_has_value)
	      __x._M_swap_val_unex(*this);
	    else
	      {
		using std::swap;
		swap(_M_unex, __x._M_unex);
	      }
	  }
      }

      // observers

      [[nodiscard]]
      constexpr const _Tp*
      operator->() const noexcept
      {
	__glibcxx_assert(_M_has_value);
	return __builtin_addressof(_M_val);
      }

      [[nodiscard]]
      constexpr _Tp*
      operator->() noexcept
      {
	__glibcxx_assert(_M_has_value);
	return __builtin_addressof(_M_val);
      }

      [[nodiscard]]
      constexpr const _Tp&
      operator*() const & noexcept
      {
	__glibcxx_assert(_M_has_value);
	return _M_val;
      }

      [[nodiscard]]
      constexpr _Tp&
      operator*() & noexcept
      {
	__glibcxx_assert(_M_has_value);
	return _M_val;
      }

      [[nodiscard]]
      constexpr const _Tp&&
      operator*() const && noexcept
      {
	__glibcxx_assert(_M_has_value);
	return std::move(_M_val);
      }

      [[nodiscard]]
      constexpr _Tp&&
      operator*() && noexcept
      {
	__glibcxx_assert(_M_has_value);
	return std::move(_M_val);
      }

      [[nodiscard]]
      constexpr explicit
      operator bool() const noexcept { return _M_has_value; }

      [[nodiscard]]
      constexpr bool has_value() const noexcept { return _M_has_value; }

      constexpr const _Tp&
      value() const &
      {
	static_assert( is_copy_constructible_v<_Er> );
	if (_M_has_value) [[likely]]
	  return _M_val;
	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
      }

      constexpr _Tp&
      value() &
      {
	static_assert( is_copy_constructible_v<_Er> );
	if (_M_has_value) [[likely]]
	  return _M_val;
	const auto& __unex = _M_unex;
	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(__unex));
      }

      constexpr const _Tp&&
      value() const &&
      {
	static_assert( is_copy_constructible_v<_Er> );
	static_assert( is_constructible_v<_Er, const _Er&&> );
	if (_M_has_value) [[likely]]
	  return std::move(_M_val);
	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
      }

      constexpr _Tp&&
      value() &&
      {
	static_assert( is_copy_constructible_v<_Er> );
	static_assert( is_constructible_v<_Er, _Er&&> );
	if (_M_has_value) [[likely]]
	  return std::move(_M_val);
	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
      }

      constexpr const _Er&
      error() const & noexcept
      {
	__glibcxx_assert(!_M_has_value);
	return _M_unex;
      }

      constexpr _Er&
      error() & noexcept
      {
	__glibcxx_assert(!_M_has_value);
	return _M_unex;
      }

      constexpr const _Er&&
      error() const && noexcept
      {
	__glibcxx_assert(!_M_has_value);
	return std::move(_M_unex);
      }

      constexpr _Er&&
      error() && noexcept
      {
	__glibcxx_assert(!_M_has_value);
	return std::move(_M_unex);
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 4406. value_or return statement is inconsistent with Mandates
      template<typename _Up = remove_cv_t<_Tp>>
	constexpr remove_cv_t<_Tp>
	value_or(_Up&& __v) const &
	noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
			 is_nothrow_convertible<_Up, _Tp>>)
	{
	  using _Xp = remove_cv_t<_Tp>;
	  static_assert( is_convertible_v<const _Tp&, _Xp> );
	  static_assert( is_convertible_v<_Up, _Tp> );

	  if (_M_has_value)
	    return _M_val;
	  return std::forward<_Up>(__v);
	}

      template<typename _Up = remove_cv_t<_Tp>>
	constexpr remove_cv_t<_Tp>
	value_or(_Up&& __v) &&
	noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
			 is_nothrow_convertible<_Up, _Tp>>)
	{
	  using _Xp = remove_cv_t<_Tp>;
	  static_assert( is_convertible_v<_Tp, _Xp> );
	  static_assert( is_convertible_v<_Up, _Xp> );

	  if (_M_has_value)
	    return std::move(_M_val);
	  return std::forward<_Up>(__v);
	}

      template<typename _Gr = _Er>
	constexpr _Er
	error_or(_Gr&& __e) const&
	{
	  static_assert( is_copy_constructible_v<_Er> );
	  static_assert( is_convertible_v<_Gr, _Er> );

	  if (_M_has_value)
	    return std::forward<_Gr>(__e);
	  return _M_unex;
	}

      template<typename _Gr = _Er>
	constexpr _Er
	error_or(_Gr&& __e) &&
	{
	  static_assert( is_move_constructible_v<_Er> );
	  static_assert( is_convertible_v<_Gr, _Er> );

	  if (_M_has_value)
	    return std::forward<_Gr>(__e);
	  return std::move(_M_unex);
	}

      // monadic operations

      template<typename _Fn> requires is_constructible_v<_Er, _Er&>
	constexpr auto
	and_then(_Fn&& __f) &
	{
	  using _Up = __expected::__result<_Fn, _Tp&>;
	  static_assert(__expected::__is_expected<_Up>,
			"the function passed to std::expected<T, E>::and_then "
			"must return a std::expected");
	  static_assert(is_same_v<typename _Up::error_type, _Er>,
			"the function passed to std::expected<T, E>::and_then "
			"must return a std::expected with the same error_type");

	  if (has_value())
	    return std::__invoke(std::forward<_Fn>(__f), _M_val);
	  else
	    return _Up(unexpect, _M_unex);
	}

      template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
	constexpr auto
	and_then(_Fn&& __f) const &
	{
	  using _Up = __expected::__result<_Fn, const _Tp&>;
	  static_assert(__expected::__is_expected<_Up>,
			"the function passed to std::expected<T, E>::and_then "
			"must return a std::expected");
	  static_assert(is_same_v<typename _Up::error_type, _Er>,
			"the function passed to std::expected<T, E>::and_then "
			"must return a std::expected with the same error_type");

	  if (has_value())
	    return std::__invoke(std::forward<_Fn>(__f), _M_val);
	  else
	    return _Up(unexpect, _M_unex);
	}

      template<typename _Fn> requires is_constructible_v<_Er, _Er>
	constexpr auto
	and_then(_Fn&& __f) &&
	{
	  using _Up = __expected::__result<_Fn, _Tp&&>;
	  static_assert(__expected::__is_expected<_Up>,
			"the function passed to std::expected<T, E>::and_then "
			"must return a std::expected");
	  static_assert(is_same_v<typename _Up::error_type, _Er>,
			"the function passed to std::expected<T, E>::and_then "
			"must return a std::expected with the same error_type");

	  if (has_value())
	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
	  else
	    return _Up(unexpect, std::move(_M_unex));
	}


      template<typename _Fn> requires is_constructible_v<_Er, const _Er>
	constexpr auto
	and_then(_Fn&& __f) const &&
	{
	  using _Up = __expected::__result<_Fn, const _Tp&&>;
	  static_assert(__expected::__is_expected<_Up>,
			"the function passed to std::expected<T, E>::and_then "
			"must return a std::expected");
	  static_assert(is_same_v<typename _Up::error_type, _Er>,
			"the function passed to std::expected<T, E>::and_then "
			"must return a std::expected with the same error_type");

	  if (has_value())
	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_val));
	  else
	    return _Up(unexpect, std::move(_M_unex));
	}

      template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
	constexpr auto
	or_else(_Fn&& __f) &
	{
	  using _Gr = __expected::__result<_Fn, _Er&>;
	  static_assert(__expected::__is_expected<_Gr>,
			"the function passed to std::expected<T, E>::or_else "
			"must return a std::expected");
	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
			"the function passed to std::expected<T, E>::or_else "
			"must return a std::expected with the same value_type");

	  if (has_value())
	    return _Gr(in_place, _M_val);
	  else
	    return std::__invoke(std::forward<_Fn>(__f), _M_unex);
	}

      template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
	constexpr auto
	or_else(_Fn&& __f) const &
	{
	  using _Gr = __expected::__result<_Fn, const _Er&>;
	  static_assert(__expected::__is_expected<_Gr>,
			"the function passed to std::expected<T, E>::or_else "
			"must return a std::expected");
	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
			"the function passed to std::expected<T, E>::or_else "
			"must return a std::expected with the same value_type");

	  if (has_value())
	    return _Gr(in_place, _M_val);
	  else
	    return std::__invoke(std::forward<_Fn>(__f), _M_unex);
	}


      template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
	constexpr auto
	or_else(_Fn&& __f) &&
	{
	  using _Gr = __expected::__result<_Fn, _Er&&>;
	  static_assert(__expected::__is_expected<_Gr>,
			"the function passed to std::expected<T, E>::or_else "
			"must return a std::expected");
	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
			"the function passed to std::expected<T, E>::or_else "
			"must return a std::expected with the same value_type");

	  if (has_value())
	    return _Gr(in_place, std::move(_M_val));
	  else
	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
	}

      template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
	constexpr auto
	or_else(_Fn&& __f) const &&
	{
	  using _Gr = __expected::__result<_Fn, const _Er&&>;
	  static_assert(__expected::__is_expected<_Gr>,
			"the function passed to std::expected<T, E>::or_else "
			"must return a std::expected");
	  static_assert(is_same_v<typename _Gr::value_type, _Tp>,
			"the function passed to std::expected<T, E>::or_else "
			"must return a std::expected with the same value_type");

	  if (has_value())
	    return _Gr(in_place, std::move(_M_val));
	  else
	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
	}

      template<typename _Fn> requires is_constructible_v<_Er, _Er&>
	constexpr auto
	transform(_Fn&& __f) &
	{
	  using _Up = __expected::__result_xform<_Fn, _Tp&>;
	  using _Res = expected<_Up, _Er>;

	  if (has_value())
	    return _Res(__in_place_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       _M_val);
			});
	  else
	    return _Res(unexpect, _M_unex);
	}

      template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
	constexpr auto
	transform(_Fn&& __f) const &
	{
	  using _Up = __expected::__result_xform<_Fn, const _Tp&>;
	  using _Res = expected<_Up, _Er>;

	  if (has_value())
	    return _Res(__in_place_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       _M_val);
			});
	  else
	    return _Res(unexpect, _M_unex);
	}

      template<typename _Fn> requires is_constructible_v<_Er, _Er>
	constexpr auto
	transform(_Fn&& __f) &&
	{
	  using _Up = __expected::__result_xform<_Fn, _Tp>;
	  using _Res = expected<_Up, _Er>;

	  if (has_value())
	    return _Res(__in_place_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       std::move(_M_val));
			});
	  else
	    return _Res(unexpect, std::move(_M_unex));
	}

      template<typename _Fn> requires is_constructible_v<_Er, const _Er>
	constexpr auto
	transform(_Fn&& __f) const &&
	{
	  using _Up = __expected::__result_xform<_Fn, const _Tp>;
	  using _Res = expected<_Up, _Er>;

	  if (has_value())
	    return _Res(__in_place_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       std::move(_M_val));
			});
	  else
	    return _Res(unexpect, std::move(_M_unex));
	}

      template<typename _Fn> requires is_constructible_v<_Tp, _Tp&>
	constexpr auto
	transform_error(_Fn&& __f) &
	{
	  using _Gr = __expected::__result_xform<_Fn, _Er&>;
	  using _Res = expected<_Tp, _Gr>;

	  if (has_value())
	    return _Res(in_place, _M_val);
	  else
	    return _Res(__unexpect_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       _M_unex);
			});
	}

      template<typename _Fn> requires is_constructible_v<_Tp, const _Tp&>
	constexpr auto
	transform_error(_Fn&& __f) const &
	{
	  using _Gr = __expected::__result_xform<_Fn, const _Er&>;
	  using _Res = expected<_Tp, _Gr>;

	  if (has_value())
	    return _Res(in_place, _M_val);
	  else
	    return _Res(__unexpect_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       _M_unex);
			});
	}

      template<typename _Fn> requires is_constructible_v<_Tp, _Tp>
	constexpr auto
	transform_error(_Fn&& __f) &&
	{
	  using _Gr = __expected::__result_xform<_Fn, _Er&&>;
	  using _Res = expected<_Tp, _Gr>;

	  if (has_value())
	    return _Res(in_place, std::move(_M_val));
	  else
	    return _Res(__unexpect_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       std::move(_M_unex));
			});
	}

      template<typename _Fn> requires is_constructible_v<_Tp, const _Tp>
	constexpr auto
	transform_error(_Fn&& __f) const &&
	{
	  using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
	  using _Res = expected<_Tp, _Gr>;

	  if (has_value())
	    return _Res(in_place, std::move(_M_val));
	  else
	    return _Res(__unexpect_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       std::move(_M_unex));
			});
	}

      // equality operators

      template<typename _Up, typename _Er2>
	requires (!is_void_v<_Up>)
	  && requires (const _Tp& __t, const _Up& __u,
		       const _Er& __e, const _Er2& __e2) {
	    { __t == __u } -> convertible_to<bool>;
	    { __e == __e2 } -> convertible_to<bool>;
	  }
	[[nodiscard]]
	friend constexpr bool
	operator==(const expected& __x, const expected<_Up, _Er2>& __y)
	noexcept(noexcept(bool(*__x == *__y))
		  && noexcept(bool(__x.error() == __y.error())))
	{
	  if (__x.has_value() != __y.has_value())
	    return false;
	  if (__x.has_value())
	    return *__x == *__y;
	  return __x.error() == __y.error();
	}

      template<typename _Up, same_as<_Tp> _Vp>
	requires (!__expected::__is_expected<_Up>)
	  && requires (const _Tp& __t, const _Up& __u) {
	    { __t == __u } -> convertible_to<bool>;
	  }
	[[nodiscard]]
	friend constexpr bool
	operator==(const expected<_Vp, _Er>& __x, const _Up& __v)
	noexcept(noexcept(bool(*__x == __v)))
	{
	  if (__x.has_value())
	    return *__x == __v;
	  return false;
	}

      template<typename _Er2>
	requires requires (const _Er& __e, const _Er2& __e2) {
	  { __e == __e2 } -> convertible_to<bool>;
	}
	[[nodiscard]]
	friend constexpr bool
	operator==(const expected& __x, const unexpected<_Er2>& __e)
	noexcept(noexcept(bool(__x.error() == __e.error())))
	{
	  if (!__x.has_value())
	    return __x.error() == __e.error();
	  return false;
	}

      friend constexpr void
      swap(expected& __x, expected& __y)
      noexcept(noexcept(__x.swap(__y)))
      requires requires {__x.swap(__y);}
      { __x.swap(__y); }

    private:
      template<typename, typename> friend class expected;

      template<typename _Vp>
	constexpr void
	_M_assign_val(_Vp&& __v)
	{
	  if (_M_has_value)
	    _M_val = std::forward<_Vp>(__v);
	  else
	    {
	      __expected::__reinit(__builtin_addressof(_M_val),
				   __builtin_addressof(_M_unex),
				   std::forward<_Vp>(__v));
	      _M_has_value = true;
	    }
	}

      template<typename _Vp>
	constexpr void
	_M_assign_unex(_Vp&& __v)
	{
	  if (_M_has_value)
	    {
	      __expected::__reinit(__builtin_addressof(_M_unex),
				   __builtin_addressof(_M_val),
				   std::forward<_Vp>(__v));
	      _M_has_value = false;
	    }
	  else
	    _M_unex = std::forward<_Vp>(__v);
	}

      // Swap two expected objects when only one has a value.
      // Precondition: this->_M_has_value && !__rhs._M_has_value
      constexpr void
      _M_swap_val_unex(expected& __rhs)
      noexcept(__and_v<is_nothrow_move_constructible<_Er>,
		       is_nothrow_move_constructible<_Tp>>)
      {
	if constexpr (is_nothrow_move_constructible_v<_Er>)
	  {
	    __expected::_Guard<_Er> __guard(__rhs._M_unex);
	    std::construct_at(__builtin_addressof(__rhs._M_val),
			      std::move(_M_val)); // might throw
	    __rhs._M_has_value = true;
	    std::destroy_at(__builtin_addressof(_M_val));
	    std::construct_at(__builtin_addressof(_M_unex),
			      __guard.release());
	    _M_has_value = false;
	  }
	else
	  {
	    __expected::_Guard<_Tp> __guard(_M_val);
	    std::construct_at(__builtin_addressof(_M_unex),
			      std::move(__rhs._M_unex)); // might throw
	    _M_has_value = false;
	    std::destroy_at(__builtin_addressof(__rhs._M_unex));
	    std::construct_at(__builtin_addressof(__rhs._M_val),
			      __guard.release());
	    __rhs._M_has_value = true;
	  }
      }

      using __in_place_inv = __expected::__in_place_inv;
      using __unexpect_inv = __expected::__unexpect_inv;

      template<typename _Fn>
	explicit constexpr
	expected(__in_place_inv, _Fn&& __fn)
	: _M_val(std::forward<_Fn>(__fn)()), _M_has_value(true)
	{ }

      template<typename _Fn>
	explicit constexpr
	expected(__unexpect_inv, _Fn&& __fn)
	: _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
	{ }

      union {
	remove_cv_t<_Tp> _M_val;
	_Er _M_unex;
      };

      bool _M_has_value;
    };

  // Partial specialization for std::expected<cv void, E>
  template<typename _Tp, typename _Er> requires is_void_v<_Tp>
    class expected<_Tp, _Er>
    {
      static_assert( __expected::__can_be_unexpected<_Er> );

      template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
	static constexpr bool __cons_from_expected
	  = __or_v<is_constructible<_Unex, expected<_Up, _Err>&>,
		   is_constructible<_Unex, expected<_Up, _Err>>,
		   is_constructible<_Unex, const expected<_Up, _Err>&>,
		   is_constructible<_Unex, const expected<_Up, _Err>>
		  >;

      template<typename _Up>
	static constexpr bool __same_val
	  = is_same_v<typename _Up::value_type, _Tp>;

      template<typename _Up>
	static constexpr bool __same_err
	  = is_same_v<typename _Up::error_type, _Er>;

    public:
      using value_type = _Tp;
      using error_type = _Er;
      using unexpected_type = unexpected<_Er>;

      template<typename _Up>
	using rebind = expected<_Up, error_type>;

      constexpr
      expected() noexcept
      : _M_void(), _M_has_value(true)
      { }

      expected(const expected&) = default;

      constexpr
      expected(const expected& __x)
      noexcept(is_nothrow_copy_constructible_v<_Er>)
      requires is_copy_constructible_v<_Er>
	    && (!is_trivially_copy_constructible_v<_Er>)
      : _M_void(), _M_has_value(__x._M_has_value)
      {
	if (!_M_has_value)
	  std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
      }

      expected(expected&&) = default;

      constexpr
      expected(expected&& __x)
      noexcept(is_nothrow_move_constructible_v<_Er>)
      requires is_move_constructible_v<_Er>
	    && (!is_trivially_move_constructible_v<_Er>)
      : _M_void(), _M_has_value(__x._M_has_value)
      {
	if (!_M_has_value)
	  std::construct_at(__builtin_addressof(_M_unex),
			    std::move(__x)._M_unex);
      }

      template<typename _Up, typename _Gr>
	requires is_void_v<_Up>
	      && is_constructible_v<_Er, const _Gr&>
	      && (!__cons_from_expected<_Up, _Gr>)
	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
	expected(const expected<_Up, _Gr>& __x)
	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
	: _M_void(), _M_has_value(__x._M_has_value)
	{
	  if (!_M_has_value)
	    std::construct_at(__builtin_addressof(_M_unex), __x._M_unex);
	}

      template<typename _Up, typename _Gr>
	requires is_void_v<_Up>
	      && is_constructible_v<_Er, _Gr>
	      && (!__cons_from_expected<_Up, _Gr>)
	constexpr explicit(!is_convertible_v<_Gr, _Er>)
	expected(expected<_Up, _Gr>&& __x)
	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
	: _M_void(), _M_has_value(__x._M_has_value)
	{
	  if (!_M_has_value)
	    std::construct_at(__builtin_addressof(_M_unex),
			      std::move(__x)._M_unex);
	}

      template<typename _Gr = _Er>
	requires is_constructible_v<_Er, const _Gr&>
	constexpr explicit(!is_convertible_v<const _Gr&, _Er>)
	expected(const unexpected<_Gr>& __u)
	noexcept(is_nothrow_constructible_v<_Er, const _Gr&>)
	: _M_unex(__u.error()), _M_has_value(false)
	{ }

      template<typename _Gr = _Er>
	requires is_constructible_v<_Er, _Gr>
	constexpr explicit(!is_convertible_v<_Gr, _Er>)
	expected(unexpected<_Gr>&& __u)
	noexcept(is_nothrow_constructible_v<_Er, _Gr>)
	: _M_unex(std::move(__u).error()), _M_has_value(false)
	{ }

      constexpr explicit
      expected(in_place_t) noexcept
      : expected()
      { }

      template<typename... _Args>
	requires is_constructible_v<_Er, _Args...>
	constexpr explicit
	expected(unexpect_t, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Er, _Args...>)
	: _M_unex(std::forward<_Args>(__args)...), _M_has_value(false)
	{ }

      template<typename _Up, typename... _Args>
	requires is_constructible_v<_Er, initializer_list<_Up>&, _Args...>
	constexpr explicit
	expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Er, initializer_list<_Up>&,
					    _Args...>)
	: _M_unex(__il, std::forward<_Args>(__args)...), _M_has_value(false)
	{ }

      constexpr ~expected() = default;

      constexpr ~expected() requires (!is_trivially_destructible_v<_Er>)
      {
	if (!_M_has_value)
	  std::destroy_at(__builtin_addressof(_M_unex));
      }

      // assignment

      expected& operator=(const expected&) = delete;

      constexpr expected&
      operator=(const expected& __x)
      noexcept(__and_v<is_nothrow_copy_constructible<_Er>,
		       is_nothrow_copy_assignable<_Er>>)
      requires is_copy_constructible_v<_Er>
	    && is_copy_assignable_v<_Er>
      {
	if (__x._M_has_value)
	  emplace();
	else
	  _M_assign_unex(__x._M_unex);
	return *this;
      }

      constexpr expected&
      operator=(expected&& __x)
      noexcept(__and_v<is_nothrow_move_constructible<_Er>,
		       is_nothrow_move_assignable<_Er>>)
      requires is_move_constructible_v<_Er>
	    && is_move_assignable_v<_Er>
      {
	if (__x._M_has_value)
	  emplace();
	else
	  _M_assign_unex(std::move(__x._M_unex));
	return *this;
      }

      template<typename _Gr>
	requires is_constructible_v<_Er, const _Gr&>
	      && is_assignable_v<_Er&, const _Gr&>
	constexpr expected&
	operator=(const unexpected<_Gr>& __e)
	{
	  _M_assign_unex(__e.error());
	  return *this;
	}

      template<typename _Gr>
	requires is_constructible_v<_Er, _Gr>
	      && is_assignable_v<_Er&, _Gr>
	constexpr expected&
	operator=(unexpected<_Gr>&& __e)
	{
	  _M_assign_unex(std::move(__e.error()));
	  return *this;
	}

      // modifiers

      constexpr void
      emplace() noexcept
      {
	if (!_M_has_value)
	  {
	    std::destroy_at(__builtin_addressof(_M_unex));
	    _M_has_value = true;
	  }
      }

      // swap
      constexpr void
      swap(expected& __x)
      noexcept(__and_v<is_nothrow_swappable<_Er&>,
		       is_nothrow_move_constructible<_Er>>)
      requires is_swappable_v<_Er> && is_move_constructible_v<_Er>
      {
	if (_M_has_value)
	  {
	    if (!__x._M_has_value)
	      {
		std::construct_at(__builtin_addressof(_M_unex),
				  std::move(__x._M_unex)); // might throw
		std::destroy_at(__builtin_addressof(__x._M_unex));
		_M_has_value = false;
		__x._M_has_value = true;
	      }
	  }
	else
	  {
	    if (__x._M_has_value)
	      {
		std::construct_at(__builtin_addressof(__x._M_unex),
				  std::move(_M_unex)); // might throw
		std::destroy_at(__builtin_addressof(_M_unex));
		_M_has_value = true;
		__x._M_has_value = false;
	      }
	    else
	      {
		using std::swap;
		swap(_M_unex, __x._M_unex);
	      }
	  }
      }

      // observers

      [[nodiscard]]
      constexpr explicit
      operator bool() const noexcept { return _M_has_value; }

      [[nodiscard]]
      constexpr bool has_value() const noexcept { return _M_has_value; }

      constexpr void
      operator*() const noexcept { __glibcxx_assert(_M_has_value); }

      constexpr void
      value() const&
      {
	static_assert( is_copy_constructible_v<_Er> );
	if (_M_has_value) [[likely]]
	  return;
	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
      }

      constexpr void
      value() &&
      {
	static_assert( is_copy_constructible_v<_Er> );
	static_assert( is_move_constructible_v<_Er> );
	if (_M_has_value) [[likely]]
	  return;
	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(std::move(_M_unex)));
      }

      constexpr const _Er&
      error() const & noexcept
      {
	__glibcxx_assert(!_M_has_value);
	return _M_unex;
      }

      constexpr _Er&
      error() & noexcept
      {
	__glibcxx_assert(!_M_has_value);
	return _M_unex;
      }

      constexpr const _Er&&
      error() const && noexcept
      {
	__glibcxx_assert(!_M_has_value);
	return std::move(_M_unex);
      }

      constexpr _Er&&
      error() && noexcept
      {
	__glibcxx_assert(!_M_has_value);
	return std::move(_M_unex);
      }

      template<typename _Gr = _Er>
	constexpr _Er
	error_or(_Gr&& __e) const&
	{
	  static_assert( is_copy_constructible_v<_Er> );
	  static_assert( is_convertible_v<_Gr, _Er> );

	  if (_M_has_value)
	    return std::forward<_Gr>(__e);
	  return _M_unex;
	}

      template<typename _Gr = _Er>
	constexpr _Er
	error_or(_Gr&& __e) &&
	{
	  static_assert( is_move_constructible_v<_Er> );
	  static_assert( is_convertible_v<_Gr, _Er> );

	  if (_M_has_value)
	    return std::forward<_Gr>(__e);
	  return std::move(_M_unex);
	}

      // monadic operations

      template<typename _Fn> requires is_constructible_v<_Er, _Er&>
	constexpr auto
	and_then(_Fn&& __f) &
	{
	  using _Up = __expected::__result0<_Fn>;
	  static_assert(__expected::__is_expected<_Up>);
	  static_assert(is_same_v<typename _Up::error_type, _Er>);

	  if (has_value())
	    return std::__invoke(std::forward<_Fn>(__f));
	  else
	    return _Up(unexpect, _M_unex);
	}

     template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
	constexpr auto
	and_then(_Fn&& __f) const &
	{
	  using _Up = __expected::__result0<_Fn>;
	  static_assert(__expected::__is_expected<_Up>);
	  static_assert(is_same_v<typename _Up::error_type, _Er>);

	  if (has_value())
	    return std::__invoke(std::forward<_Fn>(__f));
	  else
	    return _Up(unexpect, _M_unex);
	}

      template<typename _Fn> requires is_constructible_v<_Er, _Er>
	constexpr auto
	and_then(_Fn&& __f) &&
	{
	  using _Up = __expected::__result0<_Fn>;
	  static_assert(__expected::__is_expected<_Up>);
	  static_assert(is_same_v<typename _Up::error_type, _Er>);

	  if (has_value())
	    return std::__invoke(std::forward<_Fn>(__f));
	  else
	    return _Up(unexpect, std::move(_M_unex));
	}

       template<typename _Fn> requires is_constructible_v<_Er, const _Er>
	constexpr auto
	and_then(_Fn&& __f) const &&
	{
	  using _Up = __expected::__result0<_Fn>;
	  static_assert(__expected::__is_expected<_Up>);
	  static_assert(is_same_v<typename _Up::error_type, _Er>);

	  if (has_value())
	    return std::__invoke(std::forward<_Fn>(__f));
	  else
	    return _Up(unexpect, std::move(_M_unex));
	}

      template<typename _Fn>
	constexpr auto
	or_else(_Fn&& __f) &
	{
	  using _Gr = __expected::__result<_Fn, _Er&>;
	  static_assert(__expected::__is_expected<_Gr>);
	  static_assert(is_same_v<typename _Gr::value_type, _Tp>);

	  if (has_value())
	    return _Gr();
	  else
	    return std::__invoke(std::forward<_Fn>(__f), _M_unex);
	}

      template<typename _Fn>
	constexpr auto
	or_else(_Fn&& __f) const &
	{
	  using _Gr = __expected::__result<_Fn, const _Er&>;
	  static_assert(__expected::__is_expected<_Gr>);
	  static_assert(is_same_v<typename _Gr::value_type, _Tp>);

	  if (has_value())
	    return _Gr();
	  else
	    return std::__invoke(std::forward<_Fn>(__f), _M_unex);
	}

      template<typename _Fn>
	constexpr auto
	or_else(_Fn&& __f) &&
	{
	  using _Gr = __expected::__result<_Fn, _Er&&>;
	  static_assert(__expected::__is_expected<_Gr>);
	  static_assert(is_same_v<typename _Gr::value_type, _Tp>);

	  if (has_value())
	    return _Gr();
	  else
	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
	}

      template<typename _Fn>
	constexpr auto
	or_else(_Fn&& __f) const &&
	{
	  using _Gr = __expected::__result<_Fn, const _Er&&>;
	  static_assert(__expected::__is_expected<_Gr>);
	  static_assert(is_same_v<typename _Gr::value_type, _Tp>);

	  if (has_value())
	    return _Gr();
	  else
	    return std::__invoke(std::forward<_Fn>(__f), std::move(_M_unex));
	}

      template<typename _Fn> requires is_constructible_v<_Er, _Er&>
	constexpr auto
	transform(_Fn&& __f) &
	{
	  using _Up = __expected::__result0_xform<_Fn>;
	  using _Res = expected<_Up, _Er>;

	  if (has_value())
	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
	  else
	    return _Res(unexpect, _M_unex);
	}

      template<typename _Fn> requires is_constructible_v<_Er, const _Er&>
	constexpr auto
	transform(_Fn&& __f) const &
	{
	  using _Up = __expected::__result0_xform<_Fn>;
	  using _Res = expected<_Up, _Er>;

	  if (has_value())
	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
	  else
	    return _Res(unexpect, _M_unex);
	}

      template<typename _Fn> requires is_constructible_v<_Er, _Er>
	constexpr auto
	transform(_Fn&& __f) &&
	{
	  using _Up = __expected::__result0_xform<_Fn>;
	  using _Res = expected<_Up, _Er>;

	  if (has_value())
	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
	  else
	    return _Res(unexpect, std::move(_M_unex));
	}

      template<typename _Fn> requires is_constructible_v<_Er, const _Er>
	constexpr auto
	transform(_Fn&& __f) const &&
	{
	  using _Up = __expected::__result0_xform<_Fn>;
	  using _Res = expected<_Up, _Er>;

	  if (has_value())
	    return _Res(__in_place_inv{}, std::forward<_Fn>(__f));
	  else
	    return _Res(unexpect, std::move(_M_unex));
	}

      template<typename _Fn>
	constexpr auto
	transform_error(_Fn&& __f) &
	{
	  using _Gr = __expected::__result_xform<_Fn, _Er&>;
	  using _Res = expected<_Tp, _Gr>;

	  if (has_value())
	    return _Res();
	  else
	    return _Res(__unexpect_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       _M_unex);
			});
	}

      template<typename _Fn>
	constexpr auto
	transform_error(_Fn&& __f) const &
	{
	  using _Gr = __expected::__result_xform<_Fn, const _Er&>;
	  using _Res = expected<_Tp, _Gr>;

	  if (has_value())
	    return _Res();
	  else
	    return _Res(__unexpect_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       _M_unex);
			});
	}

      template<typename _Fn>
	constexpr auto
	transform_error(_Fn&& __f) &&
	{
	  using _Gr = __expected::__result_xform<_Fn, _Er&&>;
	  using _Res = expected<_Tp, _Gr>;

	  if (has_value())
	    return _Res();
	  else
	    return _Res(__unexpect_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       std::move(_M_unex));
			});
	}

      template<typename _Fn>
	constexpr auto
	transform_error(_Fn&& __f) const &&
	{
	  using _Gr = __expected::__result_xform<_Fn, const _Er&&>;
	  using _Res = expected<_Tp, _Gr>;

	  if (has_value())
	    return _Res();
	  else
	    return _Res(__unexpect_inv{}, [&]() {
			  return std::__invoke(std::forward<_Fn>(__f),
					       std::move(_M_unex));
			});
	}

      // equality operators

      template<typename _Up, typename _Er2>
	requires is_void_v<_Up>
	  && requires (const _Er& __e, const _Er2& __e2) {
	    { __e == __e2 } -> convertible_to<bool>;
	  }
	[[nodiscard]]
	friend constexpr bool
	operator==(const expected& __x, const expected<_Up, _Er2>& __y)
	noexcept(noexcept(bool(__x.error() == __y.error())))
	{
	  if (__x.has_value() != __y.has_value())
	    return false;
	  if (__x.has_value())
	    return true;
	  return __x.error() == __y.error();
	}

      template<typename _Er2>
	requires requires (const _Er& __e, const _Er2& __e2) {
	  { __e == __e2 } -> convertible_to<bool>;
	}
	[[nodiscard]]
	friend constexpr bool
	operator==(const expected& __x, const unexpected<_Er2>& __e)
	noexcept(noexcept(bool(__x.error() == __e.error())))
	{
	  if (!__x.has_value())
	    return __x.error() == __e.error();
	  return false;
	}

      friend constexpr void
      swap(expected& __x, expected& __y)
      noexcept(noexcept(__x.swap(__y)))
      requires requires { __x.swap(__y); }
      { __x.swap(__y); }

    private:
      template<typename, typename> friend class expected;

      template<typename _Vp>
	constexpr void
	_M_assign_unex(_Vp&& __v)
	{
	  if (_M_has_value)
	    {
	      std::construct_at(__builtin_addressof(_M_unex),
				std::forward<_Vp>(__v));
	      _M_has_value = false;
	    }
	  else
	    _M_unex = std::forward<_Vp>(__v);
	}

      using __in_place_inv = __expected::__in_place_inv;
      using __unexpect_inv = __expected::__unexpect_inv;

      template<typename _Fn>
	explicit constexpr
	expected(__in_place_inv, _Fn&& __fn)
	: _M_void(), _M_has_value(true)
	{ std::forward<_Fn>(__fn)(); }

      template<typename _Fn>
	explicit constexpr
	expected(__unexpect_inv, _Fn&& __fn)
	: _M_unex(std::forward<_Fn>(__fn)()), _M_has_value(false)
	{ }

      union {
	struct { } _M_void;
	_Er _M_unex;
      };

      bool _M_has_value;
    };
  /// @}

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // __cpp_lib_expected
#endif // _GLIBCXX_EXPECTED
