// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_EXPERIMENTAL_MEMORY
#define _LIBCPP_EXPERIMENTAL_MEMORY

/*
    experimental/memory synopsis

namespace std::experimental::inline fundamentals_v2  {

template <class W> class observer_ptr {
public:
    using element_type = W;
    using pointer = add_pointer_t<W>; // exposition-only
    using reference = add_lvalue_reference_t<W>; // exposition-only

    // default ctor
    constexpr observer_ptr() noexcept;

    // pointer-accepting ctors
    constexpr observer_ptr(nullptr_t) noexcept;
    constexpr explicit observer_ptr(pointer) noexcept;

    // copying ctors (in addition to compiler-generated copy ctor)
    template <class W2> constexpr observer_ptr(observer_ptr<W2>) noexcept;

    // observers
    constexpr pointer get() const noexcept;
    constexpr reference operator*() const;
    constexpr pointer operator->() const noexcept;
    constexpr explicit operator bool() const noexcept;

    // conversions
    constexpr explicit operator pointer() const noexcept;

    // modifiers
    constexpr pointer release() noexcept;
    constexpr void reset(pointer = nullptr) noexcept;
    constexpr void swap(observer_ptr&) noexcept;
};

}
*/

#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#  include <__cxx03/__config>
#else
#  include <__config>
#  include <__cstddef/nullptr_t.h>
#  include <__cstddef/size_t.h>
#  include <__functional/hash.h>
#  include <__functional/operations.h>
#  include <__type_traits/add_pointer.h>
#  include <__type_traits/add_reference.h>
#  include <__type_traits/common_type.h>
#  include <__type_traits/enable_if.h>
#  include <__type_traits/is_convertible.h>
#  include <version>

#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#    pragma GCC system_header
#  endif

#  ifdef _LIBCPP_ENABLE_EXPERIMENTAL

_LIBCPP_BEGIN_NAMESPACE_LFTS_V2

#    if _LIBCPP_STD_VER >= 17

template <class _Wp>
class observer_ptr {
public:
  using element_type = _Wp;

  // constructors
  _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr() noexcept : __ptr_(nullptr) {}
  _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(nullptr_t) noexcept : __ptr_(nullptr) {}
  _LIBCPP_HIDE_FROM_ABI constexpr explicit observer_ptr(element_type* __p) noexcept : __ptr_(__p) {}

  template <class _W2, __enable_if_t<is_convertible<_W2*, _Wp*>::value, int> = 0>
  _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(observer_ptr<_W2> __other) noexcept : __ptr_(__other.get()) {}

  // observers
  _LIBCPP_HIDE_FROM_ABI constexpr element_type* get() const noexcept { return __ptr_; }
  _LIBCPP_HIDE_FROM_ABI constexpr add_lvalue_reference_t<_Wp> operator*() const { return *__ptr_; }
  _LIBCPP_HIDE_FROM_ABI constexpr element_type* operator->() const noexcept { return __ptr_; }
  _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __ptr_ != nullptr; }

  // conversions
  _LIBCPP_HIDE_FROM_ABI constexpr explicit operator element_type*() const noexcept { return __ptr_; }

  // modifiers
  _LIBCPP_HIDE_FROM_ABI constexpr void reset(element_type* __p = nullptr) noexcept { __ptr_ = __p; }
  _LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr& __other) noexcept {
    observer_ptr __tmp = __other;
    __other            = *this;
    *this              = __tmp;
  }
  _LIBCPP_HIDE_FROM_ABI constexpr element_type* release() noexcept {
    observer_ptr __p;
    __p.swap(*this);
    return __p.get();
  }

private:
  element_type* __ptr_;
};

// specializations

template <class _Wp>
_LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr<_Wp>& __a, observer_ptr<_Wp>& __b) noexcept {
  __a.swap(__b);
}

template <class _Wp>
_LIBCPP_HIDE_FROM_ABI observer_ptr<_Wp> make_observer(_Wp* __ptr) noexcept {
  return observer_ptr<_Wp>{__ptr};
}

template <class _W1, class _W2>
_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
  return __a.get() == __b.get();
}

template <class _W1, class _W2>
_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
  return !(__a == __b);
}

template <class _Wp>
_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_Wp> __p, nullptr_t) {
  return !__p;
}

template <class _Wp>
_LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, observer_ptr<_Wp> __p) {
  return !__p;
}

template <class _Wp>
_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_Wp> __p, nullptr_t) {
  return (bool)__p;
}

template <class _Wp>
_LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, observer_ptr<_Wp> __p) {
  return (bool)__p;
}

template <class _W1, class _W2>
_LIBCPP_HIDE_FROM_ABI bool operator<(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
  return std::less<typename std::common_type<_W1*, _W2*>::type>()(__a.get(), __b.get());
}

template <class _W1, class _W2>
_LIBCPP_HIDE_FROM_ABI bool operator>(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
  return __b < __a;
}

template <class _W1, class _W2>
_LIBCPP_HIDE_FROM_ABI bool operator<=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
  return !(__a > __b);
}

template <class _W1, class _W2>
_LIBCPP_HIDE_FROM_ABI bool operator>=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
  return !(__a < __b);
}

#    endif // _LIBCPP_STD_VER >= 17

_LIBCPP_END_NAMESPACE_LFTS_V2

_LIBCPP_BEGIN_NAMESPACE_STD

// hash

#    if _LIBCPP_STD_VER >= 17
template <class _Tp>
struct hash<experimental::observer_ptr<_Tp>> {
  _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::observer_ptr<_Tp>& __ptr) const noexcept {
    return hash<_Tp*>()(__ptr.get());
  }
};
#    endif // _LIBCPP_STD_VER >= 17

_LIBCPP_END_NAMESPACE_STD

#  endif // _LIBCPP_ENABLE_EXPERIMENTAL

#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
#    include <cstddef>
#    include <limits>
#  endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)

#endif /* _LIBCPP_EXPERIMENTAL_MEMORY */
