// <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

#pragma GCC system_header

#if __cplusplus > 202002L && __cpp_concepts >= 202002L

#include <initializer_list>
#include <bits/exception.h>	// exception
#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
   * @{
   */

#define __cpp_lib_expected 202202L

  /// 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;

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

    public:

      [[nodiscard]]
      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:
      explicit
      bad_expected_access(_Er __e) : _M_unex(std::move(__e)) { }

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

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

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

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

      [[nodiscard]]
      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 undoc
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 _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>);
}
/// @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 undoc
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();
	}
    }
}
/// @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> );

      template<typename _Up, typename _Err, typename _Unex = unexpected<_Er>>
	static constexpr bool __cons_from_expected
	  = __or_v<is_constructible<_Tp, expected<_Up, _Err>&>,
		   is_constructible<_Tp, expected<_Up, _Err>>,
		   is_constructible<_Tp, const expected<_Up, _Err>&>,
		   is_constructible<_Tp, const expected<_Up, _Err>>,
		   is_convertible<expected<_Up, _Err>&, _Tp>,
		   is_convertible<expected<_Up, _Err>, _Tp>,
		   is_convertible<const expected<_Up, _Err>&, _Tp>,
		   is_convertible<const expected<_Up, _Err>, _Tp>,
		   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, typename _Err>
	constexpr static bool __explicit_conv
	  = __or_v<__not_<is_convertible<_Up, _Tp>>,
		   __not_<is_convertible<_Err, _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 = _Tp>
	requires (!is_same_v<remove_cvref_t<_Up>, expected>)
	  && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
	  && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
	  && is_constructible_v<_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 = _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 &
      {
	if (_M_has_value) [[likely]]
	  return _M_val;
	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
      }

      constexpr _Tp&
      value() &
      {
	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 &&
      {
	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() &&
      {
	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);
      }

      template<typename _Up>
	constexpr _Tp
	value_or(_Up&& __v) const &
	noexcept(__and_v<is_nothrow_copy_constructible<_Tp>,
			 is_nothrow_convertible<_Up, _Tp>>)
	{
	  static_assert( is_copy_constructible_v<_Tp> );
	  static_assert( is_convertible_v<_Up, _Tp> );

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

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

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

      // equality operators

      template<typename _Up, typename _Er2>
	requires (!is_void_v<_Up>)
	friend constexpr bool
	operator==(const expected& __x, const expected<_Up, _Er2>& __y)
	// FIXME: noexcept(noexcept(bool(*__x == *__y))
		  // && noexcept(bool(__x.error() == __y.error())))
	{
	  if (__x.has_value())
	    return __y.has_value() && bool(*__x == *__y);
	  else
	    return !__y.has_value() && bool(__x.error() == __y.error());
	}

      template<typename _Up>
	friend constexpr bool
	operator==(const expected& __x, const _Up& __v)
	// FIXME: noexcept(noexcept(bool(*__x == __v)))
	{ return __x.has_value() && bool(*__x == __v); }

      template<typename _Er2>
	friend constexpr bool
	operator==(const expected& __x, const unexpected<_Er2>& __e)
	// FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
	{ return !__x.has_value() && bool(__x.error() == __e.error()); }

      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;
	  }
      }

      union {
	_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>>
		  >;

    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&
      {
	if (_M_has_value) [[likely]]
	  return;
	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_unex));
      }

      constexpr void
      value() &&
      {
	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);
      }

      // equality operators

      template<typename _Up, typename _Er2>
	requires is_void_v<_Up>
	friend constexpr bool
	operator==(const expected& __x, const expected<_Up, _Er2>& __y)
	// FIXME: noexcept(noexcept(bool(__x.error() == __y.error())))
	{
	  if (__x.has_value())
	    return __y.has_value();
	  else
	    return !__y.has_value() && bool(__x.error() == __y.error());
	}

      template<typename _Er2>
	friend constexpr bool
	operator==(const expected& __x, const unexpected<_Er2>& __e)
	// FIXME: noexcept(noexcept(bool(__x.error() == __e.error())))
	{ return !__x.has_value() && bool(__x.error() == __e.error()); }

      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);
	}


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

      bool _M_has_value;
    };
  /// @}

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++23
#endif // _GLIBCXX_EXPECTED
