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 <__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 72template <class _Wp> 73class observer_ptr { 74public: 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 107private: 108 element_type* __ptr_; 109}; 110 111// specializations 112 113template <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 118template <class _Wp> 119_LIBCPP_HIDE_FROM_ABI observer_ptr<_Wp> make_observer(_Wp* __ptr) noexcept { 120 return observer_ptr<_Wp>{__ptr}; 121} 122 123template <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 128template <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 133template <class _Wp> 134_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_Wp> __p, nullptr_t) { 135 return !__p; 136} 137 138template <class _Wp> 139_LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, observer_ptr<_Wp> __p) { 140 return !__p; 141} 142 143template <class _Wp> 144_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_Wp> __p, nullptr_t) { 145 return (bool)__p; 146} 147 148template <class _Wp> 149_LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, observer_ptr<_Wp> __p) { 150 return (bool)__p; 151} 152 153template <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 158template <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 163template <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 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 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 182template <class _Tp> 183struct 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 */ 195