| // -*- 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 | |
| # if _LIBCPP_STD_VER >= 17 | |
| _LIBCPP_BEGIN_NAMESPACE_LFTS_V2 | |
| 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); | |
| } | |
| _LIBCPP_END_NAMESPACE_LFTS_V2 | |
| _LIBCPP_BEGIN_NAMESPACE_STD | |
| // hash | |
| 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()); | |
| } | |
| }; | |
| _LIBCPP_END_NAMESPACE_STD | |
| # endif // _LIBCPP_STD_VER >= 17 | |
| # endif // _LIBCPP_ENABLE_EXPERIMENTAL | |
| #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) | |
| #endif /* _LIBCPP_EXPERIMENTAL_MEMORY */ |