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

// Copyright (C) 2013-2020 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 experimental/optional
 *  This is a TS C++ Library header.
 *  @ingroup libfund-ts
 */

#ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL
#define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1

#if __cplusplus >= 201402L

#include <utility>
#include <type_traits>
#include <stdexcept>
#include <new>
#include <initializer_list>
#include <bits/functexcept.h>
#include <bits/functional_hash.h>
#include <bits/enable_special_members.h>
#include <experimental/bits/lfts_config.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

namespace experimental
{
inline namespace fundamentals_v1
{
  /**
   * @defgroup optional Optional values
   * @ingroup libfund-ts
   *
   * Class template for optional values and surrounding facilities, as
   * described in n3793 "A proposal to add a utility class to represent
   * optional objects (Revision 5)".
   *
   * @{
   */

#define __cpp_lib_experimental_optional 201411

  // All subsequent [X.Y.n] references are against n3793.

  // [X.Y.4]
  template<typename _Tp>
    class optional;

  // [X.Y.5]
  /// Tag type for in-place construction.
  struct in_place_t { };

  /// Tag for in-place construction.
  constexpr in_place_t in_place { };

  // [X.Y.6]
  /// 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) { }
  };

  // [X.Y.6]
  /// Tag to disengage optional objects.
  constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token };

  // [X.Y.7]
  /**
   *  @brief Exception class thrown when a disengaged optional object is
   *  dereferenced.
   *  @ingroup exceptions
   */
  class bad_optional_access : public logic_error
  {
  public:
    bad_optional_access() : logic_error("bad optional access") { }

    // XXX This constructor is non-standard. Should not be inline
    explicit bad_optional_access(const char* __arg) : logic_error(__arg) { }

    virtual ~bad_optional_access() noexcept = default;
  };

  /// @cond undocumented

  void
  __throw_bad_optional_access(const char*)
  __attribute__((__noreturn__));

  // XXX Does not belong here.
  inline void
  __throw_bad_optional_access(const char* __s)
  { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); }

  /**
    * @brief Class template that holds the necessary state for @ref optional
    * and that has the responsibility for construction and the special members.
    *
    * Such a separate base class template is necessary in order to
    * conditionally enable the special members (e.g. copy/move constructors).
    * Note that this means that @ref _Optional_base implements the
    * functionality for copy and move assignment, but not for converting
    * assignment.
    *
    * @see optional, _Enable_special_members
    */
  template<typename _Tp, bool _ShouldProvideDestructor =
	   !is_trivially_destructible<_Tp>::value>
    class _Optional_base
    {
    private:
      // Remove const to avoid prohibition of reusing object storage for
      // const-qualified types in [3.8/9]. This is strictly internal
      // and even optional itself is oblivious to it.
      using _Stored_type = remove_const_t<_Tp>;

    public:
      // [X.Y.4.1] Constructors.

      // Constructors for disengaged optionals.
      constexpr _Optional_base() noexcept
      : _M_empty{} { }

      constexpr _Optional_base(nullopt_t) noexcept
      : _Optional_base{} { }

      // Constructors for engaged optionals.
      template<typename... _Args>
        constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
        : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }

      template<typename _Up, typename... _Args,
               enable_if_t<is_constructible<_Tp,
                                            initializer_list<_Up>&,
                                            _Args&&...>::value,
                           int>...>
        constexpr explicit _Optional_base(in_place_t,
                                          initializer_list<_Up> __il,
                                          _Args&&... __args)
        : _M_payload(__il, std::forward<_Args>(__args)...),
          _M_engaged(true) { }

      // Copy and move constructors.
      _Optional_base(const _Optional_base& __other)
      {
        if (__other._M_engaged)
          this->_M_construct(__other._M_get());
      }

      _Optional_base(_Optional_base&& __other)
      noexcept(is_nothrow_move_constructible<_Tp>())
      {
        if (__other._M_engaged)
          this->_M_construct(std::move(__other._M_get()));
      }

      // [X.Y.4.3] (partly) Assignment.
      _Optional_base&
      operator=(const _Optional_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();
	  }

        return *this;
      }

      _Optional_base&
      operator=(_Optional_base&& __other)
      noexcept(__and_<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();
	  }
	return *this;
      }

      // [X.Y.4.2] Destructor.
      ~_Optional_base()
      {
        if (this->_M_engaged)
          this->_M_payload.~_Stored_type();
      }

      // The following functionality is also needed by optional, hence the
      // protected accessibility.
    protected:
      constexpr bool _M_is_engaged() const noexcept
      { return this->_M_engaged; }

      // The _M_get operations have _M_engaged as a precondition.
      constexpr _Tp&
      _M_get() noexcept
      { return _M_payload; }

      constexpr const _Tp&
      _M_get() const noexcept
      { return _M_payload; }

      // The _M_construct operation has !_M_engaged as a precondition
      // while _M_destruct has _M_engaged as a precondition.
      template<typename... _Args>
        void
        _M_construct(_Args&&... __args)
        noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
        {
          ::new (std::__addressof(this->_M_payload))
            _Stored_type(std::forward<_Args>(__args)...);
          this->_M_engaged = true;
        }

      void
      _M_destruct()
      {
        this->_M_engaged = false;
        this->_M_payload.~_Stored_type();
      }

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

    private:
      struct _Empty_byte { };
      union {
          _Empty_byte _M_empty;
          _Stored_type _M_payload;
      };
      bool _M_engaged = false;
    };

  /// Partial specialization that is exactly identical to the primary template
  /// save for not providing a destructor, to fulfill triviality requirements.
  template<typename _Tp>
    class _Optional_base<_Tp, false>
    {
    private:
      using _Stored_type = remove_const_t<_Tp>;

    public:
      constexpr _Optional_base() noexcept
      : _M_empty{} { }

      constexpr _Optional_base(nullopt_t) noexcept
      : _Optional_base{} { }

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

      template<typename _Up, typename... _Args,
               enable_if_t<is_constructible<_Tp,
                                            initializer_list<_Up>&,
                                            _Args&&...>::value,
			   int>...>
        constexpr explicit _Optional_base(in_place_t,
                                          initializer_list<_Up> __il,
                                          _Args&&... __args)
        : _M_payload(__il, std::forward<_Args>(__args)...),
          _M_engaged(true) { }

      _Optional_base(const _Optional_base& __other)
      {
        if (__other._M_engaged)
          this->_M_construct(__other._M_get());
      }

      _Optional_base(_Optional_base&& __other)
      noexcept(is_nothrow_move_constructible<_Tp>())
      {
        if (__other._M_engaged)
          this->_M_construct(std::move(__other._M_get()));
      }

      _Optional_base&
      operator=(const _Optional_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();
	  }
	return *this;
      }

      _Optional_base&
      operator=(_Optional_base&& __other)
      noexcept(__and_<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();
	  }
	return *this;
      }

      // Sole difference
      // ~_Optional_base() noexcept = default;

    protected:
      constexpr bool _M_is_engaged() const noexcept
      { return this->_M_engaged; }

      _Tp&
      _M_get() noexcept
      { return _M_payload; }

      constexpr const _Tp&
      _M_get() const noexcept
      { return _M_payload; }

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

      void
      _M_destruct()
      {
        this->_M_engaged = false;
        this->_M_payload.~_Stored_type();
      }

      void
      _M_reset()
      {
        if (this->_M_engaged)
          this->_M_destruct();
      }

    private:
      struct _Empty_byte { };
      union
      {
	_Empty_byte _M_empty;
	_Stored_type _M_payload;
      };
      bool _M_engaged = false;
    };

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

  /// @endcond

  /**
    * @brief Class template for optional values.
    */
  template<typename _Tp>
    class optional
    : private _Optional_base<_Tp>,
      private _Enable_copy_move<
        // Copy constructor.
        is_copy_constructible<_Tp>::value,
        // Copy assignment.
        __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
        // Move constructor.
        is_move_constructible<_Tp>::value,
        // Move assignment.
        __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
        // Unique tag type.
        optional<_Tp>>
    {
      static_assert(__and_<__not_<is_same<remove_cv_t<_Tp>, nullopt_t>>,
			   __not_<is_same<remove_cv_t<_Tp>, in_place_t>>,
			   __not_<is_reference<_Tp>>>(),
                    "Invalid instantiation of optional<T>");

    private:
      using _Base = _Optional_base<_Tp>;

    public:
      using value_type = _Tp;

      // _Optional_base has the responsibility for construction.
      using _Base::_Base;

      constexpr optional() = default;
      // Converting constructors for engaged optionals.
      template <typename _Up = _Tp,
                enable_if_t<__and_<
			      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
			      is_constructible<_Tp, _Up&&>,
			      is_convertible<_Up&&, _Tp>
			      >::value, bool> = true>
      constexpr optional(_Up&& __t)
        : _Base(in_place, std::forward<_Up>(__t)) { }

      template <typename _Up = _Tp,
                enable_if_t<__and_<
			      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
			      is_constructible<_Tp, _Up&&>,
			      __not_<is_convertible<_Up&&, _Tp>>
			      >::value, bool> = false>
      explicit constexpr optional(_Up&& __t)
        : _Base(in_place, std::forward<_Up>(__t)) { }

      template <typename _Up,
                enable_if_t<__and_<
			    __not_<is_same<_Tp, _Up>>,
			    is_constructible<_Tp, const _Up&>,
			    is_convertible<const _Up&, _Tp>,
			    __not_<__converts_from_optional<_Tp, _Up>>
			    >::value, bool> = true>
      constexpr optional(const optional<_Up>& __t)
      {
	if (__t)
	  emplace(*__t);
      }

      template <typename _Up,
                 enable_if_t<__and_<
			       __not_<is_same<_Tp, _Up>>,
			       is_constructible<_Tp, const _Up&>,
			       __not_<is_convertible<const _Up&, _Tp>>,
			       __not_<__converts_from_optional<_Tp, _Up>>
			       >::value, bool> = false>
      explicit constexpr optional(const optional<_Up>& __t)
      {
	if (__t)
	  emplace(*__t);
      }

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

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

      // [X.Y.4.3] (partly) Assignment.
      optional&
      operator=(nullopt_t) noexcept
      {
        this->_M_reset();
        return *this;
      }

      template<typename _Up = _Tp>
        enable_if_t<__and_<
		      __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
		      is_constructible<_Tp, _Up>,
		      __not_<__and_<is_scalar<_Tp>,
				    is_same<_Tp, decay_t<_Up>>>>,
		      is_assignable<_Tp&, _Up>>::value,
		    optional&>
        operator=(_Up&& __u)
        {
          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>
	enable_if_t<__and_<
		      __not_<is_same<_Tp, _Up>>,
		      is_constructible<_Tp, const _Up&>,
		      is_assignable<_Tp&, _Up>,
		      __not_<__converts_from_optional<_Tp, _Up>>,
		      __not_<__assigns_from_optional<_Tp, _Up>>
		      >::value,
		    optional&>
        operator=(const optional<_Up>& __u)
        {
          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>
	enable_if_t<__and_<
		      __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>>
		      >::value,
		    optional&>
        operator=(optional<_Up>&& __u)
        {
          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>
	enable_if_t<is_constructible<_Tp, _Args&&...>::value>
	emplace(_Args&&... __args)
	{
	  this->_M_reset();
	  this->_M_construct(std::forward<_Args>(__args)...);
	}

      template<typename _Up, typename... _Args>
	enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
				     _Args&&...>::value>
	emplace(initializer_list<_Up> __il, _Args&&... __args)
	{
	  this->_M_reset();
	  this->_M_construct(__il, std::forward<_Args>(__args)...);
	}

      // [X.Y.4.2] Destructor is implicit, implemented in _Optional_base.

      // [X.Y.4.4] Swap.
      void
      swap(optional& __other)
      noexcept(is_nothrow_move_constructible<_Tp>()
               && __is_nothrow_swappable<_Tp>::value)
      {
        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();
	  }
      }

      // [X.Y.4.5] Observers.
      constexpr const _Tp*
      operator->() const
      { return std::__addressof(this->_M_get()); }

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

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

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

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

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

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

      constexpr const _Tp&
      value() const&
      {
	return this->_M_is_engaged()
	  ?  this->_M_get()
	  : (__throw_bad_optional_access("Attempt to access value of a "
		                         "disengaged optional object"),
	     this->_M_get());
      }

      constexpr _Tp&
      value()&
      {
	return this->_M_is_engaged()
	  ?  this->_M_get()
	  : (__throw_bad_optional_access("Attempt to access value of a "
		                         "disengaged optional object"),
	     this->_M_get());
      }

      constexpr _Tp&&
      value()&&
      {
	return this->_M_is_engaged()
	  ?  std::move(this->_M_get())
	  : (__throw_bad_optional_access("Attempt to access value of a "
		                         "disengaged optional object"),
	     std::move(this->_M_get()));
      }

      constexpr const _Tp&&
      value() const&&
      {
	return this->_M_is_engaged()
	  ?  std::move(this->_M_get())
	  : (__throw_bad_optional_access("Attempt to access value of a "
		                         "disengaged optional object"),
	     std::move(this->_M_get()));
      }

      template<typename _Up>
	constexpr _Tp
	value_or(_Up&& __u) const&
	{
	  static_assert(__and_<is_copy_constructible<_Tp>,
			       is_convertible<_Up&&, _Tp>>(),
			"Cannot return value");

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

      template<typename _Up>
	_Tp
	value_or(_Up&& __u) &&
	{
	  static_assert(__and_<is_move_constructible<_Tp>,
			       is_convertible<_Up&&, _Tp>>(),
			"Cannot return value" );

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

  /// @relates experimental::optional @{

  // [X.Y.8] Comparisons between optional values.
  template<typename _Tp>
    constexpr bool
    operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
    {
      return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
	     && (!__lhs || *__lhs == *__rhs);
    }

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

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

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

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

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

  // [X.Y.9] Comparisons with nullopt.
  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 !__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; }

  // [X.Y.10] Comparisons with value type.
  template<typename _Tp>
    constexpr bool
    operator==(const optional<_Tp>& __lhs, const _Tp& __rhs)
    { return __lhs && *__lhs == __rhs; }

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

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

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

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

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

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

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

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

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

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

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

  // [X.Y.11]
  template<typename _Tp>
    inline void
    swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
    noexcept(noexcept(__lhs.swap(__rhs)))
    { __lhs.swap(__rhs); }

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

  // @} relates experimental::optional
  // @} group optional
} // namespace fundamentals_v1
} // namespace experimental

  // [X.Y.12]
  /// std::hash partial specialization for experimental::optional
  /// @relates experimental::optional
  template<typename _Tp>
    struct hash<experimental::optional<_Tp>>
    {
      using result_type = size_t;
      using argument_type = experimental::optional<_Tp>;

      size_t
      operator()(const experimental::optional<_Tp>& __t) const
      noexcept(noexcept(hash<_Tp> {}(*__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<_Tp> {}(*__t) : __magic_disengaged_hash;
      }
    };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++14

#endif // _GLIBCXX_EXPERIMENTAL_OPTIONAL
