// <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>)
      {
	static_assert( 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 requires {__x.swap(__y);}
      { __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_invalid(), _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_invalid(), _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_invalid(), _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_invalid(), _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;
	_GLIBCXX_THROW_OR_ABORT(bad_expected_access<_Er>(_M_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)
	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)
	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)
	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(__rhs._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 {
	struct { } _M_invalid;
	_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)
	{ }

      template<typename... _Args>
	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)
	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)
	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
