// <experimental/memory> -*- C++ -*-

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

//
// N4336 Working Draft, C++ Extensions for Library Fundamentals, Version 2
//

#ifndef _GLIBCXX_EXPERIMENTAL_MEMORY
#define _GLIBCXX_EXPERIMENTAL_MEMORY 1

#pragma GCC system_header

#if __cplusplus >= 201402L

#include <memory>
#include <type_traits>
#include <experimental/bits/shared_ptr.h>
#include <bits/functional_hash.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

namespace experimental
{
inline namespace fundamentals_v2
{
#define __cpp_lib_experimental_observer_ptr 201411

  template <typename _Tp>
    class observer_ptr
    {
    public:
      // publish our template parameter and variations thereof
      using element_type = _Tp;
      using __pointer = add_pointer_t<_Tp>;            // exposition-only
      using __reference = add_lvalue_reference_t<_Tp>; // exposition-only

      // 3.2.2, observer_ptr constructors
      // default c'tor
      constexpr observer_ptr() noexcept
      : __t()
      { }

      // pointer-accepting c'tors
      constexpr observer_ptr(nullptr_t) noexcept
      : __t()
      { }

      constexpr explicit observer_ptr(__pointer __p) noexcept
      : __t(__p)
      { }

      // copying c'tors (in addition to compiler-generated copy c'tor)
      template <typename _Up,
		typename = typename enable_if<
		  is_convertible<typename add_pointer<_Up>::type, __pointer
		  >::value
		>::type>
      constexpr observer_ptr(observer_ptr<_Up> __p) noexcept
      : __t(__p.get())
      {
      }

      // 3.2.3, observer_ptr observers
      constexpr __pointer
      get() const noexcept
      {
	return __t;
      }

      constexpr __reference
      operator*() const
      {
	return *get();
      }

      constexpr __pointer
      operator->() const noexcept
      {
	return get();
      }

      constexpr explicit operator bool() const noexcept
      {
	return get() != nullptr;
      }

      // 3.2.4, observer_ptr conversions
      constexpr explicit operator __pointer() const noexcept
      {
	return get();
      }

      // 3.2.5, observer_ptr modifiers
      constexpr __pointer
      release() noexcept
      {
	__pointer __tmp = get();
	reset();
	return __tmp;
      }

      constexpr void
      reset(__pointer __p = nullptr) noexcept
      {
	__t = __p;
      }

      constexpr void
      swap(observer_ptr& __p) noexcept
      {
	std::swap(__t, __p.__t);
      }

    private:
      __pointer __t;
    }; // observer_ptr<>

  template<typename _Tp>
    void
    swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept
    {
      __p1.swap(__p2);
    }

  template<typename _Tp>
    observer_ptr<_Tp>
    make_observer(_Tp* __p) noexcept
    {
      return observer_ptr<_Tp>(__p);
    }

  template<typename _Tp, typename _Up>
    bool
    operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
    {
      return __p1.get() == __p2.get();
    }

  template<typename _Tp, typename _Up>
    bool
    operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
    {
    return !(__p1 == __p2);
    }

  template<typename _Tp>
    bool
    operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept
    {
      return !__p;
    }

  template<typename _Tp>
    bool
    operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept
    {
      return !__p;
    }

  template<typename _Tp>
    bool
    operator!=(observer_ptr<_Tp> __p, nullptr_t) noexcept
    {
      return bool(__p);
    }

  template<typename _Tp>
    bool
    operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept
    {
      return bool(__p);
    }

  template<typename _Tp, typename _Up>
    bool
    operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
    {
      return std::less<typename common_type<typename add_pointer<_Tp>::type,
					    typename add_pointer<_Up>::type
					    >::type
		       >{}(__p1.get(), __p2.get());
    }

  template<typename _Tp, typename _Up>
    bool
    operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
    {
      return __p2 < __p1;
    }

  template<typename _Tp, typename _Up>
    bool
    operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
    {
      return !(__p2 < __p1);
    }

  template<typename _Tp, typename _Up>
    bool
    operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
    {
      return !(__p1 < __p2);
    }
} // namespace fundamentals_v2
} // namespace experimental

template <typename _Tp>
  struct hash<experimental::observer_ptr<_Tp>>
  {
    using result_type = size_t;
    using argument_type = experimental::observer_ptr<_Tp>;

    size_t
    operator()(const experimental::observer_ptr<_Tp>& __t) const
    noexcept(noexcept(hash<typename add_pointer<_Tp>::type> {}(__t.get())))
    {
      return hash<typename add_pointer<_Tp>::type> {}(__t.get());
    }
  };


_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // __cplusplus <= 201103L

#endif // _GLIBCXX_EXPERIMENTAL_MEMORY
