1 // <experimental/memory> -*- C++ -*- 2 3 // Copyright (C) 2015-2022 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file experimental/memory 26 * This is a TS C++ Library header. 27 * @ingroup libfund-ts 28 */ 29 30 // 31 // N4336 Working Draft, C++ Extensions for Library Fundamentals, Version 2 32 // 33 34 #ifndef _GLIBCXX_EXPERIMENTAL_MEMORY 35 #define _GLIBCXX_EXPERIMENTAL_MEMORY 1 36 37 #pragma GCC system_header 38 39 #if __cplusplus >= 201402L 40 41 #include <memory> 42 #include <type_traits> 43 #include <experimental/bits/shared_ptr.h> 44 #include <bits/functional_hash.h> 45 46 namespace std _GLIBCXX_VISIBILITY(default) 47 { 48 _GLIBCXX_BEGIN_NAMESPACE_VERSION 49 50 namespace experimental 51 { 52 inline namespace fundamentals_v2 53 { 54 #define __cpp_lib_experimental_observer_ptr 201411 55 56 template <typename _Tp> 57 class observer_ptr 58 { 59 public: 60 // publish our template parameter and variations thereof 61 using element_type = _Tp; 62 using __pointer = add_pointer_t<_Tp>; // exposition-only 63 using __reference = add_lvalue_reference_t<_Tp>; // exposition-only 64 65 // 3.2.2, observer_ptr constructors 66 // default c'tor 67 constexpr observer_ptr() noexcept 68 : __t() 69 { } 70 71 // pointer-accepting c'tors 72 constexpr observer_ptr(nullptr_t) noexcept 73 : __t() 74 { } 75 76 constexpr explicit observer_ptr(__pointer __p) noexcept 77 : __t(__p) 78 { } 79 80 // copying c'tors (in addition to compiler-generated copy c'tor) 81 template <typename _Up, 82 typename = typename enable_if< 83 is_convertible<typename add_pointer<_Up>::type, __pointer 84 >::value 85 >::type> 86 constexpr observer_ptr(observer_ptr<_Up> __p) noexcept 87 : __t(__p.get()) 88 { 89 } 90 91 // 3.2.3, observer_ptr observers 92 constexpr __pointer 93 get() const noexcept 94 { 95 return __t; 96 } 97 98 constexpr __reference 99 operator*() const 100 { 101 return *get(); 102 } 103 104 constexpr __pointer 105 operator->() const noexcept 106 { 107 return get(); 108 } 109 110 constexpr explicit operator bool() const noexcept 111 { 112 return get() != nullptr; 113 } 114 115 // 3.2.4, observer_ptr conversions 116 constexpr explicit operator __pointer() const noexcept 117 { 118 return get(); 119 } 120 121 // 3.2.5, observer_ptr modifiers 122 constexpr __pointer 123 release() noexcept 124 { 125 __pointer __tmp = get(); 126 reset(); 127 return __tmp; 128 } 129 130 constexpr void 131 reset(__pointer __p = nullptr) noexcept 132 { 133 __t = __p; 134 } 135 136 constexpr void 137 swap(observer_ptr& __p) noexcept 138 { 139 std::swap(__t, __p.__t); 140 } 141 142 private: 143 __pointer __t; 144 }; // observer_ptr<> 145 146 template<typename _Tp> 147 void 148 swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept 149 { 150 __p1.swap(__p2); 151 } 152 153 template<typename _Tp> 154 observer_ptr<_Tp> 155 make_observer(_Tp* __p) noexcept 156 { 157 return observer_ptr<_Tp>(__p); 158 } 159 160 template<typename _Tp, typename _Up> 161 bool 162 operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 163 { 164 return __p1.get() == __p2.get(); 165 } 166 167 template<typename _Tp, typename _Up> 168 bool 169 operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 170 { 171 return !(__p1 == __p2); 172 } 173 174 template<typename _Tp> 175 bool 176 operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept 177 { 178 return !__p; 179 } 180 181 template<typename _Tp> 182 bool 183 operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept 184 { 185 return !__p; 186 } 187 188 template<typename _Tp> 189 bool 190 operator!=(observer_ptr<_Tp> __p, nullptr_t) noexcept 191 { 192 return bool(__p); 193 } 194 195 template<typename _Tp> 196 bool 197 operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept 198 { 199 return bool(__p); 200 } 201 202 template<typename _Tp, typename _Up> 203 bool 204 operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 205 { 206 return std::less<typename common_type<typename add_pointer<_Tp>::type, 207 typename add_pointer<_Up>::type 208 >::type 209 >{}(__p1.get(), __p2.get()); 210 } 211 212 template<typename _Tp, typename _Up> 213 bool 214 operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 215 { 216 return __p2 < __p1; 217 } 218 219 template<typename _Tp, typename _Up> 220 bool 221 operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 222 { 223 return !(__p2 < __p1); 224 } 225 226 template<typename _Tp, typename _Up> 227 bool 228 operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 229 { 230 return !(__p1 < __p2); 231 } 232 } // namespace fundamentals_v2 233 } // namespace experimental 234 235 template <typename _Tp> 236 struct hash<experimental::observer_ptr<_Tp>> 237 { 238 using result_type = size_t; 239 using argument_type = experimental::observer_ptr<_Tp>; 240 241 size_t 242 operator()(const experimental::observer_ptr<_Tp>& __t) const 243 noexcept(noexcept(hash<typename add_pointer<_Tp>::type> {}(__t.get()))) 244 { 245 return hash<typename add_pointer<_Tp>::type> {}(__t.get()); 246 } 247 }; 248 249 250 _GLIBCXX_END_NAMESPACE_VERSION 251 } // namespace std 252 253 #endif // __cplusplus <= 201103L 254 255 #endif // _GLIBCXX_EXPERIMENTAL_MEMORY 256