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 16namespace std::experimental::inline fundamentals_v2 { 17 18template <class W> class observer_ptr { 19public: 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#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) 53# include <__cxx03/experimental/memory> 54#else 55# include <__config> 56# include <__cstddef/nullptr_t.h> 57# include <__cstddef/size_t.h> 58# include <__functional/hash.h> 59# include <__functional/operations.h> 60# include <__type_traits/add_lvalue_reference.h> 61# include <__type_traits/add_pointer.h> 62# include <__type_traits/common_type.h> 63# include <__type_traits/enable_if.h> 64# include <__type_traits/is_convertible.h> 65# include <version> 66 67# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 68# pragma GCC system_header 69# endif 70 71# ifdef _LIBCPP_ENABLE_EXPERIMENTAL 72 73_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 74 75# if _LIBCPP_STD_VER >= 17 76 77template <class _Wp> 78class observer_ptr { 79public: 80 using element_type = _Wp; 81 82 // constructors 83 _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr() noexcept : __ptr_(nullptr) {} 84 _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(nullptr_t) noexcept : __ptr_(nullptr) {} 85 _LIBCPP_HIDE_FROM_ABI constexpr explicit observer_ptr(element_type* __p) noexcept : __ptr_(__p) {} 86 87 template <class _W2, __enable_if_t<is_convertible<_W2*, _Wp*>::value, int> = 0> 88 _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(observer_ptr<_W2> __other) noexcept : __ptr_(__other.get()) {} 89 90 // observers 91 _LIBCPP_HIDE_FROM_ABI constexpr element_type* get() const noexcept { return __ptr_; } 92 _LIBCPP_HIDE_FROM_ABI constexpr add_lvalue_reference_t<_Wp> operator*() const { return *__ptr_; } 93 _LIBCPP_HIDE_FROM_ABI constexpr element_type* operator->() const noexcept { return __ptr_; } 94 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __ptr_ != nullptr; } 95 96 // conversions 97 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator element_type*() const noexcept { return __ptr_; } 98 99 // modifiers 100 _LIBCPP_HIDE_FROM_ABI constexpr void reset(element_type* __p = nullptr) noexcept { __ptr_ = __p; } 101 _LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr& __other) noexcept { 102 observer_ptr __tmp = __other; 103 __other = *this; 104 *this = __tmp; 105 } 106 _LIBCPP_HIDE_FROM_ABI constexpr element_type* release() noexcept { 107 observer_ptr __p; 108 __p.swap(*this); 109 return __p.get(); 110 } 111 112private: 113 element_type* __ptr_; 114}; 115 116// specializations 117 118template <class _Wp> 119_LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr<_Wp>& __a, observer_ptr<_Wp>& __b) noexcept { 120 __a.swap(__b); 121} 122 123template <class _Wp> 124_LIBCPP_HIDE_FROM_ABI observer_ptr<_Wp> make_observer(_Wp* __ptr) noexcept { 125 return observer_ptr<_Wp>{__ptr}; 126} 127 128template <class _W1, class _W2> 129_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 130 return __a.get() == __b.get(); 131} 132 133template <class _W1, class _W2> 134_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 135 return !(__a == __b); 136} 137 138template <class _Wp> 139_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_Wp> __p, nullptr_t) { 140 return !__p; 141} 142 143template <class _Wp> 144_LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, observer_ptr<_Wp> __p) { 145 return !__p; 146} 147 148template <class _Wp> 149_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_Wp> __p, nullptr_t) { 150 return (bool)__p; 151} 152 153template <class _Wp> 154_LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, observer_ptr<_Wp> __p) { 155 return (bool)__p; 156} 157 158template <class _W1, class _W2> 159_LIBCPP_HIDE_FROM_ABI bool operator<(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 160 return std::less<typename std::common_type<_W1*, _W2*>::type>()(__a.get(), __b.get()); 161} 162 163template <class _W1, class _W2> 164_LIBCPP_HIDE_FROM_ABI bool operator>(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 165 return __b < __a; 166} 167 168template <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 173template <class _W1, class _W2> 174_LIBCPP_HIDE_FROM_ABI bool operator>=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 175 return !(__a < __b); 176} 177 178# endif // _LIBCPP_STD_VER >= 17 179 180_LIBCPP_END_NAMESPACE_LFTS_V2 181 182_LIBCPP_BEGIN_NAMESPACE_STD 183 184// hash 185 186# if _LIBCPP_STD_VER >= 17 187template <class _Tp> 188struct hash<experimental::observer_ptr<_Tp>> { 189 _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::observer_ptr<_Tp>& __ptr) const noexcept { 190 return hash<_Tp*>()(__ptr.get()); 191 } 192}; 193# endif // _LIBCPP_STD_VER >= 17 194 195_LIBCPP_END_NAMESPACE_STD 196 197# endif // _LIBCPP_ENABLE_EXPERIMENTAL 198 199# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 200# include <cstddef> 201# include <limits> 202# endif 203#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) 204 205#endif /* _LIBCPP_EXPERIMENTAL_MEMORY */ 206