// <optional> -*- C++ -*-

// Copyright (C) 2013-2021 Free Software Foundation, Inc.
//
// 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/optional
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_OPTIONAL
#define _GLIBCXX_OPTIONAL 1

#pragma GCC system_header

#if __cplusplus >= 201703L

#include <type_traits>
#include <exception>
#include <new>
#include <initializer_list>
#include <bits/enable_special_members.h>
#include <bits/exception_defines.h>
#include <bits/functional_hash.h>
#include <bits/stl_construct.h> // _Construct
#include <bits/utility.h> // in_place_t
#if __cplusplus > 201703L
# include <compare>
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   *  @addtogroup utilities
   *  @{
   */

#if __cplusplus == 201703L
# define __cpp_lib_optional 201606L
#else
# define __cpp_lib_optional 202106L
#endif

  template<typename _Tp>
    class optional;

  /// Tag type to disengage optional objects.
  struct nullopt_t
  {
    // Do not user-declare default constructor at all for
    // optional_value = {} syntax to work.
    // nullopt_t() = delete;

    // Used for constructing nullopt.
    enum class _Construct { _Token };

    // Must be constexpr for nullopt_t to be literal.
    explicit constexpr nullopt_t(_Construct) noexcept { }
  };

  /// Tag to disengage optional objects.
  inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };

  /**
   *  @brief Exception class thrown when a disengaged optional object is
   *  dereferenced.
   *  @ingroup exceptions
   */
  class bad_optional_access : public exception
  {
  public:
    bad_optional_access() = default;
    virtual ~bad_optional_access() = default;

    const char* what() const noexcept override
    { return "bad optional access"; }
  };

  // XXX Does not belong here.
  [[__noreturn__]] inline void
  __throw_bad_optional_access()
  { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); }

  // This class template manages construction/destruction of
  // the contained value for a std::optional.
  template <typename _Tp>
    struct _Optional_payload_base
    {
      using _Stored_type = remove_const_t<_Tp>;

      _Optional_payload_base() = default;
      ~_Optional_payload_base() = default;

      template<typename... _Args>
	constexpr
	_Optional_payload_base(in_place_t __tag, _Args&&... __args)
	: _M_payload(__tag, std::forward<_Args>(__args)...),
	  _M_engaged(true)
	{ }

      template<typename _Up, typename... _Args>
	constexpr
	_Optional_payload_base(std::initializer_list<_Up> __il,
			       _Args&&... __args)
	: _M_payload(__il, std::forward<_Args>(__args)...),
	  _M_engaged(true)
	{ }

      // Constructor used by _Optional_base copy constructor when the
      // contained value is not trivially copy constructible.
      constexpr
      _Optional_payload_base(bool __engaged,
			     const _Optional_payload_base& __other)
      {
	if (__other._M_engaged)
	  this->_M_construct(__other._M_get());
      }

      // Constructor used by _Optional_base move constructor when the
      // contained value is not trivially move constructible.
      constexpr
      _Optional_payload_base(bool __engaged,
			     _Optional_payload_base&& __other)
      {
	if (__other._M_engaged)
	  this->_M_construct(std::move(__other._M_get()));
      }

      // Copy constructor is only used to when the contained value is
      // trivially copy constructible.
      _Optional_payload_base(const _Optional_payload_base&) = default;

      // Move constructor is only used to when the contained value is
      // trivially copy constructible.
      _Optional_payload_base(_Optional_payload_base&&) = default;

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

      _Optional_payload_base&
      operator=(_Optional_payload_base&&) = default;

      // used to perform non-trivial copy assignment.
      constexpr void
      _M_copy_assign(const _Optional_payload_base& __other)
      {
	if (this->_M_engaged && __other._M_engaged)
	  this->_M_get() = __other._M_get();
	else
	  {
	    if (__other._M_engaged)
	      this->_M_construct(__other._M_get());
	    else
	      this->_M_reset();
	  }
      }

      // used to perform non-trivial move assignment.
      constexpr void
      _M_move_assign(_Optional_payload_base&& __other)
      noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
		       is_nothrow_move_assignable<_Tp>>)
      {
	if (this->_M_engaged && __other._M_engaged)
	  this->_M_get() = std::move(__other._M_get());
	else
	  {
	    if (__other._M_engaged)
	      this->_M_construct(std::move(__other._M_get()));
	    else
	      this->_M_reset();
	  }
      }

      struct _Empty_byte { };

      template<typename _Up, bool = is_trivially_destructible_v<_Up>>
	union _Storage
	{
	  constexpr _Storage() noexcept : _M_empty() { }

	  template<typename... _Args>
	    constexpr
	    _Storage(in_place_t, _Args&&... __args)
	    : _M_value(std::forward<_Args>(__args)...)
	    { }

	  template<typename _Vp, typename... _Args>
	    constexpr
	    _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
	    : _M_value(__il, std::forward<_Args>(__args)...)
	    { }

	  _Empty_byte _M_empty;
	  _Up _M_value;
	};

      template<typename _Up>
	union _Storage<_Up, false>
	{
	  constexpr _Storage() noexcept : _M_empty() { }

	  template<typename... _Args>
	    constexpr
	    _Storage(in_place_t, _Args&&... __args)
	    : _M_value(std::forward<_Args>(__args)...)
	    { }

	  template<typename _Vp, typename... _Args>
	    constexpr
	    _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)
	    : _M_value(__il, std::forward<_Args>(__args)...)
	    { }

	  // User-provided destructor is needed when _Up has non-trivial dtor.
	  _GLIBCXX20_CONSTEXPR ~_Storage() { }

	  _Empty_byte _M_empty;
	  _Up _M_value;
	};

      _Storage<_Stored_type> _M_payload;

      bool _M_engaged = false;

      template<typename... _Args>
	constexpr void
	_M_construct(_Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
	{
	  std::_Construct(std::__addressof(this->_M_payload._M_value),
			  std::forward<_Args>(__args)...);
	  this->_M_engaged = true;
	}

      constexpr void
      _M_destroy() noexcept
      {
	_M_engaged = false;
	_M_payload._M_value.~_Stored_type();
      }

      // The _M_get() operations have _M_engaged as a precondition.
      // They exist to access the contained value with the appropriate
      // const-qualification, because _M_payload has had the const removed.

      constexpr _Tp&
      _M_get() noexcept
      { return this->_M_payload._M_value; }

      constexpr const _Tp&
      _M_get() const noexcept
      { return this->_M_payload._M_value; }

      // _M_reset is a 'safe' operation with no precondition.
      constexpr void
      _M_reset() noexcept
      {
	if (this->_M_engaged)
	  _M_destroy();
      }
    };

  // Class template that manages the payload for optionals.
  template <typename _Tp,
	    bool /*_HasTrivialDestructor*/ =
	      is_trivially_destructible_v<_Tp>,
	    bool /*_HasTrivialCopy */ =
	      is_trivially_copy_assignable_v<_Tp>
	      && is_trivially_copy_constructible_v<_Tp>,
	    bool /*_HasTrivialMove */ =
	      is_trivially_move_assignable_v<_Tp>
	      && is_trivially_move_constructible_v<_Tp>>
    struct _Optional_payload;

  // Payload for potentially-constexpr optionals (trivial copy/move/destroy).
  template <typename _Tp>
    struct _Optional_payload<_Tp, true, true, true>
    : _Optional_payload_base<_Tp>
    {
      using _Optional_payload_base<_Tp>::_Optional_payload_base;

      _Optional_payload() = default;
    };

  // Payload for optionals with non-trivial copy construction/assignment.
  template <typename _Tp>
    struct _Optional_payload<_Tp, true, false, true>
    : _Optional_payload_base<_Tp>
    {
      using _Optional_payload_base<_Tp>::_Optional_payload_base;

      _Optional_payload() = default;
      ~_Optional_payload() = default;
      _Optional_payload(const _Optional_payload&) = default;
      _Optional_payload(_Optional_payload&&) = default;
      _Optional_payload& operator=(_Optional_payload&&) = default;

      // Non-trivial copy assignment.
      constexpr
      _Optional_payload&
      operator=(const _Optional_payload& __other)
      {
	this->_M_copy_assign(__other);
	return *this;
      }
    };

  // Payload for optionals with non-trivial move construction/assignment.
  template <typename _Tp>
    struct _Optional_payload<_Tp, true, true, false>
    : _Optional_payload_base<_Tp>
    {
      using _Optional_payload_base<_Tp>::_Optional_payload_base;

      _Optional_payload() = default;
      ~_Optional_payload() = default;
      _Optional_payload(const _Optional_payload&) = default;
      _Optional_payload(_Optional_payload&&) = default;
      _Optional_payload& operator=(const _Optional_payload&) = default;

      // Non-trivial move assignment.
      constexpr
      _Optional_payload&
      operator=(_Optional_payload&& __other)
      noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
		       is_nothrow_move_assignable<_Tp>>)
      {
	this->_M_move_assign(std::move(__other));
	return *this;
      }
    };

  // Payload for optionals with non-trivial copy and move assignment.
  template <typename _Tp>
    struct _Optional_payload<_Tp, true, false, false>
    : _Optional_payload_base<_Tp>
    {
      using _Optional_payload_base<_Tp>::_Optional_payload_base;

      _Optional_payload() = default;
      ~_Optional_payload() = default;
      _Optional_payload(const _Optional_payload&) = default;
      _Optional_payload(_Optional_payload&&) = default;

      // Non-trivial copy assignment.
      constexpr
      _Optional_payload&
      operator=(const _Optional_payload& __other)
      {
	this->_M_copy_assign(__other);
	return *this;
      }

      // Non-trivial move assignment.
      constexpr
      _Optional_payload&
      operator=(_Optional_payload&& __other)
      noexcept(__and_v<is_nothrow_move_constructible<_Tp>,
		       is_nothrow_move_assignable<_Tp>>)
      {
	this->_M_move_assign(std::move(__other));
	return *this;
      }
    };

  // Payload for optionals with non-trivial destructors.
  template <typename _Tp, bool _Copy, bool _Move>
    struct _Optional_payload<_Tp, false, _Copy, _Move>
    : _Optional_payload<_Tp, true, false, false>
    {
      // Base class implements all the constructors and assignment operators:
      using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
      _Optional_payload() = default;
      _Optional_payload(const _Optional_payload&) = default;
      _Optional_payload(_Optional_payload&&) = default;
      _Optional_payload& operator=(const _Optional_payload&) = default;
      _Optional_payload& operator=(_Optional_payload&&) = default;

      // Destructor needs to destroy the contained value:
      _GLIBCXX20_CONSTEXPR ~_Optional_payload() { this->_M_reset(); }
    };

  // Common base class for _Optional_base<T> to avoid repeating these
  // member functions in each specialization.
  template<typename _Tp, typename _Dp>
    class _Optional_base_impl
    {
    protected:
      using _Stored_type = remove_const_t<_Tp>;

      // The _M_construct operation has !_M_engaged as a precondition
      // while _M_destruct has _M_engaged as a precondition.
      template<typename... _Args>
	constexpr void
	_M_construct(_Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
	{
	  static_cast<_Dp*>(this)->_M_payload._M_construct(
	    std::forward<_Args>(__args)...);
	}

      constexpr void
      _M_destruct() noexcept
      { static_cast<_Dp*>(this)->_M_payload._M_destroy(); }

      // _M_reset is a 'safe' operation with no precondition.
      constexpr void
      _M_reset() noexcept
      { static_cast<_Dp*>(this)->_M_payload._M_reset(); }

      constexpr bool _M_is_engaged() const noexcept
      { return static_cast<const _Dp*>(this)->_M_payload._M_engaged; }

      // The _M_get operations have _M_engaged as a precondition.
      constexpr _Tp&
      _M_get() noexcept
      {
	__glibcxx_assert(this->_M_is_engaged());
	return static_cast<_Dp*>(this)->_M_payload._M_get();
      }

      constexpr const _Tp&
      _M_get() const noexcept
      {
	__glibcxx_assert(this->_M_is_engaged());
	return static_cast<const _Dp*>(this)->_M_payload._M_get();
      }
    };

  /**
    * @brief Class template that provides copy/move constructors of optional.
    *
    * Such a separate base class template is necessary in order to
    * conditionally make copy/move constructors trivial.
    *
    * When the contained value is trivially copy/move constructible,
    * the copy/move constructors of _Optional_base will invoke the
    * trivial copy/move constructor of _Optional_payload. Otherwise,
    * they will invoke _Optional_payload(bool, const _Optional_payload&)
    * or _Optional_payload(bool, _Optional_payload&&) to initialize
    * the contained value, if copying/moving an engaged optional.
    *
    * Whether the other special members are trivial is determined by the
    * _Optional_payload<_Tp> specialization used for the _M_payload member.
    *
    * @see optional, _Enable_special_members
    */
  template<typename _Tp,
	   bool = is_trivially_copy_constructible_v<_Tp>,
	   bool = is_trivially_move_constructible_v<_Tp>>
    struct _Optional_base
    : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
    {
      // Constructors for disengaged optionals.
      constexpr _Optional_base() = default;

      // Constructors for engaged optionals.
      template<typename... _Args,
	       enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
	constexpr explicit
	_Optional_base(in_place_t, _Args&&... __args)
	: _M_payload(in_place, std::forward<_Args>(__args)...)
	{ }

      template<typename _Up, typename... _Args,
	       enable_if_t<is_constructible_v<_Tp,
					      initializer_list<_Up>&,
					      _Args...>, bool> = false>
	constexpr explicit
	_Optional_base(in_place_t,
		       initializer_list<_Up> __il,
		       _Args&&... __args)
	: _M_payload(in_place, __il, std::forward<_Args>(__args)...)
	{ }

      // Copy and move constructors.
      constexpr
      _Optional_base(const _Optional_base& __other)
      : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
      { }

      constexpr
      _Optional_base(_Optional_base&& __other)
      noexcept(is_nothrow_move_constructible_v<_Tp>)
      : _M_payload(__other._M_payload._M_engaged,
		   std::move(__other._M_payload))
      { }

      // Assignment operators.
      _Optional_base& operator=(const _Optional_base&) = default;
      _Optional_base& operator=(_Optional_base&&) = default;

      _Optional_payload<_Tp> _M_payload;
    };

  template<typename _Tp>
    struct _Optional_base<_Tp, false, true>
    : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
    {
      // Constructors for disengaged optionals.
      constexpr _Optional_base() = default;

      // Constructors for engaged optionals.
      template<typename... _Args,
	       enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
	constexpr explicit
	_Optional_base(in_place_t, _Args&&... __args)
	: _M_payload(in_place, std::forward<_Args>(__args)...)
	{ }

      template<typename _Up, typename... _Args,
	       enable_if_t<is_constructible_v<_Tp,
					      initializer_list<_Up>&,
					      _Args...>, bool> = false>
	constexpr explicit
	_Optional_base(in_place_t,
		       initializer_list<_Up> __il,
		       _Args... __args)
	: _M_payload(in_place, __il, std::forward<_Args>(__args)...)
	{ }

      // Copy and move constructors.
      constexpr _Optional_base(const _Optional_base& __other)
      : _M_payload(__other._M_payload._M_engaged, __other._M_payload)
      { }

      constexpr _Optional_base(_Optional_base&& __other) = default;

      // Assignment operators.
      _Optional_base& operator=(const _Optional_base&) = default;
      _Optional_base& operator=(_Optional_base&&) = default;

      _Optional_payload<_Tp> _M_payload;
    };

  template<typename _Tp>
    struct _Optional_base<_Tp, true, false>
    : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
    {
      // Constructors for disengaged optionals.
      constexpr _Optional_base() = default;

      // Constructors for engaged optionals.
      template<typename... _Args,
	       enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
	constexpr explicit
	_Optional_base(in_place_t, _Args&&... __args)
	: _M_payload(in_place, std::forward<_Args>(__args)...)
	{ }

      template<typename _Up, typename... _Args,
	       enable_if_t<is_constructible_v<_Tp,
					      initializer_list<_Up>&,
					      _Args...>, bool> = false>
	constexpr explicit
	_Optional_base(in_place_t,
		       initializer_list<_Up> __il,
		       _Args&&... __args)
	: _M_payload(in_place, __il, std::forward<_Args>(__args)...)
	{ }

      // Copy and move constructors.
      constexpr _Optional_base(const _Optional_base& __other) = default;

      constexpr
      _Optional_base(_Optional_base&& __other)
      noexcept(is_nothrow_move_constructible_v<_Tp>)
      : _M_payload(__other._M_payload._M_engaged,
		   std::move(__other._M_payload))
      { }

      // Assignment operators.
      _Optional_base& operator=(const _Optional_base&) = default;
      _Optional_base& operator=(_Optional_base&&) = default;

      _Optional_payload<_Tp> _M_payload;
    };

  template<typename _Tp>
    struct _Optional_base<_Tp, true, true>
    : _Optional_base_impl<_Tp, _Optional_base<_Tp>>
    {
      // Constructors for disengaged optionals.
      constexpr _Optional_base() = default;

      // Constructors for engaged optionals.
      template<typename... _Args,
	       enable_if_t<is_constructible_v<_Tp, _Args...>, bool> = false>
	constexpr explicit
	_Optional_base(in_place_t, _Args&&... __args)
	: _M_payload(in_place, std::forward<_Args>(__args)...)
	{ }

      template<typename _Up, typename... _Args,
	       enable_if_t<is_constructible_v<_Tp,
					      initializer_list<_Up>&,
					      _Args...>, bool> = false>
	constexpr explicit
	_Optional_base(in_place_t,
		       initializer_list<_Up> __il,
		       _Args&&... __args)
	: _M_payload(in_place, __il, std::forward<_Args>(__args)...)
	{ }

      // Copy and move constructors.
      constexpr _Optional_base(const _Optional_base& __other) = default;
      constexpr _Optional_base(_Optional_base&& __other) = default;

      // Assignment operators.
      _Optional_base& operator=(const _Optional_base&) = default;
      _Optional_base& operator=(_Optional_base&&) = default;

      _Optional_payload<_Tp> _M_payload;
    };

  template<typename _Tp>
  class optional;

  template<typename _Tp, typename _Up>
    using __converts_from_optional =
      __or_<is_constructible<_Tp, const optional<_Up>&>,
	    is_constructible<_Tp, optional<_Up>&>,
	    is_constructible<_Tp, const optional<_Up>&&>,
	    is_constructible<_Tp, optional<_Up>&&>,
	    is_convertible<const optional<_Up>&, _Tp>,
	    is_convertible<optional<_Up>&, _Tp>,
	    is_convertible<const optional<_Up>&&, _Tp>,
	    is_convertible<optional<_Up>&&, _Tp>>;

  template<typename _Tp, typename _Up>
    using __assigns_from_optional =
      __or_<is_assignable<_Tp&, const optional<_Up>&>,
	    is_assignable<_Tp&, optional<_Up>&>,
	    is_assignable<_Tp&, const optional<_Up>&&>,
	    is_assignable<_Tp&, optional<_Up>&&>>;

  /**
    * @brief Class template for optional values.
    */
  template<typename _Tp>
    class optional
    : private _Optional_base<_Tp>,
      private _Enable_copy_move<
	// Copy constructor.
	is_copy_constructible_v<_Tp>,
	// Copy assignment.
	__and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
	// Move constructor.
	is_move_constructible_v<_Tp>,
	// Move assignment.
	__and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
	// Unique tag type.
	optional<_Tp>>
    {
      static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
      static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
      static_assert(!is_reference_v<_Tp>);

    private:
      using _Base = _Optional_base<_Tp>;

      // SFINAE helpers
      template<typename _Up>
	using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
      template<typename _Up>
	using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
      template<typename... _Cond>
	using _Requires = enable_if_t<__and_v<_Cond...>, bool>;

    public:
      using value_type = _Tp;

      constexpr optional() noexcept { }

      constexpr optional(nullopt_t) noexcept { }

      // Converting constructors for engaged optionals.
      template<typename _Up = _Tp,
	       _Requires<__not_self<_Up>, __not_tag<_Up>,
			 is_constructible<_Tp, _Up>,
			 is_convertible<_Up, _Tp>> = true>
	constexpr
	optional(_Up&& __t)
	noexcept(is_nothrow_constructible_v<_Tp, _Up>)
	: _Base(std::in_place, std::forward<_Up>(__t)) { }

      template<typename _Up = _Tp,
	       _Requires<__not_self<_Up>, __not_tag<_Up>,
			 is_constructible<_Tp, _Up>,
			 __not_<is_convertible<_Up, _Tp>>> = false>
	explicit constexpr
	optional(_Up&& __t)
	noexcept(is_nothrow_constructible_v<_Tp, _Up>)
	: _Base(std::in_place, std::forward<_Up>(__t)) { }

      template<typename _Up,
	       _Requires<__not_<is_same<_Tp, _Up>>,
			 is_constructible<_Tp, const _Up&>,
			 is_convertible<const _Up&, _Tp>,
			 __not_<__converts_from_optional<_Tp, _Up>>> = true>
	constexpr
	optional(const optional<_Up>& __t)
	noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
	{
	  if (__t)
	    emplace(*__t);
	}

      template<typename _Up,
	       _Requires<__not_<is_same<_Tp, _Up>>,
			 is_constructible<_Tp, const _Up&>,
			 __not_<is_convertible<const _Up&, _Tp>>,
			 __not_<__converts_from_optional<_Tp, _Up>>> = false>
	explicit constexpr
	optional(const optional<_Up>& __t)
	noexcept(is_nothrow_constructible_v<_Tp, const _Up&>)
	{
	  if (__t)
	    emplace(*__t);
	}

      template<typename _Up,
	       _Requires<__not_<is_same<_Tp, _Up>>,
			 is_constructible<_Tp, _Up>,
			 is_convertible<_Up, _Tp>,
			 __not_<__converts_from_optional<_Tp, _Up>>> = true>
	constexpr
	optional(optional<_Up>&& __t)
	noexcept(is_nothrow_constructible_v<_Tp, _Up>)
	{
	  if (__t)
	    emplace(std::move(*__t));
	}

      template<typename _Up,
	       _Requires<__not_<is_same<_Tp, _Up>>,
			 is_constructible<_Tp, _Up>,
			 __not_<is_convertible<_Up, _Tp>>,
			 __not_<__converts_from_optional<_Tp, _Up>>> = false>
	explicit constexpr
	optional(optional<_Up>&& __t)
	noexcept(is_nothrow_constructible_v<_Tp, _Up>)
	{
	  if (__t)
	    emplace(std::move(*__t));
	}

      template<typename... _Args,
	       _Requires<is_constructible<_Tp, _Args...>> = false>
	explicit constexpr
	optional(in_place_t, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
	: _Base(std::in_place, std::forward<_Args>(__args)...) { }

      template<typename _Up, typename... _Args,
	       _Requires<is_constructible<_Tp,
					  initializer_list<_Up>&,
					  _Args...>> = false>
	explicit constexpr
	optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
					    _Args...>)
	: _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }


      // Assignment operators.
      _GLIBCXX20_CONSTEXPR optional&
      operator=(nullopt_t) noexcept
      {
	this->_M_reset();
	return *this;
      }

      template<typename _Up = _Tp>
	_GLIBCXX20_CONSTEXPR
	enable_if_t<__and_v<__not_self<_Up>,
			    __not_<__and_<is_scalar<_Tp>,
					  is_same<_Tp, decay_t<_Up>>>>,
			    is_constructible<_Tp, _Up>,
			    is_assignable<_Tp&, _Up>>,
		    optional&>
	operator=(_Up&& __u)
	noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
			 is_nothrow_assignable<_Tp&, _Up>>)
	{
	  if (this->_M_is_engaged())
	    this->_M_get() = std::forward<_Up>(__u);
	  else
	    this->_M_construct(std::forward<_Up>(__u));

	  return *this;
	}

      template<typename _Up>
	_GLIBCXX20_CONSTEXPR
	enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
			    is_constructible<_Tp, const _Up&>,
			    is_assignable<_Tp&, const _Up&>,
			    __not_<__converts_from_optional<_Tp, _Up>>,
			    __not_<__assigns_from_optional<_Tp, _Up>>>,
		    optional&>
	operator=(const optional<_Up>& __u)
	noexcept(__and_v<is_nothrow_constructible<_Tp, const _Up&>,
			 is_nothrow_assignable<_Tp&, const _Up&>>)
	{
	  if (__u)
	    {
	      if (this->_M_is_engaged())
		this->_M_get() = *__u;
	      else
		this->_M_construct(*__u);
	    }
	  else
	    {
	      this->_M_reset();
	    }
	  return *this;
	}

      template<typename _Up>
	_GLIBCXX20_CONSTEXPR
	enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
			    is_constructible<_Tp, _Up>,
			    is_assignable<_Tp&, _Up>,
			    __not_<__converts_from_optional<_Tp, _Up>>,
			    __not_<__assigns_from_optional<_Tp, _Up>>>,
		    optional&>
	operator=(optional<_Up>&& __u)
	noexcept(__and_v<is_nothrow_constructible<_Tp, _Up>,
			 is_nothrow_assignable<_Tp&, _Up>>)
	{
	  if (__u)
	    {
	      if (this->_M_is_engaged())
		this->_M_get() = std::move(*__u);
	      else
		this->_M_construct(std::move(*__u));
	    }
	  else
	    {
	      this->_M_reset();
	    }

	  return *this;
	}

      template<typename... _Args>
	_GLIBCXX20_CONSTEXPR
	enable_if_t<is_constructible_v<_Tp, _Args...>, _Tp&>
	emplace(_Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
	{
	  this->_M_reset();
	  this->_M_construct(std::forward<_Args>(__args)...);
	  return this->_M_get();
	}

      template<typename _Up, typename... _Args>
	_GLIBCXX20_CONSTEXPR
	enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
		    _Tp&>
	emplace(initializer_list<_Up> __il, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
					    _Args...>)
	{
	  this->_M_reset();
	  this->_M_construct(__il, std::forward<_Args>(__args)...);
	  return this->_M_get();
	}

      // Destructor is implicit, implemented in _Optional_base.

      // Swap.
      _GLIBCXX20_CONSTEXPR void
      swap(optional& __other)
      noexcept(is_nothrow_move_constructible_v<_Tp>
	       && is_nothrow_swappable_v<_Tp>)
      {
	using std::swap;

	if (this->_M_is_engaged() && __other._M_is_engaged())
	  swap(this->_M_get(), __other._M_get());
	else if (this->_M_is_engaged())
	  {
	    __other._M_construct(std::move(this->_M_get()));
	    this->_M_destruct();
	  }
	else if (__other._M_is_engaged())
	  {
	    this->_M_construct(std::move(__other._M_get()));
	    __other._M_destruct();
	  }
      }

      // Observers.
      constexpr const _Tp*
      operator->() const noexcept
      { return std::__addressof(this->_M_get()); }

      constexpr _Tp*
      operator->() noexcept
      { return std::__addressof(this->_M_get()); }

      constexpr const _Tp&
      operator*() const& noexcept
      { return this->_M_get(); }

      constexpr _Tp&
      operator*()& noexcept
      { return this->_M_get(); }

      constexpr _Tp&&
      operator*()&& noexcept
      { return std::move(this->_M_get()); }

      constexpr const _Tp&&
      operator*() const&& noexcept
      { return std::move(this->_M_get()); }

      constexpr explicit operator bool() const noexcept
      { return this->_M_is_engaged(); }

      constexpr bool has_value() const noexcept
      { return this->_M_is_engaged(); }

      constexpr const _Tp&
      value() const&
      {
	if (this->_M_is_engaged())
	  return this->_M_get();
	__throw_bad_optional_access();
      }

      constexpr _Tp&
      value()&
      {
	if (this->_M_is_engaged())
	  return this->_M_get();
	__throw_bad_optional_access();
      }

      constexpr _Tp&&
      value()&&
      {
	if (this->_M_is_engaged())
	  return std::move(this->_M_get());
	__throw_bad_optional_access();
      }

      constexpr const _Tp&&
      value() const&&
      {
	if (this->_M_is_engaged())
	  return std::move(this->_M_get());
	__throw_bad_optional_access();
      }

      template<typename _Up>
	constexpr _Tp
	value_or(_Up&& __u) const&
	{
	  static_assert(is_copy_constructible_v<_Tp>);
	  static_assert(is_convertible_v<_Up&&, _Tp>);

	  if (this->_M_is_engaged())
	    return this->_M_get();
	  else
	    return static_cast<_Tp>(std::forward<_Up>(__u));
	}

      template<typename _Up>
	constexpr _Tp
	value_or(_Up&& __u) &&
	{
	  static_assert(is_move_constructible_v<_Tp>);
	  static_assert(is_convertible_v<_Up&&, _Tp>);

	  if (this->_M_is_engaged())
	    return std::move(this->_M_get());
	  else
	    return static_cast<_Tp>(std::forward<_Up>(__u));
	}

      _GLIBCXX20_CONSTEXPR void reset() noexcept { this->_M_reset(); }
    };

  template<typename _Tp>
    using __optional_relop_t =
      enable_if_t<is_convertible<_Tp, bool>::value, bool>;

  template<typename _Tp, typename _Up>
    using __optional_eq_t = __optional_relop_t<
      decltype(std::declval<const _Tp&>() == std::declval<const _Up&>())
      >;

  template<typename _Tp, typename _Up>
    using __optional_ne_t = __optional_relop_t<
      decltype(std::declval<const _Tp&>() != std::declval<const _Up&>())
      >;

  template<typename _Tp, typename _Up>
    using __optional_lt_t = __optional_relop_t<
      decltype(std::declval<const _Tp&>() < std::declval<const _Up&>())
      >;

  template<typename _Tp, typename _Up>
    using __optional_gt_t = __optional_relop_t<
      decltype(std::declval<const _Tp&>() > std::declval<const _Up&>())
      >;

  template<typename _Tp, typename _Up>
    using __optional_le_t = __optional_relop_t<
      decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>())
      >;

  template<typename _Tp, typename _Up>
    using __optional_ge_t = __optional_relop_t<
      decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>())
      >;

  // Comparisons between optional values.
  template<typename _Tp, typename _Up>
    constexpr auto
    operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    -> __optional_eq_t<_Tp, _Up>
    {
      return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
	     && (!__lhs || *__lhs == *__rhs);
    }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    -> __optional_ne_t<_Tp, _Up>
    {
      return static_cast<bool>(__lhs) != static_cast<bool>(__rhs)
	|| (static_cast<bool>(__lhs) && *__lhs != *__rhs);
    }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    -> __optional_lt_t<_Tp, _Up>
    {
      return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
    }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    -> __optional_gt_t<_Tp, _Up>
    {
      return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
    }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    -> __optional_le_t<_Tp, _Up>
    {
      return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
    }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs)
    -> __optional_ge_t<_Tp, _Up>
    {
      return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
    }

#ifdef __cpp_lib_three_way_comparison
  template<typename _Tp, three_way_comparable_with<_Tp> _Up>
    constexpr compare_three_way_result_t<_Tp, _Up>
    operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y)
    {
      return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
    }
#endif

  // Comparisons with nullopt.
  template<typename _Tp>
    constexpr bool
    operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept
    { return !__lhs; }

#ifdef __cpp_lib_three_way_comparison
  template<typename _Tp>
    constexpr strong_ordering
    operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept
    { return bool(__x) <=> false; }
#else
  template<typename _Tp>
    constexpr bool
    operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept
    { return !__rhs; }

  template<typename _Tp>
    constexpr bool
    operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept
    { return static_cast<bool>(__lhs); }

  template<typename _Tp>
    constexpr bool
    operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept
    { return static_cast<bool>(__rhs); }

  template<typename _Tp>
    constexpr bool
    operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
    { return false; }

  template<typename _Tp>
    constexpr bool
    operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept
    { return static_cast<bool>(__rhs); }

  template<typename _Tp>
    constexpr bool
    operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept
    { return static_cast<bool>(__lhs); }

  template<typename _Tp>
    constexpr bool
    operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
    { return false; }

  template<typename _Tp>
    constexpr bool
    operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept
    { return !__lhs; }

  template<typename _Tp>
    constexpr bool
    operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept
    { return true; }

  template<typename _Tp>
    constexpr bool
    operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept
    { return true; }

  template<typename _Tp>
    constexpr bool
    operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept
    { return !__rhs; }
#endif // three-way-comparison

  // Comparisons with value type.
  template<typename _Tp, typename _Up>
    constexpr auto
    operator==(const optional<_Tp>& __lhs, const _Up& __rhs)
    -> __optional_eq_t<_Tp, _Up>
    { return __lhs && *__lhs == __rhs; }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator==(const _Up& __lhs, const optional<_Tp>& __rhs)
    -> __optional_eq_t<_Up, _Tp>
    { return __rhs && __lhs == *__rhs; }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator!=(const optional<_Tp>& __lhs, const _Up& __rhs)
    -> __optional_ne_t<_Tp, _Up>
    { return !__lhs || *__lhs != __rhs; }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator!=(const _Up& __lhs, const optional<_Tp>& __rhs)
    -> __optional_ne_t<_Up, _Tp>
    { return !__rhs || __lhs != *__rhs; }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator<(const optional<_Tp>& __lhs, const _Up& __rhs)
    -> __optional_lt_t<_Tp, _Up>
    { return !__lhs || *__lhs < __rhs; }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
    -> __optional_lt_t<_Up, _Tp>
    { return __rhs && __lhs < *__rhs; }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator>(const optional<_Tp>& __lhs, const _Up& __rhs)
    -> __optional_gt_t<_Tp, _Up>
    { return __lhs && *__lhs > __rhs; }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator>(const _Up& __lhs, const optional<_Tp>& __rhs)
    -> __optional_gt_t<_Up, _Tp>
    { return !__rhs || __lhs > *__rhs; }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator<=(const optional<_Tp>& __lhs, const _Up& __rhs)
    -> __optional_le_t<_Tp, _Up>
    { return !__lhs || *__lhs <= __rhs; }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator<=(const _Up& __lhs, const optional<_Tp>& __rhs)
    -> __optional_le_t<_Up, _Tp>
    { return __rhs && __lhs <= *__rhs; }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator>=(const optional<_Tp>& __lhs, const _Up& __rhs)
    -> __optional_ge_t<_Tp, _Up>
    { return __lhs && *__lhs >= __rhs; }

  template<typename _Tp, typename _Up>
    constexpr auto
    operator>=(const _Up& __lhs, const optional<_Tp>& __rhs)
    -> __optional_ge_t<_Up, _Tp>
    { return !__rhs || __lhs >= *__rhs; }

#ifdef __cpp_lib_three_way_comparison
  template<typename _Tp>
    inline constexpr bool __is_optional_v = false;
  template<typename _Tp>
    inline constexpr bool __is_optional_v<optional<_Tp>> = true;

  template<typename _Tp, typename _Up>
    requires (!__is_optional_v<_Up>)
      && three_way_comparable_with<_Tp, _Up>
    constexpr compare_three_way_result_t<_Tp, _Up>
    operator<=>(const optional<_Tp>& __x, const _Up& __v)
    { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
#endif

  // Swap and creation functions.

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 2748. swappable traits for optionals
  template<typename _Tp>
    _GLIBCXX20_CONSTEXPR
    inline enable_if_t<is_move_constructible_v<_Tp> && is_swappable_v<_Tp>>
    swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
    noexcept(noexcept(__lhs.swap(__rhs)))
    { __lhs.swap(__rhs); }

  template<typename _Tp>
    enable_if_t<!(is_move_constructible_v<_Tp> && is_swappable_v<_Tp>)>
    swap(optional<_Tp>&, optional<_Tp>&) = delete;

  template<typename _Tp>
    constexpr
    enable_if_t<is_constructible_v<decay_t<_Tp>, _Tp>,
		optional<decay_t<_Tp>>>
    make_optional(_Tp&& __t)
    noexcept(is_nothrow_constructible_v<optional<decay_t<_Tp>>, _Tp>)
    { return optional<decay_t<_Tp>>{ std::forward<_Tp>(__t) }; }

  template<typename _Tp, typename... _Args>
    constexpr
    enable_if_t<is_constructible_v<_Tp, _Args...>,
		optional<_Tp>>
    make_optional(_Args&&... __args)
    noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
    { return optional<_Tp>{ in_place, std::forward<_Args>(__args)... }; }

  template<typename _Tp, typename _Up, typename... _Args>
    constexpr
    enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
		optional<_Tp>>
    make_optional(initializer_list<_Up> __il, _Args&&... __args)
    noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
    { return optional<_Tp>{ in_place, __il, std::forward<_Args>(__args)... }; }

  // Hash.

  template<typename _Tp, typename _Up = remove_const_t<_Tp>,
	   bool = __poison_hash<_Up>::__enable_hash_call>
    struct __optional_hash_call_base
    {
      size_t
      operator()(const optional<_Tp>& __t) const
      noexcept(noexcept(hash<_Up>{}(*__t)))
      {
	// We pick an arbitrary hash for disengaged optionals which hopefully
	// usual values of _Tp won't typically hash to.
	constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
	return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
      }
    };

  template<typename _Tp, typename _Up>
    struct __optional_hash_call_base<_Tp, _Up, false> {};

  template<typename _Tp>
    struct hash<optional<_Tp>>
    : private __poison_hash<remove_const_t<_Tp>>,
      public __optional_hash_call_base<_Tp>
    {
      using result_type [[__deprecated__]] = size_t;
      using argument_type [[__deprecated__]] = optional<_Tp>;
    };

  template<typename _Tp>
    struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
    { };

  /// @}

#if __cpp_deduction_guides >= 201606
  template <typename _Tp> optional(_Tp) -> optional<_Tp>;
#endif

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++17

#endif // _GLIBCXX_OPTIONAL
