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

// Copyright (C) 2015-2016 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.
 */

//
// 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 <= 201103L
# include <bits/c++14_warning.h>
#else

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

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace experimental
{
inline namespace fundamentals_v2
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#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);
    }

_GLIBCXX_END_NAMESPACE_VERSION
} // 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());
    }
  };

} // namespace std

#endif // __cplusplus <= 201103L

#endif // _GLIBCXX_EXPERIMENTAL_MEMORY
