/* An <expected> for -*- C++ -*- 14.
   Derived, in part, from the libstdc++ one, but mostly distinct.
   Copyright (C) 2026 The GNU Toolchain Authors.

This file is part of GCC.

GCC 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.

GCC 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.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef GCC_EXPECTED
#define GCC_EXPECTED 1

#include <utility>
#include <type_traits>
#include <initializer_list>
#include <memory>

#include "gbits/assert.h"
#include "gbits/enable_special_members.h"
#include "gbits/exception_defines.h"
#include "gbits/extras.h"
#include "gbits/inplace_tags.h"
#include "gbits/invoke.h"
#include "gbits/stl_construct.h"

#ifdef GCC_BACKPORT_WANT_EXCEPTIONS
# include <exception>
#endif

#include "expectedfwd"

namespace gcc
{
  // [expected]
  template<typename E>
  struct unexpected;

  struct unexpect_t
  {
    explicit unexpect_t () = default;
  };
  static constexpr unexpect_t unexpect{};

  namespace detail { namespace exp
  {
    template<typename T>
    struct is_unexpected : std::false_type {};

    template<typename E>
    struct is_unexpected<unexpected<E>> : std::true_type {};

    template<typename T>
    struct is_expected : std::false_type {};

    template<typename T, typename E>
    struct is_expected<expected<T, E>> : std::true_type {};

    // true_type if E can be contained in an unexpected{} or !has_value
    // expected.
    template<typename E>
    using can_be_unexpected_val = and_<
      std::is_object<E>,
      not_<std::is_array<E>>,
      not_<is_unexpected<E>>,
      not_<is_cv_qualified<E>>
      >;

    // true_type if non-void T can be contained in a has_value expected.
    template<typename T>
    using can_be_expected_val_2 = and_<
      std::is_object<T>,
      not_<std::is_array<T>>,
      not_<is_in_place<T>>,
      not_<is_unexpected<T>>,
      not_<std::is_same<T, unexpect_t>>
      >;
    template<typename T>
    using can_be_expected_val = can_be_expected_val_2<std::remove_cv_t<T>>;

    // 'bool' if T1 is equality-comparable with T2, and E1 with E2, SFINAE-fail
    // otherwise.  Used for comparisons of expected types.
    template<typename T1, typename T2,
	     typename E1, typename E2>
    using eql_2_return_t = detail::relop_return_t<
      decltype (std::declval<const T1&> () == std::declval<const T2&> ()),
      decltype (std::declval<const E1&> () == std::declval<const E2&> ())
      >;

    // Implements the "U is a specialization of expected and is_same_v<typename
    // U::error_type, E> is true." mandate where U=Candidate and E=WantedError.
    template<typename Candidate, typename WantedError>
    struct is_expected_with_error : std::false_type {};

    template<typename T, typename WantedError>
    struct is_expected_with_error<expected<T, WantedError>, WantedError>
      : std::true_type {};

    // Implements the "G is a specialization of expected and
    // is_same_v<typename G::value_type, T> is true." mandate, where
    // G=Candidate and T=WantedValue.
    template<typename Candidate, typename WantedValue>
    struct is_expected_with_value : std::false_type {};

    template<typename E, typename WantedValue>
    struct is_expected_with_value<expected<WantedValue, E>, WantedValue>
      : std::true_type {};

    // Shorthand.
    template<template<typename> class Trait, typename T, typename E>
    using trait_2 = and_<Trait<T>, Trait<E>>;

    // Tag type, use supplied invocable to populate 'val'.
    struct in_place_inv {};
    // Likewise, but for 'unex'.
    struct unexpect_inv {};
  }} // namespace detail::exp

  template<typename E>
  struct unexpected
  {
    // [expected.un.general]p2
    static_assert (detail::exp::can_be_unexpected_val<E>::value,
		   "E not a valid type for unexpected<>");

    // [expected.un.cons]
    unexpected (const unexpected &) = default;
    unexpected (unexpected &&) = default;

    template<typename Err = E,
	     typename = std::enable_if_t<and_<
	       std::is_constructible<E, Err>,
	       not_<is_in_place<Err>>,
	       not_<std::is_same<remove_cvref_t<Err>, unexpected>>
	       >::value>>
    constexpr explicit
    unexpected (Err &&err)
      : unex (std::forward<Err>(err))
    {}

    template<typename... Args,
	     typename = std::enable_if_t<
	       std::is_constructible<E, Args...>::value
	       >>
    constexpr explicit
    unexpected (in_place_t, Args&&... args)
      : unex (std::forward<Args>(args)...)
    {}

    template<typename U, typename... Args,
	     typename = std::enable_if_t<
	       std::is_constructible<E, std::initializer_list<U>&, Args...>::value
	       >>
    constexpr explicit unexpected (in_place_t,
				  std::initializer_list<U> il, Args&&... args)
      : unex (il, std::forward<Args>(args)...)
    {}

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

    // [expected.un.obs]
    [[nodiscard]] constexpr const E &
    error () const & noexcept
    { return unex; }

    [[nodiscard]] constexpr E &
    error () & noexcept
    { return unex; }

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

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

    // [expected.un.swap]
    template<typename E_ = E>
    constexpr std::enable_if_t<g_is_swappable<E_>::value>
    swap (unexpected& other) noexcept (g_is_nothrow_swappable<E>::value)
    {
      using std::swap;
      swap (unex, other.unex);
    }

    template<typename E_ = E>
    friend constexpr std::enable_if_t<g_is_swappable<E_>::value>
    swap (unexpected &x, unexpected &y) noexcept (noexcept (x.swap (y)))
    { x.swap (y); }

    // [expected.un.eq]
    template<typename E2>
    [[nodiscard]] friend constexpr eql_return_t<E, E2>
    operator== (const unexpected &x, const unexpected<E2> &y)
    { return x.error () == y.error (); }

  private:
    template<typename, typename, bool>
    friend struct expected;

    E unex;
  };

  // EXTENSION: Permit deduction of 'unexpected' from value type.  Eventually
  // to be replaced with a deduction guide.
  template<typename E>
  constexpr unexpected<std::decay_t<E>>
  make_unexpected (E &&e)
  { return unexpected<std::decay_t<E>> (std::forward<E> (e)); }

#if __cpp_deduction_guides >= 201703L
  template<class E> unexpected (E) -> unexpected<E>;
#endif

#ifdef GCC_BACKPORT_WANT_EXCEPTIONS
  // Only implemented to permit running testsuites for <expected> against this
  // implementation.  Never actually enabled.

  // [expected.void.bad]
  template<typename E>
    class bad_expected_access;

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

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

    public:

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

  // [expected.bad]
  template<typename E>
    class bad_expected_access : public bad_expected_access<void> {
    public:
      GCC_BACKPORT_CONSTEXPR_BAD_EXPECTED_ACCESS explicit
      bad_expected_access (E g_e) : m_unex (std::move (g_e)) { }

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

      [[nodiscard]]
      GCC_BACKPORT_CONSTEXPR_BAD_EXPECTED_ACCESS E&
      error () & noexcept
      { return m_unex; }

      [[nodiscard]]
      GCC_BACKPORT_CONSTEXPR_BAD_EXPECTED_ACCESS const E&
      error () const & noexcept
      { return m_unex; }

      [[nodiscard]]
      GCC_BACKPORT_CONSTEXPR_BAD_EXPECTED_ACCESS E&&
      error () && noexcept
      { return std::move (m_unex); }

      [[nodiscard]]
      GCC_BACKPORT_CONSTEXPR_BAD_EXPECTED_ACCESS const E&&
      error () const && noexcept
      { return std::move (m_unex); }

    private:
      E m_unex;
    };
#undef GCC_BACKPORT_CONSTEXPR_BAD_EXPECTED_ACCESS
#endif // GCC_BACKPORT_WANT_EXCEPTIONS

  namespace detail { namespace exp
  {
    struct in_value_t {};
    // Tag, construct value field.
    static constexpr in_value_t in_value;
    struct in_unex_t {};
    // Tag, construct unex field.
    static constexpr in_unex_t in_unex;
    struct in_unused_t {};
    // Tag, construct unused field.
    static constexpr in_unused_t in_unused;

    // Replaces T=void for storage, and acts as a placeholder when storage is
    // empty.
    struct void_storage {};

#define GCC_EXP_STORAGE_2_COMMON			\
    constexpr storage_2 () = default;			\
							\
    template<typename... Args>				\
    constexpr storage_2 (in_value_t, Args&&... args)	\
      : m_value (std::forward<Args> (args)...)		\
      , m_has_value (true)				\
    {}							\
							\
    template<typename... Args>				\
    constexpr storage_2 (in_unex_t, Args&&... args)	\
      : m_unex (std::forward<Args> (args)...)		\
      , m_has_value (false)				\
    {}							\
							\
    constexpr storage_2 (in_unused_t)			\
      : m_unused ()					\
	/* To appease constexpr; always overwritten. */	\
      , m_has_value (false)				\
    {}							\
							\
    template<typename Fn>				\
    constexpr storage_2 (in_place_inv, Fn &&fn)		\
      : m_value (std::forward<Fn> (fn) ())		\
      , m_has_value (true)				\
    {}							\
							\
    template<typename Fn>				\
    constexpr storage_2 (unexpect_inv, Fn &&fn)		\
      : m_unex (std::forward<Fn> (fn) ())		\
      , m_has_value (false)				\
    {}							\
							\
    GCC_BACKPORT20_CONSTEXPR void			\
    clear_storage ()					\
    {							\
      if (this->m_has_value)				\
	gcc::destroy_at (std::addressof (this->m_value));	\
      else						\
	gcc::destroy_at (std::addressof (this->m_unex));	\
    }

    // Container holding the contents of the expected.  Provides the
    // destructor.
    template<typename T, typename E,
	     bool is_trivial = trait_2<std::is_trivially_destructible,
				       T, E>::value>
    struct storage_2
    {
      /* Non-trivially destructible T or E.  Need a hand-written
	 destructor.  */
      GCC_BACKPORT20_CONSTEXPR
      ~storage_2 ()
      { clear_storage (); }

      GCC_EXP_STORAGE_2_COMMON

      union {
	void_storage m_unused;
	std::remove_cv_t<T> m_value;
	E m_unex;
      };
      bool m_has_value;
    };

    template<typename T, typename E>
    struct storage_2<T, E, true>
    {
      GCC_EXP_STORAGE_2_COMMON

      union {
	void_storage m_unused;
	std::remove_cv_t<T> m_value;
	E m_unex;
      };
      bool m_has_value;
    };
#undef GCC_EXP_STORAGE_2_COMMON

    // This layer provides some utilities.
    template<typename T, typename E>
    struct storage_1 : storage_2<T, E>
    {
      using storage_2<T, E>::storage_2;

      // Getters preserving const-ness and ref-ness of *this.
#define GCC_EXP_STORAGE_1_DO_GETTER(type, member, name)	\
      constexpr type &name () & noexcept		\
      { return this->member; }				\
      constexpr const type &name () const & noexcept	\
      { return this->member; }				\
      constexpr type &&name () && noexcept		\
      { return std::move (this->member); }		\
      constexpr const type &&name () const && noexcept	\
      { return std::move (this->member); }

      GCC_EXP_STORAGE_1_DO_GETTER (T, m_value, value)
      GCC_EXP_STORAGE_1_DO_GETTER (E, m_unex, unex)
#undef GCC_EXP_STORAGE_1_DO_GETTER


      // Helpers, for initial construction.
      template<typename... Args>
      constexpr void
      construct_value (Args&&... args)
      {
	gcc::construct_at (std::addressof (this->m_value),
			   std::forward<Args> (args)...);
	this->m_has_value = true;
      }

      template<typename... Args>
      constexpr void
      construct_unex (Args&&... args)
      {
	gcc::construct_at (std::addressof (this->m_unex),
			   std::forward<Args> (args)...);
	this->m_has_value = false;
      }

      // Copy/move construct our value/unex field based on other storage.
      // Presumes 'm_unused' is active right now.
      template<typename Other>
      constexpr
      std::enable_if_t<std::is_convertible<std::remove_reference_t<Other> *,
					   const volatile storage_1 *>::value>
      construct (Other &&other)
      {
	if (other.m_has_value)
	  this->construct_value (std::forward<Other> (other).value ());
	else
	  this->construct_unex (std::forward<Other> (other).unex ());
      }

      // reinit-expected exposition-only helper.

      // Pick branch of reinit-expected helper.
      template<typename T2, typename U, typename... Args>
      static constexpr int
      pick_reinit_expected ()
      {
	if (std::is_same<U, void_storage>::value)
	  // We're implementing expected<[cv] void, E> by reusing the storage
	  // for expected<T, E> but giving it a dummy empty struct.
	  //
	  // However, doing this naively runs into a problem: if E cannot be
	  // nothrow-constructed but can be nothrow-moved, reinit_expected will
	  // construct a temporary E and move it into place, rather than
	  // constructing it directly as [expected.void.assign] says.
	  //
	  // You may think we can just use branch 1 always then, but that
	  // leaves us with a destroyed m_value and no m_unex, and with
	  // m_has_value = true, so accesses down the line can trigger issues.
	  //
	  // In reality, we don't use exceptions in GCC.  So, whatever, we can
	  // take the higher-overhead branch.
	  return 3;
	else if (std::is_nothrow_constructible<T2, Args...>::value)
	  return 1;
	else if (std::is_nothrow_move_constructible<T2>::value)
	  return 2;
	else
	  return 3;
      }

      template<typename T2, typename U, typename... Args>
      GCC_BACKPORT20_CONSTEXPR void
      reinit_expected_ (std::integral_constant<int, 1>,
			T2& newval, U& oldval, Args&&... args)
      {
	gcc::destroy_at (std::addressof (oldval));
	gcc::construct_at (std::addressof (newval),
			   std::forward<Args> (args)...);
      }

      template<typename T2, typename U, typename... Args>
      GCC_BACKPORT20_CONSTEXPR void
      reinit_expected_ (std::integral_constant<int, 2>,
			T2& newval, U& oldval, Args&&... args)
      {
	T2 tmp (std::forward<Args> (args)...);
	gcc::destroy_at (std::addressof (oldval));
	gcc::construct_at (std::addressof (newval), std::move (tmp));
      }

      template<typename T2, typename U, typename... Args>
      GCC_BACKPORT20_CONSTEXPR void
      reinit_expected_ (std::integral_constant<int, 3>,
			T2& newval, U& oldval, Args&&... args)
      {
	U tmp (std::move (oldval));
	gcc::destroy_at (std::addressof (oldval));
	g_try
	  {
	    gcc::construct_at (std::addressof (newval),
			       std::forward<Args> (args)...);
	  }
	g_catch (...)
	  {
	    gcc::construct_at (std::addressof (oldval),
			       std::move (tmp));
	    g_throw_exception_again;
	  }
      }

      template<typename T2, typename U, typename... Args>
      GCC_BACKPORT20_CONSTEXPR void
      reinit_expected (T2& newval, U& oldval, Args&&... args)
      {
	constexpr int branch = pick_reinit_expected<T2, U, Args...>();
	reinit_expected_ (std::integral_constant<int, branch> (),
			  newval, oldval, std::forward<Args> (args)...);
      }

      // Assign m_value.
      template<typename U>
      GCC_BACKPORT20_CONSTEXPR void
      assign_value (U &&v)
      {
	if (this->m_has_value)
	  // "If has_value() is true, equivalent to: val = std::forward<U>(v);"
	  this->m_value = std::forward<U> (v);
	else
	  // "Otherwise, equivalent to: reinit-expected(val, unex,
	  // std::forward<U>(v)); has_val = true;"
	  {
	    reinit_expected (this->m_value, this->m_unex, std::forward<U> (v));
	    this->m_has_value = true;
	  }
      }

      // Assign m_unex.
      template<typename Other>
      GCC_BACKPORT20_CONSTEXPR void
      assign_unex (Other &&other)
      {
	if (this->m_has_value)
	  // "If has_value() is true, equivalent to: reinit-expected (unex, val,
	  // std::forward<GF>(e.error())); has_val = false;"
	  {
	    // Must clear value first.
	    reinit_expected (this->m_unex, this->m_value,
			     std::forward<Other> (other));
	    this->m_has_value = false;
	  }
	else
	  // "Otherwise, equivalent to: unex = std::forward<GF>(e.error());"
	  this->m_unex = std::forward<Other> (other);

	// Note that the std::forward<GF> (e.error ()) bit is hoisted to the
	// caller.
      }

      // Non-trivial move/copy assignment implementation.  OTHER must be a
      // storage_1.  Called by the respective special members.
      template<typename Other>
      GCC_BACKPORT20_CONSTEXPR
      std::enable_if_t<std::is_convertible<std::remove_reference_t<Other> *,
					   const volatile storage_1 *>::value>
      assign (Other &&other)
      {
	if (this->m_has_value && other.m_has_value)
	  // "If this->has_value() && rhs.has_value() is true, equivalent to
	  // val = *rhs." / "If this->has_value() && rhs.has_value() is true,
	  // equivalent to val = std::move(*rhs)."
	  this->m_value = std::forward<Other> (other).value ();
	else if (this->m_has_value)
	  // "Otherwise, if this->has_value() is true, equivalent to:
	  // reinit-expected(unex, val, rhs.error())" / "Otherwise, if
	  // this->has_value() is true, equivalent to: reinit-expected(unex,
	  // val, std::move(rhs.error()))"
	  reinit_expected (this->m_unex, this->m_value,
			   std::forward<Other> (other).unex ());
	else if (other.m_has_value)
	  // "Otherwise, if rhs.has_value() is true, equivalent to:
	  // reinit-expected(val, unex, *rhs)" / "Otherwise, if rhs.has_value()
	  // is true, equivalent to: reinit-expected(val, unex,
	  // std::move(*rhs))"
	  reinit_expected (this->m_value, this->m_unex,
			   std::forward<Other> (other).value ());
	else
	  // "Otherwise, equivalent to unex = std::move(rhs.error())."
	  this->m_unex = std::forward<Other> (other).unex ();
	// "Then, if no exception was thrown, equivalent to: has_val =
	// rhs.has_value(); return *this;"
	this->m_has_value = other.m_has_value;
      }

      // [expected.object.swap]p2 "For the case where rhs.has_value() is false
      // and this->has_value() is true", without the final 'has_val'
      // reassignments.
      template<typename E_ = E>
      GCC_BACKPORT20_CONSTEXPR
      std::enable_if_t<std::is_nothrow_move_constructible<E_>::value>
      swap_1 (T &val, E &unex,
	      T &rhs_val, E &rhs_unex)
      {
	E tmp (std::move (rhs_unex));
	gcc::destroy_at (std::addressof (rhs_unex));
	g_try
	  {
	    gcc::construct_at (std::addressof (rhs_val), std::move (val));
	    gcc::destroy_at (std::addressof (val));
	    gcc::construct_at (std::addressof (unex), std::move (tmp));
	  }
	g_catch (...)
	  {
	    gcc::construct_at (std::addressof (rhs_unex), std::move (tmp));
	    g_throw_exception_again;
	  }
      }

      template<typename E_ = E>
      GCC_BACKPORT20_CONSTEXPR
      std::enable_if_t<!std::is_nothrow_move_constructible<E_>::value>
      swap_1 (T &val, E &unex,
	      T &rhs_val, E &rhs_unex)
      {
	static_assert (std::is_nothrow_move_constructible<T>::value,
		       "Can't swap without a nothrow-move-constructible T or E"
		       ", is a constraint missing on swap?");
	T tmp (std::move (val));
	gcc::destroy_at (std::addressof (val));
	g_try
	  {
	    gcc::construct_at (std::addressof (unex), std::move (rhs_unex));
	    gcc::destroy_at (std::addressof (rhs_unex));
	    gcc::construct_at (std::addressof (rhs_val), std::move (tmp));
	  }
	g_catch (...)
	  {
	    gcc::construct_at (std::addressof (val), std::move (tmp));
	    g_throw_exception_again;
	  }
      }

      GCC_BACKPORT20_CONSTEXPR void
      _swap (storage_1 &other)
      {
	using std::swap;

	if (this->m_has_value && other.m_has_value)
	  swap (this->m_value, other.m_value);
	else if (!this->m_has_value && !other.m_has_value)
	  swap (this->m_unex, other.m_unex);
	else if (!this->m_has_value && other.m_has_value)
	  other._swap (*this);
	else
	  {
	    swap_1 (this->m_value, this->m_unex, other.m_value, other.m_unex);
	    this->m_has_value = false;
	    other.m_has_value = true;
	  }
      }
    };

    // Copy operations.
    template<typename T, typename E,
	     bool is_trivial = trait_2<std::is_trivially_copy_constructible,
				       T, E>::value>
    struct storage_copy_cons;

    template<typename T, typename E>
    struct storage_copy_cons<T, E, true> : storage_1<T, E>
    {
      using storage_1<T, E>::storage_1;
      storage_copy_cons (storage_copy_cons &&) = default;
      storage_copy_cons &
      operator= (const storage_copy_cons& other) = default;
      storage_copy_cons &
      operator= (storage_copy_cons&& other) = default;

      // Does not require explicit copy constructor.
      storage_copy_cons (const storage_copy_cons &) = default;
    };

    template<typename T, typename E>
    struct storage_copy_cons<T, E, false> : storage_1<T, E>
    {
      using storage_1<T, E>::storage_1;
      storage_copy_cons (storage_copy_cons &&) = default;
      storage_copy_cons &
      operator= (const storage_copy_cons& other) = default;
      storage_copy_cons &
      operator= (storage_copy_cons&& other) = default;

      // Requires explicit copy constructor.
      constexpr
      storage_copy_cons (const storage_copy_cons &o)
	: storage_1<T, E>(in_unused)
      { this->construct (o); }
    };

    template<typename T, typename E,
	     bool is_trivial = and_<
	       std::is_trivially_copy_constructible<T>,
	       std::is_trivially_copy_assignable<T>,
	       std::is_trivially_destructible<T>,
	       std::is_trivially_copy_constructible<E>,
	       std::is_trivially_copy_assignable<E>,
	       std::is_trivially_destructible<E>
	       >::value>
    struct storage_copy_assign;

    template<typename T, typename E>
    struct storage_copy_assign<T, E, true> : storage_copy_cons<T, E>
    {
      using storage_copy_cons<T, E>::storage_copy_cons;
      storage_copy_assign (const storage_copy_assign &) = default;
      storage_copy_assign (storage_copy_assign &&) = default;
      storage_copy_assign &
      operator= (storage_copy_assign&& other) = default;

      // Trivially copy-assignable.
      storage_copy_assign &
      operator= (const storage_copy_assign& other)
	noexcept (and_<trait_2<std::is_nothrow_copy_assignable, T, E>,
		       trait_2<std::is_nothrow_copy_constructible, T, E>>::value)
      = default;
    };

    template<typename T, typename E>
    struct storage_copy_assign<T, E, false> : storage_copy_cons<T, E>
    {
      using storage_copy_cons<T, E>::storage_copy_cons;
      storage_copy_assign (const storage_copy_assign &) = default;
      storage_copy_assign (storage_copy_assign &&) = default;
      storage_copy_assign &
      operator= (storage_copy_assign&& other) = default;

      // Requires explicit copy assignment.
      GCC_BACKPORT20_CONSTEXPR storage_copy_assign &
      operator= (const storage_copy_assign& other)
	noexcept (and_<trait_2<std::is_nothrow_copy_assignable, T, E>,
		       trait_2<std::is_nothrow_copy_constructible, T, E>>::value)
      {
	this->assign (other);
	return *this;
      }
    };

    // Move operations.
    template<typename T, typename E,
	     bool is_trivial = trait_2<std::is_trivially_move_constructible,
				       T, E>::value>
    struct storage_move_cons;

    template<typename T, typename E>
    struct storage_move_cons<T, E, true> : storage_copy_assign<T, E>
    {
      using storage_copy_assign<T, E>::storage_copy_assign;
      storage_move_cons (const storage_move_cons &) = default;
      storage_move_cons &
      operator= (const storage_move_cons &) = default;
      storage_move_cons &
      operator= (storage_move_cons &&) = default;

      // Does not require explicit move constructor.
      storage_move_cons (storage_move_cons &&) = default;
    };

    template<typename T, typename E>
    struct storage_move_cons<T, E, false> : storage_copy_assign<T, E>
    {
      using storage_copy_assign<T, E>::storage_copy_assign;
      storage_move_cons (const storage_move_cons &) = default;
      storage_move_cons &operator= (const storage_move_cons &) = default;
      storage_move_cons &operator= (storage_move_cons &&) = default;

      // Requires explicit move constructor.
      constexpr
      storage_move_cons (storage_move_cons &&o)
	noexcept (trait_2<std::is_nothrow_move_constructible, T, E>::value)
	: storage_copy_assign<T, E>(in_unused)
      { this->construct (std::move (o)); }
    };

    template<typename T, typename E,
	     bool is_trivial = and_<
	       trait_2<std::is_trivially_move_constructible, T, E>,
	       trait_2<std::is_trivially_move_assignable, T, E>,
	       trait_2<std::is_trivially_destructible, T, E>
	       >::value>
    struct storage_move_assign;

    template<typename T, typename E>
    struct storage_move_assign<T, E, true> : storage_move_cons<T, E>
    {
      using storage_move_cons<T, E>::storage_move_cons;
      storage_move_assign (storage_move_assign&&) = default;
      storage_move_assign (const storage_move_assign&) = default;
      storage_move_assign&
      operator= (const storage_move_assign&) = default;

      // Trivially move-assignable.
      storage_move_assign &
      operator= (storage_move_assign&& other)
	noexcept (and_<trait_2<std::is_nothrow_move_assignable, T, E>,
		       trait_2<std::is_nothrow_move_constructible, T, E>>::value)
      = default;
    };

    template<typename T, typename E>
    struct storage_move_assign<T, E, false> : storage_move_cons<T, E>
    {
      using storage_move_cons<T, E>::storage_move_cons;
      storage_move_assign (storage_move_assign&&) = default;
      storage_move_assign (const storage_move_assign&) = default;
      storage_move_assign&
      operator= (const storage_move_assign&) = default;

      // Requires explicit move assignment.
      GCC_BACKPORT20_CONSTEXPR storage_move_assign &
      operator= (storage_move_assign&& other)
	noexcept (and_<trait_2<std::is_nothrow_move_assignable, T, E>,
		       trait_2<std::is_nothrow_move_constructible, T, E>>::value)
      {
	this->assign (std::move (other));
	return *this;
      }
    };

    // Default construction.
    template<typename T, typename E,
	     bool is_default_cons = std::is_default_constructible<T>::value>
    struct storage_default_cons;

    template<typename T, typename E>
    struct storage_default_cons<T, E, false> : storage_move_assign<T, E>
    {
      using storage_move_assign<T, E>::storage_move_assign;
      // No default constructor.
      constexpr storage_default_cons () = delete;
    };

    template<typename T, typename E>
    struct storage_default_cons<T, E, true> : storage_move_assign<T, E>
    {
      using storage_move_assign<T, E>::storage_move_assign;
      constexpr storage_default_cons ()
	 noexcept (std::is_nothrow_constructible<T>::value)
	: storage_move_assign<T, E> (in_value)
      {}
    };

    // Final link in the chain.
    template<typename T, typename E>
    using storage = storage_default_cons<T, E>;
  }} // namespace detail::exp

  // [expected.expected]
  template<typename T, typename E, bool is_void>
  struct [[nodiscard]] expected
    : private detail::exp::storage<T, E>
    , private G_Enable_copy_move<
	// Copy constructor.
	detail::exp::trait_2<std::is_copy_constructible, T, E>::value,
	// Copy assignment.
	and_<detail::exp::trait_2<std::is_copy_assignable, T, E>,
	     detail::exp::trait_2<std::is_copy_constructible, T, E>,
	     or_<std::is_nothrow_move_constructible<T>,
		 std::is_nothrow_move_constructible<E>>
	     >::value,
	// Move constructor.
	detail::exp::trait_2<std::is_move_constructible, T, E>::value,
	// Move assignment.
	and_<detail::exp::trait_2<std::is_move_assignable, T, E>,
	     detail::exp::trait_2<std::is_move_constructible, T, E>,
	     or_<std::is_nothrow_move_constructible<T>,
		 std::is_nothrow_move_constructible<E>>>::value
      >
  {
  private:
    using storage = detail::exp::storage<T, E>;

    // 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 G_Up, typename G_Gr, typename G_Unex = unexpected<E>,
	     typename = std::remove_cv_t<T>>
    struct g_cons_from_expected
      : or_<std::is_constructible<T, expected<G_Up, G_Gr>&>,
	    std::is_constructible<T, expected<G_Up, G_Gr>>,
	    std::is_constructible<T, const expected<G_Up, G_Gr>&>,
	    std::is_constructible<T, const expected<G_Up, G_Gr>>,
	    std::is_convertible<expected<G_Up, G_Gr>&, T>,
	    std::is_convertible<expected<G_Up, G_Gr>, T>,
	    std::is_convertible<const expected<G_Up, G_Gr>&, T>,
	    std::is_convertible<const expected<G_Up, G_Gr>, T>,
	    std::is_constructible<G_Unex, expected<G_Up, G_Gr>&>,
	    std::is_constructible<G_Unex, expected<G_Up, G_Gr>>,
	    std::is_constructible<G_Unex, const expected<G_Up, G_Gr>&>,
	    std::is_constructible<G_Unex, const expected<G_Up, G_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 G_Up, typename G_Gr, typename G_Unex>
    struct g_cons_from_expected<G_Up, G_Gr, G_Unex, bool>
      : or_<std::is_constructible<G_Unex, expected<G_Up, G_Gr>&>,
	      std::is_constructible<G_Unex, expected<G_Up, G_Gr>>,
	      std::is_constructible<G_Unex, const expected<G_Up, G_Gr>&>,
	      std::is_constructible<G_Unex, const expected<G_Up, G_Gr>>
	      >
    {};

    template<typename G_Up, typename G_Gr>
    using g_explicit_conv
    = or_<not_<std::is_convertible<G_Up, T>>,
	  not_<std::is_convertible<G_Gr, E>>
	  >;

    // Constraints for 'swap'
    template<typename T_, typename E_>
    using Constrain_swap = std::enable_if_t<and_<
      g_is_swappable<T_>,
      g_is_swappable<E_>,
      std::is_move_constructible<T_>,
      std::is_move_constructible<E_>,
      or_<
	std::is_nothrow_move_constructible<T_>,
	std::is_nothrow_move_constructible<E_>
	>
      >::value>;

  public:
    static_assert (detail::exp::can_be_unexpected_val<E>::value,
		   "E not a valid expected error type");
    static_assert (detail::exp::can_be_expected_val<T>::value,
		   "T cannot be expected<>");

    using value_type = T;
    using error_type = E;
    using unexpected_type = unexpected<E>;

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

    // [expected.object.obs]

    // [expected.object.obs]p1
    [[nodiscard]] constexpr const T*
    operator-> () const noexcept
    {
      gccbackport_assert (this->m_has_value && "Accessing value of expected with no value");
      return std::addressof (this->m_value);
    }

    [[nodiscard]] constexpr T*
    operator-> () noexcept
    {
      gccbackport_assert (this->m_has_value && "Accessing value of expected with no value");
      return std::addressof (this->m_value);
    }

    // [expected.object.obs]p3
    [[nodiscard]] constexpr const T&
    operator* () const & noexcept
    {
      gccbackport_assert (this->m_has_value && "Accessing value of expected with no value");
      return this->m_value;
    }

    [[nodiscard]] constexpr T&
    operator* () & noexcept
    {
      gccbackport_assert (this->m_has_value && "Accessing value of expected with no value");
      return this->m_value;
    }

    // [expected.object.obs]p5
    [[nodiscard]] constexpr T&&
    operator* () && noexcept
    {
      gccbackport_assert (this->m_has_value && "Accessing value of expected with no value");
      return std::move (this->m_value);
    }

    [[nodiscard]] constexpr const T&&
    operator* () const && noexcept
    {
      gccbackport_assert (this->m_has_value && "Accessing value of expected with no value");
      return std::move (this->m_value);
    }

    // [expected.object.obs]p7
    [[nodiscard]] constexpr explicit
    operator bool () const noexcept
    { return this->m_has_value; }

    [[nodiscard]] constexpr bool
    has_value () const noexcept
    { return this->m_has_value; }

    // [expected.object.obs]p8
    [[nodiscard]] constexpr bool
    has_error () const noexcept
    { return !this->m_has_value; }

    // TODO(arsen): restore [[likely]]

    // [expected.object.obs]p9
    constexpr const T&
    value () const &
    {
      static_assert (std::is_copy_constructible<E>::value, "");
      if (this->m_has_value)
	return this->m_value;
      g_throw_or_abort (bad_expected_access<E> (gcc::as_const (error ())));
    }

    constexpr T&
    value () &
    {
      static_assert (std::is_copy_constructible<E>::value, "");
      if (this->m_has_value)
	return this->m_value;
      g_throw_or_abort (bad_expected_access<E> (gcc::as_const (error ())));
    }

    // [expected.object.obs]p12
    constexpr const T&&
    value () const &&
    {
      static_assert (std::is_copy_constructible<E>::value, "");
      static_assert (std::is_constructible<E, const E&&>::value, "");
      if (this->m_has_value)
	return std::move (this->m_value);
      g_throw_or_abort (bad_expected_access<E> (std::move (error ())));
    }

    constexpr T&&
    value () &&
    {
      static_assert (std::is_copy_constructible<E>::value, "");
      static_assert (std::is_constructible<E, E&&>::value, "");
      if (this->m_has_value)
	return std::move (this->m_value);
      g_throw_or_abort (bad_expected_access<E> (std::move (error ())));
    }

    // [expected.object.obs]p15
    constexpr const E&
    error () const & noexcept
    {
      gccbackport_assert (!this->m_has_value && "Accessing error of expected with no error");
      return this->m_unex;
    }

    constexpr E&
    error () & noexcept
    {
      gccbackport_assert (!this->m_has_value && "Accessing error of expected with no error");
      return this->m_unex;
    }

    // [expected.object.obs]p17
    constexpr const E&&
    error () const && noexcept
    {
      gccbackport_assert (!this->m_has_value && "Accessing error of expected with no error");
      return std::move (this->m_unex);
    }

    constexpr E&&
    error () && noexcept
    {
      gccbackport_assert (!this->m_has_value && "Accessing error of expected with no error");
      return std::move (this->m_unex);
    }

    // [expected.object.obs]p19
    template<typename U = std::remove_cv_t<T>>
    constexpr T
    value_or (U &&v) const &
    {
      static_assert (std::is_convertible<U, T>::value,
		     "lvalue-reference value_or requires that type of "
		     "argument is convertible to the value type");
      static_assert (std::is_copy_constructible<T>::value,
		     "lvalue-reference value_or requires that value type is "
		     "copy-constructible");
      return (this->m_has_value
	      ? **this
	      : static_cast<T> (std::forward<U> (v)));
    }

    // [expected.object.obs]p21
    template<typename U = std::remove_cv_t<T>>
    constexpr T
    value_or (U &&v) &&
    {
      static_assert (std::is_convertible<U, T>::value,
		     "rvalue-reference value_or requires that type of "
		     "argument is convertible to the value type");
      static_assert (std::is_move_constructible<T>::value,
		     "rvalue-reference value_or requires that value type is "
		     "move-constructible");
      return (this->m_has_value
	      ? std::move (**this)
	      : static_cast<T> (std::forward<U> (v)));
    }

    // [expected.object.obs]p23
    template<typename G = E>
    constexpr E
    error_or (G &&e) const &
    {
      static_assert (std::is_convertible<G, E>::value,
		     "lvalue-reference error_or requires that type of "
		     "argument is convertible to the value type");
      static_assert (std::is_copy_constructible<E>::value,
		     "lvalue-reference error_or requires that error type is "
		     "copy-constructible");
      if (this->m_has_value)
	return std::forward<G> (e);
      return this->m_unex;
    }

    // [expected.object.obs]p26
    template<typename G = E>
    constexpr E
    error_or (G &&e) &&
    {
      static_assert (std::is_convertible<G, E>::value,
		     "rvalue-reference error_or requires that type of "
		     "argument is convertible to the value type");
      static_assert (std::is_move_constructible<E>::value,
		     "rvalue-reference error_or requires that error type is "
		     "move-constructible");
      if (this->m_has_value)
	return std::forward<G> (e);
      return std::move (this->m_unex);
    }

    // Constructors [expected.object.cons]

    // [expected.object.cons]p1; condition provided by base class
    expected () = default;

    // [expected.object.cons]p6 and [expected.object.cons]p11 - the copy/move
    // constructors - are implemented by storage and constrained by
    // G_Enable_copy_move.
    expected (const expected&) = default;
    expected (expected&&) = default;

    // [expected.object.cons]p17
    template<typename U, typename G,
	     G_Requires<
	       // Constraints:
	       not_<g_cons_from_expected<U, G>>,
	       std::is_constructible<T, const U&>,
	       std::is_constructible<E, const G&>,

	       // !Explicit:
	       not_<g_explicit_conv<const U&, const G&>>
	       > = false>
    constexpr expected (const expected<U, G>& rhs)
      : storage (detail::exp::in_unused)
    {
      if (rhs.has_value ())
	this->construct_value (*rhs);
      else
	this->construct_unex (rhs.error ());
    }

    template<typename U, typename G,
	     G_Requires<
	       // Constraints:
	       not_<g_cons_from_expected<U, G>>,
	       std::is_constructible<T, const U&>,
	       std::is_constructible<E, const G&>,

	       // Explicit:
	       g_explicit_conv<const U&, const G&>
	       > = false>
    constexpr explicit expected (const expected<U, G>& rhs)
      : storage (detail::exp::in_unused)
    {
      if (rhs.has_value ())
	this->construct_value (*rhs);
      else
	this->construct_unex (rhs.error ());
    }

    template<typename U, typename G,
	     G_Requires<
	       // Constraints:
	       not_<g_cons_from_expected<U, G>>,
	       std::is_constructible<T, U&&>,
	       std::is_constructible<E, G&&>,

	       // !Explicit:
	       not_<g_explicit_conv<U, G>>
	       > = false>
    constexpr expected (expected<U, G>&& rhs)
      : storage (detail::exp::in_unused)
    {
      if (rhs.has_value ())
	this->construct_value (std::move (*rhs));
      else
	this->construct_unex (std::move (rhs.m_unex));
    }

    template<typename U, typename G,
	     G_Requires<
	       // Constraints:
	       not_<g_cons_from_expected<U, G>>,
	       std::is_constructible<T, U&&>,
	       std::is_constructible<E, G&&>,

	       // Explicit:
	       g_explicit_conv<U, G>
	       > = false>
    constexpr explicit expected (expected<U, G>&& rhs)
      : storage (detail::exp::in_unused)
    {
      if (rhs.has_value ())
	this->construct_value (std::move (*rhs));
      else
	this->construct_unex (std::move (rhs.m_unex));
    }

    // [expected.object.cons]p23
    template<typename U = std::remove_cv_t<T>,
	     G_Requires<
	       // Constraints:
	       not_<std::is_same<remove_cvref_t<U>, in_place_t>>,
	       not_<std::is_same<remove_cvref_t<U>, expected>>,
	       not_<std::is_same<remove_cvref_t<U>, unexpect_t>>,
	       not_<detail::exp::is_unexpected<remove_cvref_t<U>>>,
	       std::is_constructible<T, U>,
	       // "if T is cv bool, remove_cvref_t<U> is not a specialization
	       // of expected"
	       or_<not_<std::is_same<std::remove_cv_t<T>, bool>>,
		   not_<detail::exp::is_expected<remove_cvref_t<U>>>>,

	       // !Explicit:
	       std::is_convertible<U, T>
	       > = false>
    constexpr expected (U&& v)
      : storage (detail::exp::in_value, std::forward<U> (v))
    {}

    template<typename U = std::remove_cv_t<T>,
	     G_Requires<
	       // Constraints:
	       not_<std::is_same<remove_cvref_t<U>, in_place_t>>,
	       not_<std::is_same<remove_cvref_t<U>, expected>>,
	       not_<std::is_same<remove_cvref_t<U>, unexpect_t>>,
	       not_<detail::exp::is_unexpected<remove_cvref_t<U>>>,
	       std::is_constructible<T, U>,
	       // "if T is cv bool, remove_cvref_t<U> is not a specialization
	       // of expected"
	       or_<not_<std::is_same<std::remove_cv_t<T>, bool>>,
		   not_<detail::exp::is_expected<remove_cvref_t<U>>>>,

	       // Explicit:
	       not_<std::is_convertible<U, T>>
	       > = false>
    constexpr explicit expected (U&& v)
      : storage (detail::exp::in_value, std::forward<U> (v))
    {}

    // [expected.object.cons]p27
    template<typename G,
	     G_Requires<
	       // Constraints:
	       std::is_constructible<E, const G&>,

	       // !Explicit:
	       std::is_convertible<const G&, E>
	       > = false>
    constexpr expected (const unexpected<G> &e)
      : storage (detail::exp::in_unex, std::forward<const G&> (e.error ()))
    {}

    template<typename G,
	     G_Requires<
	       // Constraints:
	       std::is_constructible<E, const G&>,

	       // Explicit:
	       not_<std::is_convertible<const G&, E>>
	       > = false>
    constexpr explicit expected (const unexpected<G> &e)
      : storage (detail::exp::in_unex, std::forward<const G&> (e.error ()))
    {}

    template<typename G,
	     G_Requires<
	       // Constraints:
	       std::is_constructible<E, G&&>,

	       // !Explicit:
	       std::is_convertible<G&&, E>
	       > = false>
    constexpr expected (unexpected<G> &&e)
      : storage (detail::exp::in_unex, std::forward<G&&> (e.error ()))
    {}

    template<typename G,
	     G_Requires<
	       // Constraints:
	       std::is_constructible<E, G&&>,

	       // Explicit:
	       not_<std::is_convertible<G&&, E>>
	       > = false>
    constexpr explicit expected (unexpected<G> &&e)
      : storage (detail::exp::in_unex, std::forward<G&&> (e.error ()))
    {}

    // [expected.object.cons]p32
    template<typename... Args,
	     G_Requires<
	       std::is_constructible<T, Args...>
	       > = false>
    constexpr explicit expected (in_place_t, Args&&... args)
      : storage (detail::exp::in_value, std::forward<Args> (args)...)
    {}

    // [expected.object.cons]p36
    template<typename U, typename... Args,
	     G_Requires<
	       std::is_constructible<T,
				     std::initializer_list<U>&, Args...>
	       > = false>
    constexpr explicit expected (in_place_t, std::initializer_list<U> il,
				 Args&&... args)
      : storage (detail::exp::in_value, il, std::forward<Args> (args)...)
    {}

    // [expected.object.cons]p40
    template<typename... Args,
	     G_Requires<
	       std::is_constructible<E, Args...>
	       > = false>
    constexpr explicit expected (unexpect_t, Args&&... args)
      : storage (detail::exp::in_unex, std::forward<Args> (args)...)
    {}

    // [expected.object.cons]p44
    template<typename U, typename... Args,
	     G_Requires<
	       std::is_constructible<E, std::initializer_list<U>&, Args...>
	       > = false>
    constexpr explicit expected (unexpect_t, std::initializer_list<U> il,
				 Args&&... args)
      : storage (detail::exp::in_unex, il, std::forward<Args> (args)...)
    {}

    // [expected.object.dtor], implemented in storage
    ~expected () = default;

    // [expected.object.assign]
    // The move/copy assignment operators are in the base class, and
    // constrained by G_Enable_copy_move, much like the constructors.
    expected &
    operator= (const expected &) = default;
    expected &
    operator= (expected &&) = default;

    // [expected.object.assign]p11
    template<typename U = std::remove_cv_t<T>,
	     G_Requires<
	       not_<std::is_same<expected, remove_cvref_t<U>>>,
	       not_<detail::exp::is_unexpected<remove_cvref_t<U>>>,
	       std::is_constructible<T, U>,
	       std::is_assignable<T&, U>,

	       or_<std::is_nothrow_constructible<T, U>,
		   std::is_nothrow_move_constructible<T>,
		   std::is_nothrow_move_constructible<E>>
	       > = false>
    GCC_BACKPORT20_CONSTEXPR expected& operator= (U&& v)
    {
      this->assign_value (std::forward<U> (v));
      return *this;
    }

    // [expected.object.assign]p14
    template<typename G,
	     G_Requires<
	       std::is_constructible<E, const G &>,
	       std::is_assignable<E&, const G &>,

	       or_<std::is_nothrow_constructible<E, const G &>,
		   std::is_nothrow_move_constructible<T>,
		   std::is_nothrow_move_constructible<E>>
	       > = false>
    GCC_BACKPORT20_CONSTEXPR expected &
    operator= (const unexpected<G>& e)
    {
      this->assign_unex (std::forward<const G &> (e.error ()));
      return *this;
    }

    template<typename G,
	     G_Requires<
	       std::is_constructible<E, G &&>,
	       std::is_assignable<E&, G &&>,

	       or_<std::is_nothrow_constructible<E, G &&>,
		   std::is_nothrow_move_constructible<T>,
		   std::is_nothrow_move_constructible<E>>
	       > = false>
    GCC_BACKPORT20_CONSTEXPR expected &
    operator= (unexpected<G>&& e)
    {
      this->assign_unex (std::forward<G &&> (e.error ()));
      return *this;
    }

    // [expected.object.assign]p18
    template<typename... Args,
	     G_Requires<
	       std::is_nothrow_constructible<T, Args...>
	       > = false>
    constexpr T &
    emplace (Args&&... args) noexcept
    {
      this->clear_storage ();
      this->m_has_value = true;
      return *gcc::construct_at (std::addressof (this->m_value),
				 std::forward<Args> (args)...);
    }

    // [expected.object.assign]p20
    template<typename U, typename... Args,
	     G_Requires<
	       std::is_nothrow_constructible<T,
					     std::initializer_list<U>&,
					     Args...>
	       > = false>
    constexpr T &
    emplace (std::initializer_list<U> il, Args&&... args) noexcept
    {
      this->clear_storage ();
      this->m_has_value = true;
      return *gcc::construct_at (std::addressof (this->m_value),
				 il, std::forward<Args> (args)...);
    }

    // [expected.object.swap]
    template<typename T_ = T, typename E_ = E>
    constexpr Constrain_swap<T_, E_>
    swap (expected& rhs)
      noexcept (and_<std::is_nothrow_move_constructible<T>,
		     g_is_nothrow_swappable<T>,
		     std::is_nothrow_move_constructible<E>,
		     g_is_nothrow_swappable<E>>::value)
    { this->_swap (static_cast<storage &> (rhs)); }

    template<typename T_ = T, typename E_ = E>
    friend constexpr
    Constrain_swap<T_, E_>
    swap (expected& x, expected& y) noexcept (noexcept (x.swap (y)))
    { x.swap (y); }

    // [expected.object.monadic]

    // [expected.object.monadic]p1
    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, E_ &>
	       > = false>
    constexpr auto
    and_then (F &&f) &
    {
      using U = remove_cvref_t<g_invoke_result_t<F, decltype (**this)>>;
      static_assert (detail::exp::is_expected_with_error<U, E>::value,
		     "the function passed to std::expected<T, E>::and_then "
		     "must return a std::expected with same error type");
      if (has_value ())
	return gcc::invoke (std::forward<F> (f), **this);
      else
	return U (unexpect, this->m_unex);
    }

    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, const E_ &>
	       > = false>
    constexpr auto
    and_then (F &&f) const &
    {
      using U = remove_cvref_t<g_invoke_result_t<F, decltype (**this)>>;
      static_assert (detail::exp::is_expected_with_error<U, E>::value,
		     "the function passed to std::expected<T, E>::and_then "
		     "must return a std::expected with same error type");
      if (has_value ())
	return gcc::invoke (std::forward<F> (f), **this);
      else
	return U (unexpect, this->m_unex);
    }

    // [expected.object.monadic]p5
    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, E_ &&>
	       > = false>
    constexpr auto
    and_then (F &&f) &&
    {
      using U = remove_cvref_t<g_invoke_result_t<F, decltype (std::move (**this))>>;
      static_assert (detail::exp::is_expected_with_error<U, E>::value,
		     "the function passed to std::expected<T, E>::and_then "
		     "must return a std::expected with same error type");
      if (has_value ())
	return gcc::invoke (std::forward<F> (f), std::move (**this));
      else
	return U (unexpect, std::move (this->m_unex));
    }

    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, const E_ &&>
	       > = false>
    constexpr auto
    and_then (F &&f) const &&
    {
      using U = remove_cvref_t<g_invoke_result_t<F, decltype (std::move (**this))>>;
      static_assert (detail::exp::is_expected_with_error<U, E>::value,
		     "the function passed to std::expected<T, E>::and_then "
		     "must return a std::expected with same error type");
      if (has_value ())
	return gcc::invoke (std::forward<F> (f), std::move (**this));
      else
	return U (unexpect, std::move (this->m_unex));
    }

    // [expected.object.monadic]p9
    template<typename F,
	     typename T_ = T,
	     G_Requires<
	       std::is_constructible<T_, T_ &>
	       > = false>
    constexpr auto
    or_else (F &&f) &
    {
      using G = remove_cvref_t<g_invoke_result_t<F, decltype (error ())>>;
      static_assert (detail::exp::is_expected_with_value<G, T>::value,
		     "the function passed to std::expected<T, E>::or_else "
		     "must return a std::expected with same value type");
      if (has_value ())
	return G (in_place, **this);
      else
	return gcc::invoke (std::forward<F> (f), this->m_unex);
    }

    template<typename F,
	     typename T_ = T,
	     G_Requires<
	       std::is_constructible<T_, const T_&>
	       > = false>
    constexpr auto
    or_else (F &&f) const &
    {
      using G = remove_cvref_t<g_invoke_result_t<F, decltype (error ())>>;
      static_assert (detail::exp::is_expected_with_value<G, T>::value,
		     "the function passed to std::expected<T, E>::or_else "
		     "must return a std::expected with same value type");
      if (has_value ())
	return G (in_place, **this);
      else
	return gcc::invoke (std::forward<F> (f), this->m_unex);
    }

    // [expected.object.monadic]p13
    template<typename F,
	     typename T_ = T,
	     G_Requires<
	       std::is_constructible<T_, T_ &&>
	       > = false>
    constexpr auto
    or_else (F &&f) &&
    {
      using G = remove_cvref_t<g_invoke_result_t<F, decltype (std::move (error ()))>>;
      static_assert (detail::exp::is_expected_with_value<G, T>::value,
		     "the function passed to std::expected<T, E>::or_else "
		     "must return a std::expected with same value type");
      if (has_value ())
	return G (in_place, std::move (**this));
      else
	return gcc::invoke (std::forward<F> (f), std::move (this->m_unex));
    }

    template<typename F,
	     typename T_ = T,
	     G_Requires<
	       std::is_constructible<T_, const T_ &&>
	       > = false>
    constexpr auto
    or_else (F &&f) const &&
    {
      using G = remove_cvref_t<g_invoke_result_t<F, decltype (std::move (error ()))>>;
      static_assert (detail::exp::is_expected_with_value<G, T>::value,
		     "the function passed to std::expected<T, E>::or_else "
		     "must return a std::expected with same value type");
      if (has_value ())
	return G (in_place, std::move (**this));
      else
	return gcc::invoke (std::forward<F> (f), std::move (this->m_unex));
    }

    // [expected.object.monadic]p17
    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, E_ &>
	       > = false>
    constexpr auto
    transform (F &&f) &
    {
      using U = std::remove_cv_t<g_invoke_result_t<F, decltype (**this)>>;
      using Res = expected<U, E>;
      if (has_value ())
	return Res (detail::exp::in_place_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), **this);
	});
      else
	return Res (unexpect, this->m_unex);
    }

    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, const E_ &>
	       > = false>
    constexpr auto
    transform (F &&f) const &
    {
      using U = std::remove_cv_t<g_invoke_result_t<F, decltype (**this)>>;
      using Res = expected<U, E>;
      if (has_value ())
	return Res (detail::exp::in_place_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), **this);
	});
      else
	return Res (unexpect, this->m_unex);
    }

    // [expected.object.monadic]p21
    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, E_ &&>
	       > = false>
    constexpr auto
    transform (F &&f) &&
    {
      using U = std::remove_cv_t<g_invoke_result_t<F, decltype (std::move (**this))>>;
      using Res = expected<U, E>;
      if (has_value ())
	return Res (detail::exp::in_place_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), std::move (**this));
	});
      else
	return Res (unexpect, std::move (this->m_unex));
    }

    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, const E_ &&>
	       > = false>
    constexpr auto
    transform (F &&f) const &&
    {
      using U = std::remove_cv_t<g_invoke_result_t<F, decltype (std::move (**this))>>;
      using Res = expected<U, E>;
      if (has_value ())
	return Res (detail::exp::in_place_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), std::move (**this));
	});
      else
	return Res (unexpect, std::move (this->m_unex));
    }

    // [expected.object.monadic]p25
    template<typename F,
	     typename T_ = T,
	     G_Requires<
	       std::is_constructible<T_, T_ &>
	       > = false>
    constexpr auto
    transform_error (F &&f) &
    {
      using G = std::remove_cv_t<g_invoke_result_t<F, decltype (error ())>>;
      using Res = expected<T, G>;
      if (has_value ())
	return Res (in_place, **this);
      else
	return Res (detail::exp::unexpect_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), this->m_unex);
	});
    }

    template<typename F,
	     typename T_ = T,
	     G_Requires<
	       std::is_constructible<T_, const T_ &>
	       > = false>
    constexpr auto
    transform_error (F &&f) const &
    {
      using G = std::remove_cv_t<g_invoke_result_t<F, decltype (error ())>>;
      using Res = expected<T, G>;
      if (has_value ())
	return Res (in_place, **this);
      else
	return Res (detail::exp::unexpect_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), this->m_unex);
	});
    }

    // [expected.object.monadic]p29
    template<typename F,
	     typename T_ = T,
	     G_Requires<
	       std::is_constructible<T_, T_ &&>
	       > = false>
    constexpr auto
    transform_error (F &&f) &&
    {
      using G = std::remove_cv_t<g_invoke_result_t<F, decltype (std::move (error ()))>>;
      using Res = expected<T, G>;
      if (has_value ())
	return Res (in_place, std::move (**this));
      else
	return Res (detail::exp::unexpect_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), std::move (this->m_unex));
	});
    }

    template<typename F,
	     typename T_ = T,
	     G_Requires<
	       std::is_constructible<T_, const T_ &&>
	       > = false>
    constexpr auto
    transform_error (F &&f) const &&
    {
      using G = std::remove_cv_t<g_invoke_result_t<F, decltype (std::move (error ()))>>;
      using Res = expected<T, G>;
      if (has_value ())
	return Res (in_place, std::move (**this));
      else
	return Res (detail::exp::unexpect_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), std::move (this->m_unex));
	});
    }

    // [expected.object.eq]
    template<typename T2, typename E2>
    [[nodiscard]] friend constexpr
    detail::exp::eql_2_return_t<T, T2, E, E2>
    operator== (const expected &x, const expected<T2, E2> &y)
    {
      if (x.m_has_value && y.m_has_value)
	return *x == *y;
      else if (!x.m_has_value && !y.m_has_value)
	return x.m_unex == y.m_unex;
      return false;
    }

    template<typename T2,
	     G_Requires<
	       not_<detail::exp::is_expected<T2>>
	       > = false>
    [[nodiscard]] friend constexpr
    eql_return_t<T, T2>
    operator== (const expected &x, const T2 &y)
    {
      if (!x.m_has_value)
	return false;
      return *x == y;
    }

    template<typename E2>
    [[nodiscard]] friend constexpr
    eql_return_t<E, E2>
    operator== (const expected &x, const unexpected<E2> &y)
    {
      if (x.m_has_value)
	return false;
      return x.m_unex == y.unex;
    }

  private:
    template<typename Fn>
    explicit constexpr
    expected (detail::exp::in_place_inv tag, Fn&& fn)
      : storage (tag, std::forward<Fn> (fn))
    {}

    template<typename Fn>
    explicit constexpr
    expected (detail::exp::unexpect_inv tag, Fn&& fn)
      : storage (tag, std::forward<Fn> (fn))
    {}

    template<typename, typename, bool>
    friend struct expected;
  };

  template<typename Void, typename E>
  struct [[nodiscard]] expected<Void, E, true>
    : private detail::exp::storage<detail::exp::void_storage, E>
    , private G_Enable_copy_move<
	// Copy constructor.
	std::is_copy_constructible<E>::value,
	// Copy assignment.
        and_<std::is_copy_assignable<E>,
	     std::is_copy_constructible<E>>::value,
	// Move constructor.
	std::is_move_constructible<E>::value,
	// Move assignment.
        and_<std::is_move_assignable<E>,
	     std::is_move_constructible<E>>::value
      >
  {
  private:
    using storage = detail::exp::storage<detail::exp::void_storage, E>;

    template<typename G_Up, typename G_Gr, typename G_Unex = unexpected<E>>
    struct g_cons_from_expected
      : or_<std::is_constructible<G_Unex, expected<G_Up, G_Gr>&>,
	    std::is_constructible<G_Unex, expected<G_Up, G_Gr>>,
	    std::is_constructible<G_Unex, const expected<G_Up, G_Gr>&>,
	    std::is_constructible<G_Unex, const expected<G_Up, G_Gr>>
	    >
    {};

    template<typename E_>
    using Constrain_swap = std::enable_if_t<and_<
      g_is_swappable<E_>,
      std::is_move_constructible<E_>
      >::value>;

  public:
    static_assert (detail::exp::can_be_unexpected_val<E>::value,
		   "E not a valid expected error type");

    using value_type = Void;
    using error_type = E;
    using unexpected_type = unexpected<E>;

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

    // [expected.void.obs]p1
    [[nodiscard]] constexpr explicit
    operator bool () const noexcept
    { return this->m_has_value; }

    [[nodiscard]] constexpr bool
    has_value () const noexcept
    { return this->m_has_value; }

    // [expected.void.obs]p2
    [[nodiscard]] constexpr bool
    has_error () const noexcept
    { return !this->m_has_value; }

    // [expected.void.obs]p3
    constexpr void
    operator* () const noexcept
    {
      gccbackport_assert (this->m_has_value && "Accessing value of expected with no value");
    }

    // [expected.void.obs]p4
    constexpr void
    value () const &
    {
      static_assert (std::is_copy_constructible<E>::value, "");
      if (!this->m_has_value)
	g_throw_or_abort (bad_expected_access<E> (error ()));
    }

    // [expected.void.obs]p6
    constexpr void
    value () &&
    {
      static_assert (std::is_copy_constructible<E>::value, "");
      static_assert (std::is_constructible<E, E&&>::value, "");
      if (!this->m_has_value)
	g_throw_or_abort (bad_expected_access<E> (std::move (error ())));
    }

    // [expected.void.obs]p8
    constexpr const E&
    error () const & noexcept
    {
      gccbackport_assert (!this->m_has_value && "Accessing error of expected with no error");
      return this->m_unex;
    }

    constexpr E&
    error () & noexcept
    {
      gccbackport_assert (!this->m_has_value && "Accessing error of expected with no error");
      return this->m_unex;
    }

    // [expected.void.obs]p10
    constexpr const E&&
    error () const && noexcept
    {
      gccbackport_assert (!this->m_has_value && "Accessing error of expected with no error");
      return std::move (this->m_unex);
    }

    constexpr E&&
    error () && noexcept
    {
      gccbackport_assert (!this->m_has_value && "Accessing error of expected with no error");
      return std::move (this->m_unex);
    }

    // [expected.void.obs]p12
    template<typename G = E>
    constexpr E
    error_or (G &&e) const &
    {
      static_assert (std::is_convertible<G, E>::value,
		     "lvalue-reference error_or requires that type of "
		     "argument is convertible to the error type");
      static_assert (std::is_copy_constructible<E>::value,
		     "lvalue-reference error_or requires that error type is "
		     "copy-constructible");
      if (this->m_has_value)
	return std::forward<G> (e);
      return this->m_unex;
    }

    // [expected.void.obs]p14
    template<typename G = E>
    constexpr E
    error_or (G &&e) &&
    {
      static_assert (std::is_convertible<G, E>::value,
		     "rvalue-reference error_or requires that type of "
		     "argument is convertible to the error type");
      static_assert (std::is_move_constructible<E>::value,
		     "rvalue-reference error_or requires that error type is "
		     "move-constructible");
      if (this->m_has_value)
	return std::forward<G> (e);
      return std::move (this->m_unex);
    }

    // Constructors [expected.void.cons]

    // [expected.void.cons]p1; condition provided by base class
    expected () = default;

    // [expected.void.cons]p2 and [expected.void.cons]p7 - the copy/move
    // constructors - are implemented by storage and constrained by
    // G_Enable_copy_move.
    expected (const expected&) = default;
    expected (expected&&) = default;

    // [expected.void.cons]p12
    template<typename U, typename G,
	     G_Requires<
	       // Constraints:
	       std::is_void<U>,
	       std::is_constructible<E, const G&>,
	       not_<g_cons_from_expected<U, G>>,

	       // !Explicit:
	       std::is_convertible<const G&, E>
	       > = false>
    constexpr expected (const expected<U, G>& rhs)
      : storage (detail::exp::in_unused)
    {
      if (rhs.has_value ())
	this->construct_value ();
      else
	this->construct_unex (rhs.error ());
    }

    template<typename U, typename G,
	     G_Requires<
	       // Constraints:
	       std::is_void<U>,
	       std::is_constructible<E, const G&>,
	       not_<g_cons_from_expected<U, G>>,

	       // Explicit:
	       not_<std::is_convertible<const G&, E>>
	       > = false>
    constexpr explicit expected (const expected<U, G>& rhs)
      : storage (detail::exp::in_unused)
    {
      if (rhs.has_value ())
	this->construct_value ();
      else
	this->construct_unex (rhs.error ());
    }

    template<typename U, typename G,
	     G_Requires<
	       // Constraints:
	       std::is_void<U>,
	       std::is_constructible<E, G&&>,
	       not_<g_cons_from_expected<U, G>>,

	       // !Explicit:
	       std::is_convertible<G, E>
	       > = false>
    constexpr expected (expected<U, G>&& rhs)
      : storage (detail::exp::in_unused)
    {
      if (rhs.has_value ())
	this->construct_value ();
      else
	this->construct_unex (std::move (rhs.m_unex));
    }

    template<typename U, typename G,
	     G_Requires<
	       // Constraints:
	       std::is_void<U>,
	       std::is_constructible<E, G &&>,
	       not_<g_cons_from_expected<U, G>>,

	       // Explicit:
	       not_<std::is_convertible<G, E>>
	       > = false>
    constexpr explicit expected (expected<U, G>&& rhs)
      : storage (detail::exp::in_unused)
    {
      if (rhs.has_value ())
	this->construct_value ();
      else
	this->construct_unex (std::move (rhs.m_unex));
    }

    // [expected.void.cons]p17
    template<typename G,
	     G_Requires<
	       // Constraints:
	       std::is_constructible<E, const G&>,

	       // !Explicit:
	       std::is_convertible<const G&, E>
	       > = false>
    constexpr expected (const unexpected<G> &e)
      : storage (detail::exp::in_unex, std::forward<const G&> (e.error ()))
    {}

    template<typename G,
	     G_Requires<
	       // Constraints:
	       std::is_constructible<E, const G&>,

	       // Explicit:
	       not_<std::is_convertible<const G&, E>>
	       > = false>
    constexpr explicit expected (const unexpected<G> &e)
      : storage (detail::exp::in_unex, std::forward<const G&> (e.error ()))
    {}

    template<typename G,
	     G_Requires<
	       // Constraints:
	       std::is_constructible<E, G&&>,

	       // !Explicit:
	       std::is_convertible<G&&, E>
	       > = false>
    constexpr expected (unexpected<G> &&e)
      : storage (detail::exp::in_unex, std::forward<G&&> (e.error ()))
    {}

    template<typename G,
	     G_Requires<
	       // Constraints:
	       std::is_constructible<E, G&&>,

	       // Explicit:
	       not_<std::is_convertible<G&&, E>>
	       > = false>
    constexpr explicit expected (unexpected<G> &&e)
      : storage (detail::exp::in_unex, std::forward<G&&> (e.error ()))
    {}

    // [expected.void.cons]p22
    constexpr explicit expected (in_place_t) noexcept
      : storage (detail::exp::in_value)
    {}

    // [expected.void.cons]p23
    template<typename... Args,
	     G_Requires<
	       std::is_constructible<E, Args...>
	       > = false>
    constexpr explicit expected (unexpect_t, Args&&... args)
      : storage (detail::exp::in_unex, std::forward<Args> (args)...)
    {}

    // [expected.void.cons]p27
    template<typename U, typename... Args,
	     G_Requires<
	       std::is_constructible<E, std::initializer_list<U>&, Args...>
	       > = false>
    constexpr explicit expected (unexpect_t, std::initializer_list<U> il,
				 Args&&... args)
      : storage (detail::exp::in_unex, il, std::forward<Args> (args)...)
    {}

    // [expected.void.dtor], implemented in storage
    ~expected () = default;

    // [expected.void.assign]p11, p5
    // The move/copy assignment operators are in the base class, and
    // constrained by G_Enable_copy_move, much like the constructors.
    expected &
    operator= (const expected &) = default;
    expected &
    operator= (expected &&) = default;

    // [expected.void.assign]p10
    template<typename G,
	     G_Requires<
	       std::is_constructible<E, const G &>,
	       std::is_assignable<E&, const G &>
	       > = false>
    GCC_BACKPORT20_CONSTEXPR expected &
    operator= (const unexpected<G>& e)
    {
      this->assign_unex (std::forward<const G &> (e.error ()));
      return *this;
    }

    template<typename G,
	     G_Requires<
	       std::is_constructible<E, G &&>,
	       std::is_assignable<E&, G &&>
	       > = false>
    GCC_BACKPORT20_CONSTEXPR expected &
    operator= (unexpected<G>&& e)
    {
      this->assign_unex (std::forward<G &&> (e.error ()));
      return *this;
    }

    // [expected.void.assign]p14
    constexpr void
    emplace () noexcept
    {
      this->clear_storage ();
      this->construct_value ();
    }

    // [expected.void.swap]
    // Not using storage::swap as in the case where one expected has a value
    // and the other does not, it makes an extra unneeded move in order to be
    // able to shift around the T value.  We don't have a T value here, but we
    // pretend we do for sake of storage.
    template<typename E_ = E>
    constexpr Constrain_swap<E_>
    swap (expected& other)
      noexcept (and_<std::is_nothrow_move_constructible<E>,
		g_is_nothrow_swappable<E>>::value)
    {
      using std::swap;

      if (this->m_has_value && other.m_has_value)
	;
      else if (!this->m_has_value && !other.m_has_value)
	swap (this->m_unex, other.m_unex);
      else if (!this->m_has_value && other.m_has_value)
	other.swap (*this);
      else
	{
	  gcc::construct_at (std::addressof (this->m_unex),
			     std::move (other.m_unex));
	  gcc::destroy_at (std::addressof (other.m_unex));
	  this->m_has_value = false;
	  other.construct_value ();
	}
    }

    template<typename E_ = E>
    friend constexpr
    Constrain_swap<E_>
    swap (expected& x, expected& y) noexcept (noexcept (x.swap (y)))
    { x.swap (y); }

    // [expected.void.monadic]p1
    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, E_ &>
	       > = false>
    constexpr auto
    and_then (F &&f) &
    {
      using U = remove_cvref_t<g_invoke_result_t<F>>;
      static_assert (detail::exp::is_expected_with_error<U, E>::value,
		     "the function passed to std::expected<T, E>::and_then "
		     "must return a std::expected with same error type");
      if (has_value ())
	return gcc::invoke (std::forward<F> (f));
      else
	return U (unexpect, this->m_unex);
    }

    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, const E_ &>
	       > = false>
    constexpr auto
    and_then (F &&f) const &
    {
      using U = remove_cvref_t<g_invoke_result_t<F>>;
      static_assert (detail::exp::is_expected_with_error<U, E>::value,
		     "the function passed to std::expected<T, E>::and_then "
		     "must return a std::expected with same error type");
      if (has_value ())
	return gcc::invoke (std::forward<F> (f));
      else
	return U (unexpect, this->m_unex);
    }

    // [expected.void.monadic]p5
    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, E_ &&>
	       > = false>
    constexpr auto
    and_then (F &&f) &&
    {
      using U = remove_cvref_t<g_invoke_result_t<F>>;
      static_assert (detail::exp::is_expected_with_error<U, E>::value,
		     "the function passed to std::expected<T, E>::and_then "
		     "must return a std::expected with same error type");
      if (has_value ())
	return gcc::invoke (std::forward<F> (f));
      else
	return U (unexpect, std::move (this->m_unex));
    }

    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, const E_ &&>
	       > = false>
    constexpr auto
    and_then (F &&f) const &&
    {
      using U = remove_cvref_t<g_invoke_result_t<F>>;
      static_assert (detail::exp::is_expected_with_error<U, E>::value,
		     "the function passed to std::expected<T, E>::and_then "
		     "must return a std::expected with same error type");
      if (has_value ())
	return gcc::invoke (std::forward<F> (f));
      else
	return U (unexpect, std::move (this->m_unex));
    }

    // [expected.void.monadic]p9
    template<typename F>
    constexpr auto
    or_else (F &&f) &
    {
      using G = remove_cvref_t<g_invoke_result_t<F, decltype (error ())>>;
      static_assert (detail::exp::is_expected_with_value<G, Void>::value,
		     "the function passed to std::expected<T, E>::or_else "
		     "must return a std::expected with same value type");
      if (has_value ())
	return G ();
      else
	return gcc::invoke (std::forward<F> (f), this->m_unex);
    }

    template<typename F>
    constexpr auto
    or_else (F &&f) const &
    {
      using G = remove_cvref_t<g_invoke_result_t<F, decltype (error ())>>;
      static_assert (detail::exp::is_expected_with_value<G, Void>::value,
		     "the function passed to std::expected<T, E>::or_else "
		     "must return a std::expected with same value type");
      if (has_value ())
	return G ();
      else
	return gcc::invoke (std::forward<F> (f), this->m_unex);
    }

    // [expected.void.monadic]p12
    template<typename F>
    constexpr auto
    or_else (F &&f) &&
    {
      using G = remove_cvref_t<g_invoke_result_t<F, decltype (std::move (error ()))>>;
      static_assert (detail::exp::is_expected_with_value<G, Void>::value,
		     "the function passed to std::expected<T, E>::or_else "
		     "must return a std::expected with same value type");
      if (has_value ())
	return G ();
      else
	return gcc::invoke (std::forward<F> (f), std::move (this->m_unex));
    }

    template<typename F>
    constexpr auto
    or_else (F &&f) const &&
    {
      using G = remove_cvref_t<g_invoke_result_t<F, decltype (std::move (error ()))>>;
      static_assert (detail::exp::is_expected_with_value<G, Void>::value,
		     "the function passed to std::expected<T, E>::or_else "
		     "must return a std::expected with same value type");
      if (has_value ())
	return G ();
      else
	return gcc::invoke (std::forward<F> (f), std::move (this->m_unex));
    }

    // [expected.void.monadic]p15
    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, E_ &>
	       > = false>
    constexpr auto
    transform (F &&f) &
    {
      using U = std::remove_cv_t<g_invoke_result_t<F>>;
      using Res = expected<U, E>;
      if (has_value ())
	return Res (detail::exp::in_place_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f));
	});
      else
	return Res (unexpect, this->m_unex);
    }

    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, const E_ &>
	       > = false>
    constexpr auto
    transform (F &&f) const &
    {
      using U = std::remove_cv_t<g_invoke_result_t<F>>;
      using Res = expected<U, E>;
      if (has_value ())
	return Res (detail::exp::in_place_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f));
	});
      else
	return Res (unexpect, this->m_unex);
    }

    // [expected.void.monadic]p19
    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, E_ &&>
	       > = false>
    constexpr auto
    transform (F &&f) &&
    {
      using U = std::remove_cv_t<g_invoke_result_t<F>>;
      using Res = expected<U, E>;
      if (has_value ())
	return Res (detail::exp::in_place_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f));
	});
      else
	return Res (unexpect, std::move (this->m_unex));
    }

    template<typename F,
	     typename E_ = E,
	     G_Requires<
	       std::is_constructible<E_, const E_ &&>
	       > = false>
    constexpr auto
    transform (F &&f) const &&
    {
      using U = std::remove_cv_t<g_invoke_result_t<F>>;
      using Res = expected<U, E>;
      if (has_value ())
	return Res (detail::exp::in_place_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f));
	});
      else
	return Res (unexpect, std::move (this->m_unex));
    }

    // [expected.void.monadic]p23
    template<typename F>
    constexpr auto
    transform_error (F &&f) &
    {
      using G = std::remove_cv_t<g_invoke_result_t<F, decltype (error ())>>;
      using Res = expected<Void, G>;
      if (has_value ())
	return Res ();
      else
	return Res (detail::exp::unexpect_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), this->m_unex);
	});
    }

    template<typename F>
    constexpr auto
    transform_error (F &&f) const &
    {
      using G = std::remove_cv_t<g_invoke_result_t<F, decltype (error ())>>;
      using Res = expected<Void, G>;
      if (has_value ())
	return Res ();
      else
	return Res (detail::exp::unexpect_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), this->m_unex);
	});
    }

    // [expected.void.monadic]p26
    template<typename F>
    constexpr auto
    transform_error (F &&f) &&
    {
      using G = std::remove_cv_t<g_invoke_result_t<F, decltype (std::move (error ()))>>;
      using Res = expected<Void, G>;
      if (has_value ())
	return Res ();
      else
	return Res (detail::exp::unexpect_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), std::move (this->m_unex));
	});
    }

    template<typename F>
    constexpr auto
    transform_error (F &&f) const &&
    {
      using G = std::remove_cv_t<g_invoke_result_t<F, decltype (std::move (error ()))>>;
      using Res = expected<Void, G>;
      if (has_value ())
	return Res ();
      else
	return Res (detail::exp::unexpect_inv{}, [&] () {
	  return gcc::invoke (std::forward<F> (f), std::move (this->m_unex));
	});
    }

    // [expected.void.eq]
    template<typename T2, typename E2,
	     G_Requires<std::is_void<T2>> = false>
    [[nodiscard]] friend constexpr
    eql_return_t<E, E2>
    operator== (const expected &x, const expected<T2, E2> &y)
    {
      if (x.m_has_value && y.m_has_value)
	return true;
      else if (!x.m_has_value && !y.m_has_value)
	return x.m_unex == y.m_unex;
      return false;
    }

    template<typename E2>
    [[nodiscard]] friend constexpr
    eql_return_t<E, E2>
    operator== (const expected &x, const unexpected<E2> &y)
    {
      if (x.m_has_value)
	return false;
      return x.m_unex == y.unex;
    }

  private:
    template<typename Fn>
    explicit constexpr
    expected (detail::exp::in_place_inv, Fn&& fn)
      : storage (detail::exp::in_value)
    { std::forward<Fn> (fn) (); }

    template<typename Fn>
    explicit constexpr
    expected (detail::exp::unexpect_inv tag, Fn&& fn)
      : storage (tag, std::forward<Fn> (fn))
    {}

    template<typename, typename, bool>
    friend struct expected;
  };

  // Inequality operators.
  template<typename T1, typename E1, typename T2, typename E2>
  [[nodiscard]] constexpr eql_return_t<expected<T1, E1>, expected<T2, E2>>
  operator!= (const expected<T1, E1>& x, const expected<T2, E2>& y)
  { return !(x == y); }

  template<typename T1, typename E1, typename T2>
  [[nodiscard]] constexpr eql_return_t<expected<T1, E1>, T2>
  operator!= (const expected<T1, E1>& x, const T2& y)
  { return !(x == y); }

  template<typename T1, typename E1, typename E2>
  [[nodiscard]] constexpr eql_return_t<expected<T1, E1>, unexpected<E2>>
  operator!= (const expected<T1, E1>& x, const unexpected<E2>& y)
  { return !(x == y); }

  template<typename E1, typename E2>
  [[nodiscard]] constexpr eql_return_t<unexpected<E1>, unexpected<E2>>
  operator!= (const unexpected<E1>& x, const unexpected<E2>& y)
  {
    return !(x == y);
  }
} // namespace gcc

#endif // GCC_EXPECTED
