|
| 1 | +// -*- C++ -*- |
| 2 | +//===----------------------------------------------------------------------===// |
| 3 | +// |
| 4 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 5 | +// See https://llvm.org/LICENSE.txt for license information. |
| 6 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 7 | +// |
| 8 | +//===----------------------------------------------------------------------===// |
| 9 | + |
| 10 | +#ifndef _LIBCPP_EXPERIMENTAL_MEMORY |
| 11 | +#define _LIBCPP_EXPERIMENTAL_MEMORY |
| 12 | + |
| 13 | +/* |
| 14 | + experimental/memory synopsis |
| 15 | +
|
| 16 | +namespace std::experimental::inline fundamentals_v2 { |
| 17 | +
|
| 18 | +template <class W> class observer_ptr { |
| 19 | +public: |
| 20 | + using element_type = W; |
| 21 | + using pointer = add_pointer_t<W>; // exposition-only |
| 22 | + using reference = add_lvalue_reference_t<W>; // exposition-only |
| 23 | +
|
| 24 | + // default ctor |
| 25 | + constexpr observer_ptr() noexcept; |
| 26 | +
|
| 27 | + // pointer-accepting ctors |
| 28 | + constexpr observer_ptr(nullptr_t) noexcept; |
| 29 | + constexpr explicit observer_ptr(pointer) noexcept; |
| 30 | +
|
| 31 | + // copying ctors (in addition to compiler-generated copy ctor) |
| 32 | + template <class W2> constexpr observer_ptr(observer_ptr<W2>) noexcept; |
| 33 | +
|
| 34 | + // observers |
| 35 | + constexpr pointer get() const noexcept; |
| 36 | + constexpr reference operator*() const; |
| 37 | + constexpr pointer operator->() const noexcept; |
| 38 | + constexpr explicit operator bool() const noexcept; |
| 39 | +
|
| 40 | + // conversions |
| 41 | + constexpr explicit operator pointer() const noexcept; |
| 42 | +
|
| 43 | + // modifiers |
| 44 | + constexpr pointer release() noexcept; |
| 45 | + constexpr void reset(pointer = nullptr) noexcept; |
| 46 | + constexpr void swap(observer_ptr&) noexcept; |
| 47 | +}; |
| 48 | +
|
| 49 | +} |
| 50 | +*/ |
| 51 | + |
| 52 | +#include <__functional/hash.h> |
| 53 | +#include <__functional/operations.h> |
| 54 | +#include <__type_traits/add_lvalue_reference.h> |
| 55 | +#include <__type_traits/add_pointer.h> |
| 56 | +#include <__type_traits/common_type.h> |
| 57 | +#include <__type_traits/enable_if.h> |
| 58 | +#include <__type_traits/is_convertible.h> |
| 59 | +#include <cstddef> |
| 60 | +#include <experimental/__config> |
| 61 | + |
| 62 | +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 63 | +# pragma GCC system_header |
| 64 | +#endif |
| 65 | + |
| 66 | +#ifdef _LIBCPP_ENABLE_EXPERIMENTAL |
| 67 | + |
| 68 | +_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 |
| 69 | + |
| 70 | +# if _LIBCPP_STD_VER >= 17 |
| 71 | + |
| 72 | +template <class _Wp> |
| 73 | +class observer_ptr { |
| 74 | +public: |
| 75 | + using element_type = _Wp; |
| 76 | + |
| 77 | + // constructors |
| 78 | + _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr() noexcept : __ptr_(nullptr) {} |
| 79 | + _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(nullptr_t) noexcept : __ptr_(nullptr) {} |
| 80 | + _LIBCPP_HIDE_FROM_ABI constexpr explicit observer_ptr(element_type* __p) noexcept : __ptr_(__p) {} |
| 81 | + |
| 82 | + template <class _W2, class = __enable_if_t<is_convertible<_W2*, _Wp*>::value>> |
| 83 | + _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(observer_ptr<_W2> __other) noexcept : __ptr_(__other.get()) {} |
| 84 | + |
| 85 | + // observers |
| 86 | + _LIBCPP_HIDE_FROM_ABI constexpr element_type* get() const noexcept { return __ptr_; } |
| 87 | + _LIBCPP_HIDE_FROM_ABI constexpr add_lvalue_reference_t<_Wp> operator*() const { return *__ptr_; } |
| 88 | + _LIBCPP_HIDE_FROM_ABI constexpr element_type* operator->() const noexcept { return __ptr_; } |
| 89 | + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __ptr_ != nullptr; } |
| 90 | + |
| 91 | + // conversions |
| 92 | + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator element_type*() const noexcept { return __ptr_; } |
| 93 | + |
| 94 | + // modifiers |
| 95 | + _LIBCPP_HIDE_FROM_ABI constexpr void reset(element_type* __p = nullptr) noexcept { __ptr_ = __p; } |
| 96 | + _LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr& __other) noexcept { |
| 97 | + observer_ptr __tmp = __other; |
| 98 | + __other = *this; |
| 99 | + *this = __tmp; |
| 100 | + } |
| 101 | + _LIBCPP_HIDE_FROM_ABI constexpr element_type* release() noexcept { |
| 102 | + observer_ptr __p; |
| 103 | + __p.swap(*this); |
| 104 | + return __p.get(); |
| 105 | + } |
| 106 | + |
| 107 | +private: |
| 108 | + element_type* __ptr_; |
| 109 | +}; |
| 110 | + |
| 111 | +// specializations |
| 112 | + |
| 113 | +template <class _Wp> |
| 114 | +_LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr<_Wp>& __a, observer_ptr<_Wp>& __b) noexcept { |
| 115 | + __a.swap(__b); |
| 116 | +} |
| 117 | + |
| 118 | +template <class _Wp> |
| 119 | +_LIBCPP_HIDE_FROM_ABI observer_ptr<_Wp> make_observer(_Wp* __ptr) noexcept { |
| 120 | + return observer_ptr<_Wp>{__ptr}; |
| 121 | +} |
| 122 | + |
| 123 | +template <class _W1, class _W2> |
| 124 | +_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { |
| 125 | + return __a.get() == __b.get(); |
| 126 | +} |
| 127 | + |
| 128 | +template <class _W1, class _W2> |
| 129 | +_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { |
| 130 | + return !(__a == __b); |
| 131 | +} |
| 132 | + |
| 133 | +template <class _Wp> |
| 134 | +_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_Wp> __p, nullptr_t) { |
| 135 | + return !__p; |
| 136 | +} |
| 137 | + |
| 138 | +template <class _Wp> |
| 139 | +_LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, observer_ptr<_Wp> __p) { |
| 140 | + return !__p; |
| 141 | +} |
| 142 | + |
| 143 | +template <class _Wp> |
| 144 | +_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_Wp> __p, nullptr_t) { |
| 145 | + return (bool)__p; |
| 146 | +} |
| 147 | + |
| 148 | +template <class _Wp> |
| 149 | +_LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, observer_ptr<_Wp> __p) { |
| 150 | + return (bool)__p; |
| 151 | +} |
| 152 | + |
| 153 | +template <class _W1, class _W2> |
| 154 | +_LIBCPP_HIDE_FROM_ABI bool operator<(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { |
| 155 | + return std::less<typename std::common_type<_W1*, _W2*>::type>()(__a.get(), __b.get()); |
| 156 | +} |
| 157 | + |
| 158 | +template <class _W1, class _W2> |
| 159 | +_LIBCPP_HIDE_FROM_ABI bool operator>(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { |
| 160 | + return __b < __a; |
| 161 | +} |
| 162 | + |
| 163 | +template <class _W1, class _W2> |
| 164 | +_LIBCPP_HIDE_FROM_ABI bool operator<=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { |
| 165 | + return !(__a > __b); |
| 166 | +} |
| 167 | + |
| 168 | +template <class _W1, class _W2> |
| 169 | +_LIBCPP_HIDE_FROM_ABI bool operator>=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { |
| 170 | + return !(__a < __b); |
| 171 | +} |
| 172 | + |
| 173 | +# endif // _LIBCPP_STD_VER >= 17 |
| 174 | + |
| 175 | +_LIBCPP_END_NAMESPACE_LFTS_V2 |
| 176 | + |
| 177 | +_LIBCPP_BEGIN_NAMESPACE_STD |
| 178 | + |
| 179 | +// hash |
| 180 | + |
| 181 | +# if _LIBCPP_STD_VER >= 17 |
| 182 | +template <class _Tp> |
| 183 | +struct hash<experimental::observer_ptr<_Tp>> { |
| 184 | + _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::observer_ptr<_Tp>& __ptr) const noexcept { |
| 185 | + return hash<_Tp*>()(__ptr.get()); |
| 186 | + } |
| 187 | +}; |
| 188 | +# endif // _LIBCPP_STD_VER >= 17 |
| 189 | + |
| 190 | +_LIBCPP_END_NAMESPACE_STD |
| 191 | + |
| 192 | +#endif // _LIBCPP_ENABLE_EXPERIMENTAL |
| 193 | + |
| 194 | +#endif /* _LIBCPP_EXPERIMENTAL_MEMORY */ |
0 commit comments