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