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