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___MEMORY_SHARED_PTR_H 11 #define _LIBCPP___MEMORY_SHARED_PTR_H 12 13 #include <__availability> 14 #include <__config> 15 #include <__functional_base> // std::less, std::binary_function 16 #include <__memory/addressof.h> 17 #include <__memory/allocation_guard.h> 18 #include <__memory/allocator.h> 19 #include <__memory/allocator_traits.h> 20 #include <__memory/compressed_pair.h> 21 #include <__memory/pointer_traits.h> 22 #include <__memory/unique_ptr.h> 23 #include <__utility/forward.h> 24 #include <cstddef> 25 #include <cstdlib> // abort 26 #include <iosfwd> 27 #include <stdexcept> 28 #include <type_traits> 29 #include <utility> 30 #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) 31 # include <atomic> 32 #endif 33 34 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 35 # include <__memory/auto_ptr.h> 36 #endif 37 38 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 39 #pragma GCC system_header 40 #endif 41 42 _LIBCPP_PUSH_MACROS 43 #include <__undef_macros> 44 45 _LIBCPP_BEGIN_NAMESPACE_STD 46 47 template <class _Alloc> 48 class __allocator_destructor 49 { 50 typedef _LIBCPP_NODEBUG_TYPE allocator_traits<_Alloc> __alloc_traits; 51 public: 52 typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::pointer pointer; 53 typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::size_type size_type; 54 private: 55 _Alloc& __alloc_; 56 size_type __s_; 57 public: 58 _LIBCPP_INLINE_VISIBILITY __allocator_destructor(_Alloc& __a, size_type __s) 59 _NOEXCEPT 60 : __alloc_(__a), __s_(__s) {} 61 _LIBCPP_INLINE_VISIBILITY 62 void operator()(pointer __p) _NOEXCEPT 63 {__alloc_traits::deallocate(__alloc_, __p, __s_);} 64 }; 65 66 // NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively) 67 // should be sufficient for thread safety. 68 // See https://llvm.org/PR22803 69 #if defined(__clang__) && __has_builtin(__atomic_add_fetch) \ 70 && defined(__ATOMIC_RELAXED) \ 71 && defined(__ATOMIC_ACQ_REL) 72 # define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 73 #elif defined(_LIBCPP_COMPILER_GCC) 74 # define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT 75 #endif 76 77 template <class _ValueType> 78 inline _LIBCPP_INLINE_VISIBILITY 79 _ValueType __libcpp_relaxed_load(_ValueType const* __value) { 80 #if !defined(_LIBCPP_HAS_NO_THREADS) && \ 81 defined(__ATOMIC_RELAXED) && \ 82 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC)) 83 return __atomic_load_n(__value, __ATOMIC_RELAXED); 84 #else 85 return *__value; 86 #endif 87 } 88 89 template <class _ValueType> 90 inline _LIBCPP_INLINE_VISIBILITY 91 _ValueType __libcpp_acquire_load(_ValueType const* __value) { 92 #if !defined(_LIBCPP_HAS_NO_THREADS) && \ 93 defined(__ATOMIC_ACQUIRE) && \ 94 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC)) 95 return __atomic_load_n(__value, __ATOMIC_ACQUIRE); 96 #else 97 return *__value; 98 #endif 99 } 100 101 template <class _Tp> 102 inline _LIBCPP_INLINE_VISIBILITY _Tp 103 __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT 104 { 105 #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS) 106 return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED); 107 #else 108 return __t += 1; 109 #endif 110 } 111 112 template <class _Tp> 113 inline _LIBCPP_INLINE_VISIBILITY _Tp 114 __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT 115 { 116 #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS) 117 return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL); 118 #else 119 return __t -= 1; 120 #endif 121 } 122 123 class _LIBCPP_EXCEPTION_ABI bad_weak_ptr 124 : public std::exception 125 { 126 public: 127 bad_weak_ptr() _NOEXCEPT = default; 128 bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default; 129 virtual ~bad_weak_ptr() _NOEXCEPT; 130 virtual const char* what() const _NOEXCEPT; 131 }; 132 133 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 134 void __throw_bad_weak_ptr() 135 { 136 #ifndef _LIBCPP_NO_EXCEPTIONS 137 throw bad_weak_ptr(); 138 #else 139 _VSTD::abort(); 140 #endif 141 } 142 143 template<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr; 144 145 class _LIBCPP_TYPE_VIS __shared_count 146 { 147 __shared_count(const __shared_count&); 148 __shared_count& operator=(const __shared_count&); 149 150 protected: 151 long __shared_owners_; 152 virtual ~__shared_count(); 153 private: 154 virtual void __on_zero_shared() _NOEXCEPT = 0; 155 156 public: 157 _LIBCPP_INLINE_VISIBILITY 158 explicit __shared_count(long __refs = 0) _NOEXCEPT 159 : __shared_owners_(__refs) {} 160 161 #if defined(_LIBCPP_BUILDING_LIBRARY) && \ 162 defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) 163 void __add_shared() _NOEXCEPT; 164 bool __release_shared() _NOEXCEPT; 165 #else 166 _LIBCPP_INLINE_VISIBILITY 167 void __add_shared() _NOEXCEPT { 168 __libcpp_atomic_refcount_increment(__shared_owners_); 169 } 170 _LIBCPP_INLINE_VISIBILITY 171 bool __release_shared() _NOEXCEPT { 172 if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) { 173 __on_zero_shared(); 174 return true; 175 } 176 return false; 177 } 178 #endif 179 _LIBCPP_INLINE_VISIBILITY 180 long use_count() const _NOEXCEPT { 181 return __libcpp_relaxed_load(&__shared_owners_) + 1; 182 } 183 }; 184 185 class _LIBCPP_TYPE_VIS __shared_weak_count 186 : private __shared_count 187 { 188 long __shared_weak_owners_; 189 190 public: 191 _LIBCPP_INLINE_VISIBILITY 192 explicit __shared_weak_count(long __refs = 0) _NOEXCEPT 193 : __shared_count(__refs), 194 __shared_weak_owners_(__refs) {} 195 protected: 196 virtual ~__shared_weak_count(); 197 198 public: 199 #if defined(_LIBCPP_BUILDING_LIBRARY) && \ 200 defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) 201 void __add_shared() _NOEXCEPT; 202 void __add_weak() _NOEXCEPT; 203 void __release_shared() _NOEXCEPT; 204 #else 205 _LIBCPP_INLINE_VISIBILITY 206 void __add_shared() _NOEXCEPT { 207 __shared_count::__add_shared(); 208 } 209 _LIBCPP_INLINE_VISIBILITY 210 void __add_weak() _NOEXCEPT { 211 __libcpp_atomic_refcount_increment(__shared_weak_owners_); 212 } 213 _LIBCPP_INLINE_VISIBILITY 214 void __release_shared() _NOEXCEPT { 215 if (__shared_count::__release_shared()) 216 __release_weak(); 217 } 218 #endif 219 void __release_weak() _NOEXCEPT; 220 _LIBCPP_INLINE_VISIBILITY 221 long use_count() const _NOEXCEPT {return __shared_count::use_count();} 222 __shared_weak_count* lock() _NOEXCEPT; 223 224 virtual const void* __get_deleter(const type_info&) const _NOEXCEPT; 225 private: 226 virtual void __on_zero_shared_weak() _NOEXCEPT = 0; 227 }; 228 229 template <class _Tp, class _Dp, class _Alloc> 230 class __shared_ptr_pointer 231 : public __shared_weak_count 232 { 233 __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_; 234 public: 235 _LIBCPP_INLINE_VISIBILITY 236 __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a) 237 : __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {} 238 239 #ifndef _LIBCPP_NO_RTTI 240 virtual const void* __get_deleter(const type_info&) const _NOEXCEPT; 241 #endif 242 243 private: 244 virtual void __on_zero_shared() _NOEXCEPT; 245 virtual void __on_zero_shared_weak() _NOEXCEPT; 246 }; 247 248 #ifndef _LIBCPP_NO_RTTI 249 250 template <class _Tp, class _Dp, class _Alloc> 251 const void* 252 __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT 253 { 254 return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr; 255 } 256 257 #endif // _LIBCPP_NO_RTTI 258 259 template <class _Tp, class _Dp, class _Alloc> 260 void 261 __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT 262 { 263 __data_.first().second()(__data_.first().first()); 264 __data_.first().second().~_Dp(); 265 } 266 267 template <class _Tp, class _Dp, class _Alloc> 268 void 269 __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT 270 { 271 typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al; 272 typedef allocator_traits<_Al> _ATraits; 273 typedef pointer_traits<typename _ATraits::pointer> _PTraits; 274 275 _Al __a(__data_.second()); 276 __data_.second().~_Alloc(); 277 __a.deallocate(_PTraits::pointer_to(*this), 1); 278 } 279 280 template <class _Tp, class _Alloc> 281 struct __shared_ptr_emplace 282 : __shared_weak_count 283 { 284 template<class ..._Args> 285 _LIBCPP_HIDE_FROM_ABI 286 explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args) 287 : __storage_(_VSTD::move(__a)) 288 { 289 #if _LIBCPP_STD_VER > 17 290 using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type; 291 _TpAlloc __tmp(*__get_alloc()); 292 allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...); 293 #else 294 ::new ((void*)__get_elem()) _Tp(_VSTD::forward<_Args>(__args)...); 295 #endif 296 } 297 298 _LIBCPP_HIDE_FROM_ABI 299 _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); } 300 301 _LIBCPP_HIDE_FROM_ABI 302 _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); } 303 304 private: 305 virtual void __on_zero_shared() _NOEXCEPT { 306 #if _LIBCPP_STD_VER > 17 307 using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type; 308 _TpAlloc __tmp(*__get_alloc()); 309 allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem()); 310 #else 311 __get_elem()->~_Tp(); 312 #endif 313 } 314 315 virtual void __on_zero_shared_weak() _NOEXCEPT { 316 using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type; 317 using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer; 318 _ControlBlockAlloc __tmp(*__get_alloc()); 319 __storage_.~_Storage(); 320 allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, 321 pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1); 322 } 323 324 // This class implements the control block for non-array shared pointers created 325 // through `std::allocate_shared` and `std::make_shared`. 326 // 327 // In previous versions of the library, we used a compressed pair to store 328 // both the _Alloc and the _Tp. This implies using EBO, which is incompatible 329 // with Allocator construction for _Tp. To allow implementing P0674 in C++20, 330 // we now use a properly aligned char buffer while making sure that we maintain 331 // the same layout that we had when we used a compressed pair. 332 using _CompressedPair = __compressed_pair<_Alloc, _Tp>; 333 struct _ALIGNAS_TYPE(_CompressedPair) _Storage { 334 char __blob_[sizeof(_CompressedPair)]; 335 336 _LIBCPP_HIDE_FROM_ABI explicit _Storage(_Alloc&& __a) { 337 ::new ((void*)__get_alloc()) _Alloc(_VSTD::move(__a)); 338 } 339 _LIBCPP_HIDE_FROM_ABI ~_Storage() { 340 __get_alloc()->~_Alloc(); 341 } 342 _Alloc* __get_alloc() _NOEXCEPT { 343 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_); 344 typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair); 345 _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first); 346 return __alloc; 347 } 348 _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT { 349 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_); 350 typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair); 351 _Tp *__elem = reinterpret_cast<_Tp*>(__second); 352 return __elem; 353 } 354 }; 355 356 static_assert(_LIBCPP_ALIGNOF(_Storage) == _LIBCPP_ALIGNOF(_CompressedPair), ""); 357 static_assert(sizeof(_Storage) == sizeof(_CompressedPair), ""); 358 _Storage __storage_; 359 }; 360 361 struct __shared_ptr_dummy_rebind_allocator_type; 362 template <> 363 class _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type> 364 { 365 public: 366 template <class _Other> 367 struct rebind 368 { 369 typedef allocator<_Other> other; 370 }; 371 }; 372 373 template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this; 374 375 template<class _Tp, class _Up> 376 struct __compatible_with 377 #if _LIBCPP_STD_VER > 14 378 : is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {}; 379 #else 380 : is_convertible<_Tp*, _Up*> {}; 381 #endif // _LIBCPP_STD_VER > 14 382 383 template <class _Ptr, class = void> 384 struct __is_deletable : false_type { }; 385 template <class _Ptr> 386 struct __is_deletable<_Ptr, decltype(delete declval<_Ptr>())> : true_type { }; 387 388 template <class _Ptr, class = void> 389 struct __is_array_deletable : false_type { }; 390 template <class _Ptr> 391 struct __is_array_deletable<_Ptr, decltype(delete[] declval<_Ptr>())> : true_type { }; 392 393 template <class _Dp, class _Pt, 394 class = decltype(declval<_Dp>()(declval<_Pt>()))> 395 static true_type __well_formed_deleter_test(int); 396 397 template <class, class> 398 static false_type __well_formed_deleter_test(...); 399 400 template <class _Dp, class _Pt> 401 struct __well_formed_deleter : decltype(__well_formed_deleter_test<_Dp, _Pt>(0)) {}; 402 403 template<class _Dp, class _Tp, class _Yp> 404 struct __shared_ptr_deleter_ctor_reqs 405 { 406 static const bool value = __compatible_with<_Tp, _Yp>::value && 407 is_move_constructible<_Dp>::value && 408 __well_formed_deleter<_Dp, _Tp*>::value; 409 }; 410 411 #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI) 412 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi)) 413 #else 414 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI 415 #endif 416 417 template<class _Tp> 418 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr 419 { 420 public: 421 #if _LIBCPP_STD_VER > 14 422 typedef weak_ptr<_Tp> weak_type; 423 typedef remove_extent_t<_Tp> element_type; 424 #else 425 typedef _Tp element_type; 426 #endif 427 428 private: 429 element_type* __ptr_; 430 __shared_weak_count* __cntrl_; 431 432 struct __nat {int __for_bool_;}; 433 public: 434 _LIBCPP_INLINE_VISIBILITY 435 _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT; 436 _LIBCPP_INLINE_VISIBILITY 437 _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT; 438 439 template<class _Yp, class = _EnableIf< 440 _And< 441 __compatible_with<_Yp, _Tp> 442 // In C++03 we get errors when trying to do SFINAE with the 443 // delete operator, so we always pretend that it's deletable. 444 // The same happens on GCC. 445 #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC) 446 , _If<is_array<_Tp>::value, __is_array_deletable<_Yp*>, __is_deletable<_Yp*> > 447 #endif 448 >::value 449 > > 450 explicit shared_ptr(_Yp* __p) : __ptr_(__p) { 451 unique_ptr<_Yp> __hold(__p); 452 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 453 typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk; 454 __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT()); 455 __hold.release(); 456 __enable_weak_this(__p, __p); 457 } 458 459 template<class _Yp, class _Dp> 460 shared_ptr(_Yp* __p, _Dp __d, 461 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat()); 462 template<class _Yp, class _Dp, class _Alloc> 463 shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, 464 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat()); 465 template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d); 466 template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a); 467 template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT; 468 _LIBCPP_INLINE_VISIBILITY 469 shared_ptr(const shared_ptr& __r) _NOEXCEPT; 470 template<class _Yp> 471 _LIBCPP_INLINE_VISIBILITY 472 shared_ptr(const shared_ptr<_Yp>& __r, 473 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat()) 474 _NOEXCEPT; 475 _LIBCPP_INLINE_VISIBILITY 476 shared_ptr(shared_ptr&& __r) _NOEXCEPT; 477 template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(shared_ptr<_Yp>&& __r, 478 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat()) 479 _NOEXCEPT; 480 template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r, 481 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat()); 482 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 483 template<class _Yp> 484 shared_ptr(auto_ptr<_Yp>&& __r, 485 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat()); 486 #endif 487 template <class _Yp, class _Dp> 488 shared_ptr(unique_ptr<_Yp, _Dp>&&, 489 typename enable_if 490 < 491 !is_lvalue_reference<_Dp>::value && 492 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 493 __nat 494 >::type = __nat()); 495 template <class _Yp, class _Dp> 496 shared_ptr(unique_ptr<_Yp, _Dp>&&, 497 typename enable_if 498 < 499 is_lvalue_reference<_Dp>::value && 500 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 501 __nat 502 >::type = __nat()); 503 504 ~shared_ptr(); 505 506 _LIBCPP_INLINE_VISIBILITY 507 shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT; 508 template<class _Yp> 509 typename enable_if 510 < 511 __compatible_with<_Yp, element_type>::value, 512 shared_ptr& 513 >::type 514 _LIBCPP_INLINE_VISIBILITY 515 operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT; 516 _LIBCPP_INLINE_VISIBILITY 517 shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT; 518 template<class _Yp> 519 typename enable_if 520 < 521 __compatible_with<_Yp, element_type>::value, 522 shared_ptr& 523 >::type 524 _LIBCPP_INLINE_VISIBILITY 525 operator=(shared_ptr<_Yp>&& __r); 526 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 527 template<class _Yp> 528 _LIBCPP_INLINE_VISIBILITY 529 typename enable_if 530 < 531 !is_array<_Yp>::value && 532 is_convertible<_Yp*, element_type*>::value, 533 shared_ptr 534 >::type& 535 operator=(auto_ptr<_Yp>&& __r); 536 #endif 537 template <class _Yp, class _Dp> 538 typename enable_if 539 < 540 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 541 shared_ptr& 542 >::type 543 _LIBCPP_INLINE_VISIBILITY 544 operator=(unique_ptr<_Yp, _Dp>&& __r); 545 546 _LIBCPP_INLINE_VISIBILITY 547 void swap(shared_ptr& __r) _NOEXCEPT; 548 _LIBCPP_INLINE_VISIBILITY 549 void reset() _NOEXCEPT; 550 template<class _Yp> 551 typename enable_if 552 < 553 __compatible_with<_Yp, element_type>::value, 554 void 555 >::type 556 _LIBCPP_INLINE_VISIBILITY 557 reset(_Yp* __p); 558 template<class _Yp, class _Dp> 559 typename enable_if 560 < 561 __compatible_with<_Yp, element_type>::value, 562 void 563 >::type 564 _LIBCPP_INLINE_VISIBILITY 565 reset(_Yp* __p, _Dp __d); 566 template<class _Yp, class _Dp, class _Alloc> 567 typename enable_if 568 < 569 __compatible_with<_Yp, element_type>::value, 570 void 571 >::type 572 _LIBCPP_INLINE_VISIBILITY 573 reset(_Yp* __p, _Dp __d, _Alloc __a); 574 575 _LIBCPP_INLINE_VISIBILITY 576 element_type* get() const _NOEXCEPT {return __ptr_;} 577 _LIBCPP_INLINE_VISIBILITY 578 typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT 579 {return *__ptr_;} 580 _LIBCPP_INLINE_VISIBILITY 581 element_type* operator->() const _NOEXCEPT 582 { 583 static_assert(!is_array<_Tp>::value, 584 "std::shared_ptr<T>::operator-> is only valid when T is not an array type."); 585 return __ptr_; 586 } 587 _LIBCPP_INLINE_VISIBILITY 588 long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;} 589 _LIBCPP_INLINE_VISIBILITY 590 bool unique() const _NOEXCEPT {return use_count() == 1;} 591 _LIBCPP_INLINE_VISIBILITY 592 explicit operator bool() const _NOEXCEPT {return get() != nullptr;} 593 template <class _Up> 594 _LIBCPP_INLINE_VISIBILITY 595 bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT 596 {return __cntrl_ < __p.__cntrl_;} 597 template <class _Up> 598 _LIBCPP_INLINE_VISIBILITY 599 bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT 600 {return __cntrl_ < __p.__cntrl_;} 601 _LIBCPP_INLINE_VISIBILITY 602 bool 603 __owner_equivalent(const shared_ptr& __p) const 604 {return __cntrl_ == __p.__cntrl_;} 605 606 #if _LIBCPP_STD_VER > 14 607 typename add_lvalue_reference<element_type>::type 608 _LIBCPP_INLINE_VISIBILITY 609 operator[](ptrdiff_t __i) const 610 { 611 static_assert(is_array<_Tp>::value, 612 "std::shared_ptr<T>::operator[] is only valid when T is an array type."); 613 return __ptr_[__i]; 614 } 615 #endif 616 617 #ifndef _LIBCPP_NO_RTTI 618 template <class _Dp> 619 _LIBCPP_INLINE_VISIBILITY 620 _Dp* __get_deleter() const _NOEXCEPT 621 {return static_cast<_Dp*>(__cntrl_ 622 ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp))) 623 : nullptr);} 624 #endif // _LIBCPP_NO_RTTI 625 626 template<class _Yp, class _CntrlBlk> 627 static shared_ptr<_Tp> 628 __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT 629 { 630 shared_ptr<_Tp> __r; 631 __r.__ptr_ = __p; 632 __r.__cntrl_ = __cntrl; 633 __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); 634 return __r; 635 } 636 637 private: 638 template <class _Yp, bool = is_function<_Yp>::value> 639 struct __shared_ptr_default_allocator 640 { 641 typedef allocator<_Yp> type; 642 }; 643 644 template <class _Yp> 645 struct __shared_ptr_default_allocator<_Yp, true> 646 { 647 typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type; 648 }; 649 650 template <class _Yp, class _OrigPtr> 651 _LIBCPP_INLINE_VISIBILITY 652 typename enable_if<is_convertible<_OrigPtr*, 653 const enable_shared_from_this<_Yp>* 654 >::value, 655 void>::type 656 __enable_weak_this(const enable_shared_from_this<_Yp>* __e, 657 _OrigPtr* __ptr) _NOEXCEPT 658 { 659 typedef typename remove_cv<_Yp>::type _RawYp; 660 if (__e && __e->__weak_this_.expired()) 661 { 662 __e->__weak_this_ = shared_ptr<_RawYp>(*this, 663 const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr))); 664 } 665 } 666 667 _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {} 668 669 template <class, class _Yp> 670 struct __shared_ptr_default_delete 671 : default_delete<_Yp> {}; 672 673 template <class _Yp, class _Un, size_t _Sz> 674 struct __shared_ptr_default_delete<_Yp[_Sz], _Un> 675 : default_delete<_Yp[]> {}; 676 677 template <class _Yp, class _Un> 678 struct __shared_ptr_default_delete<_Yp[], _Un> 679 : default_delete<_Yp[]> {}; 680 681 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr; 682 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr; 683 }; 684 685 #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES 686 template<class _Tp> 687 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; 688 template<class _Tp, class _Dp> 689 shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>; 690 #endif 691 692 template<class _Tp> 693 inline 694 _LIBCPP_CONSTEXPR 695 shared_ptr<_Tp>::shared_ptr() _NOEXCEPT 696 : __ptr_(nullptr), 697 __cntrl_(nullptr) 698 { 699 } 700 701 template<class _Tp> 702 inline 703 _LIBCPP_CONSTEXPR 704 shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT 705 : __ptr_(nullptr), 706 __cntrl_(nullptr) 707 { 708 } 709 710 template<class _Tp> 711 template<class _Yp, class _Dp> 712 shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, 713 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type) 714 : __ptr_(__p) 715 { 716 #ifndef _LIBCPP_NO_EXCEPTIONS 717 try 718 { 719 #endif // _LIBCPP_NO_EXCEPTIONS 720 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 721 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk; 722 #ifndef _LIBCPP_CXX03_LANG 723 __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT()); 724 #else 725 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); 726 #endif // not _LIBCPP_CXX03_LANG 727 __enable_weak_this(__p, __p); 728 #ifndef _LIBCPP_NO_EXCEPTIONS 729 } 730 catch (...) 731 { 732 __d(__p); 733 throw; 734 } 735 #endif // _LIBCPP_NO_EXCEPTIONS 736 } 737 738 template<class _Tp> 739 template<class _Dp> 740 shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d) 741 : __ptr_(nullptr) 742 { 743 #ifndef _LIBCPP_NO_EXCEPTIONS 744 try 745 { 746 #endif // _LIBCPP_NO_EXCEPTIONS 747 typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT; 748 typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk; 749 #ifndef _LIBCPP_CXX03_LANG 750 __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT()); 751 #else 752 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); 753 #endif // not _LIBCPP_CXX03_LANG 754 #ifndef _LIBCPP_NO_EXCEPTIONS 755 } 756 catch (...) 757 { 758 __d(__p); 759 throw; 760 } 761 #endif // _LIBCPP_NO_EXCEPTIONS 762 } 763 764 template<class _Tp> 765 template<class _Yp, class _Dp, class _Alloc> 766 shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, 767 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type) 768 : __ptr_(__p) 769 { 770 #ifndef _LIBCPP_NO_EXCEPTIONS 771 try 772 { 773 #endif // _LIBCPP_NO_EXCEPTIONS 774 typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk; 775 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; 776 typedef __allocator_destructor<_A2> _D2; 777 _A2 __a2(__a); 778 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); 779 ::new ((void*)_VSTD::addressof(*__hold2.get())) 780 #ifndef _LIBCPP_CXX03_LANG 781 _CntrlBlk(__p, _VSTD::move(__d), __a); 782 #else 783 _CntrlBlk(__p, __d, __a); 784 #endif // not _LIBCPP_CXX03_LANG 785 __cntrl_ = _VSTD::addressof(*__hold2.release()); 786 __enable_weak_this(__p, __p); 787 #ifndef _LIBCPP_NO_EXCEPTIONS 788 } 789 catch (...) 790 { 791 __d(__p); 792 throw; 793 } 794 #endif // _LIBCPP_NO_EXCEPTIONS 795 } 796 797 template<class _Tp> 798 template<class _Dp, class _Alloc> 799 shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a) 800 : __ptr_(nullptr) 801 { 802 #ifndef _LIBCPP_NO_EXCEPTIONS 803 try 804 { 805 #endif // _LIBCPP_NO_EXCEPTIONS 806 typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk; 807 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; 808 typedef __allocator_destructor<_A2> _D2; 809 _A2 __a2(__a); 810 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); 811 ::new ((void*)_VSTD::addressof(*__hold2.get())) 812 #ifndef _LIBCPP_CXX03_LANG 813 _CntrlBlk(__p, _VSTD::move(__d), __a); 814 #else 815 _CntrlBlk(__p, __d, __a); 816 #endif // not _LIBCPP_CXX03_LANG 817 __cntrl_ = _VSTD::addressof(*__hold2.release()); 818 #ifndef _LIBCPP_NO_EXCEPTIONS 819 } 820 catch (...) 821 { 822 __d(__p); 823 throw; 824 } 825 #endif // _LIBCPP_NO_EXCEPTIONS 826 } 827 828 template<class _Tp> 829 template<class _Yp> 830 inline 831 shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT 832 : __ptr_(__p), 833 __cntrl_(__r.__cntrl_) 834 { 835 if (__cntrl_) 836 __cntrl_->__add_shared(); 837 } 838 839 template<class _Tp> 840 inline 841 shared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT 842 : __ptr_(__r.__ptr_), 843 __cntrl_(__r.__cntrl_) 844 { 845 if (__cntrl_) 846 __cntrl_->__add_shared(); 847 } 848 849 template<class _Tp> 850 template<class _Yp> 851 inline 852 shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, 853 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type) 854 _NOEXCEPT 855 : __ptr_(__r.__ptr_), 856 __cntrl_(__r.__cntrl_) 857 { 858 if (__cntrl_) 859 __cntrl_->__add_shared(); 860 } 861 862 template<class _Tp> 863 inline 864 shared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT 865 : __ptr_(__r.__ptr_), 866 __cntrl_(__r.__cntrl_) 867 { 868 __r.__ptr_ = nullptr; 869 __r.__cntrl_ = nullptr; 870 } 871 872 template<class _Tp> 873 template<class _Yp> 874 inline 875 shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r, 876 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type) 877 _NOEXCEPT 878 : __ptr_(__r.__ptr_), 879 __cntrl_(__r.__cntrl_) 880 { 881 __r.__ptr_ = nullptr; 882 __r.__cntrl_ = nullptr; 883 } 884 885 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 886 template<class _Tp> 887 template<class _Yp> 888 shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r, 889 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) 890 : __ptr_(__r.get()) 891 { 892 typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk; 893 __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>()); 894 __enable_weak_this(__r.get(), __r.get()); 895 __r.release(); 896 } 897 #endif 898 899 template<class _Tp> 900 template <class _Yp, class _Dp> 901 shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, 902 typename enable_if 903 < 904 !is_lvalue_reference<_Dp>::value && 905 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 906 __nat 907 >::type) 908 : __ptr_(__r.get()) 909 { 910 #if _LIBCPP_STD_VER > 11 911 if (__ptr_ == nullptr) 912 __cntrl_ = nullptr; 913 else 914 #endif 915 { 916 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 917 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT > _CntrlBlk; 918 __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT()); 919 __enable_weak_this(__r.get(), __r.get()); 920 } 921 __r.release(); 922 } 923 924 template<class _Tp> 925 template <class _Yp, class _Dp> 926 shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, 927 typename enable_if 928 < 929 is_lvalue_reference<_Dp>::value && 930 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 931 __nat 932 >::type) 933 : __ptr_(__r.get()) 934 { 935 #if _LIBCPP_STD_VER > 11 936 if (__ptr_ == nullptr) 937 __cntrl_ = nullptr; 938 else 939 #endif 940 { 941 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 942 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, 943 reference_wrapper<typename remove_reference<_Dp>::type>, 944 _AllocT > _CntrlBlk; 945 __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT()); 946 __enable_weak_this(__r.get(), __r.get()); 947 } 948 __r.release(); 949 } 950 951 template<class _Tp> 952 shared_ptr<_Tp>::~shared_ptr() 953 { 954 if (__cntrl_) 955 __cntrl_->__release_shared(); 956 } 957 958 template<class _Tp> 959 inline 960 shared_ptr<_Tp>& 961 shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT 962 { 963 shared_ptr(__r).swap(*this); 964 return *this; 965 } 966 967 template<class _Tp> 968 template<class _Yp> 969 inline 970 typename enable_if 971 < 972 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, 973 shared_ptr<_Tp>& 974 >::type 975 shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT 976 { 977 shared_ptr(__r).swap(*this); 978 return *this; 979 } 980 981 template<class _Tp> 982 inline 983 shared_ptr<_Tp>& 984 shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT 985 { 986 shared_ptr(_VSTD::move(__r)).swap(*this); 987 return *this; 988 } 989 990 template<class _Tp> 991 template<class _Yp> 992 inline 993 typename enable_if 994 < 995 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, 996 shared_ptr<_Tp>& 997 >::type 998 shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r) 999 { 1000 shared_ptr(_VSTD::move(__r)).swap(*this); 1001 return *this; 1002 } 1003 1004 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 1005 template<class _Tp> 1006 template<class _Yp> 1007 inline 1008 typename enable_if 1009 < 1010 !is_array<_Yp>::value && 1011 is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, 1012 shared_ptr<_Tp> 1013 >::type& 1014 shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r) 1015 { 1016 shared_ptr(_VSTD::move(__r)).swap(*this); 1017 return *this; 1018 } 1019 #endif 1020 1021 template<class _Tp> 1022 template <class _Yp, class _Dp> 1023 inline 1024 typename enable_if 1025 < 1026 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, 1027 typename shared_ptr<_Tp>::element_type*>::value, 1028 shared_ptr<_Tp>& 1029 >::type 1030 shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r) 1031 { 1032 shared_ptr(_VSTD::move(__r)).swap(*this); 1033 return *this; 1034 } 1035 1036 template<class _Tp> 1037 inline 1038 void 1039 shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT 1040 { 1041 _VSTD::swap(__ptr_, __r.__ptr_); 1042 _VSTD::swap(__cntrl_, __r.__cntrl_); 1043 } 1044 1045 template<class _Tp> 1046 inline 1047 void 1048 shared_ptr<_Tp>::reset() _NOEXCEPT 1049 { 1050 shared_ptr().swap(*this); 1051 } 1052 1053 template<class _Tp> 1054 template<class _Yp> 1055 inline 1056 typename enable_if 1057 < 1058 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, 1059 void 1060 >::type 1061 shared_ptr<_Tp>::reset(_Yp* __p) 1062 { 1063 shared_ptr(__p).swap(*this); 1064 } 1065 1066 template<class _Tp> 1067 template<class _Yp, class _Dp> 1068 inline 1069 typename enable_if 1070 < 1071 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, 1072 void 1073 >::type 1074 shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d) 1075 { 1076 shared_ptr(__p, __d).swap(*this); 1077 } 1078 1079 template<class _Tp> 1080 template<class _Yp, class _Dp, class _Alloc> 1081 inline 1082 typename enable_if 1083 < 1084 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, 1085 void 1086 >::type 1087 shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a) 1088 { 1089 shared_ptr(__p, __d, __a).swap(*this); 1090 } 1091 1092 // 1093 // std::allocate_shared and std::make_shared 1094 // 1095 template<class _Tp, class _Alloc, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> > 1096 _LIBCPP_HIDE_FROM_ABI 1097 shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args) 1098 { 1099 using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>; 1100 using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type; 1101 __allocation_guard<_ControlBlockAllocator> __guard(__a, 1); 1102 ::new ((void*)_VSTD::addressof(*__guard.__get())) _ControlBlock(__a, _VSTD::forward<_Args>(__args)...); 1103 auto __control_block = __guard.__release_ptr(); 1104 return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block)); 1105 } 1106 1107 template<class _Tp, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> > 1108 _LIBCPP_HIDE_FROM_ABI 1109 shared_ptr<_Tp> make_shared(_Args&& ...__args) 1110 { 1111 return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...); 1112 } 1113 1114 template<class _Tp, class _Up> 1115 inline _LIBCPP_INLINE_VISIBILITY 1116 bool 1117 operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT 1118 { 1119 return __x.get() == __y.get(); 1120 } 1121 1122 template<class _Tp, class _Up> 1123 inline _LIBCPP_INLINE_VISIBILITY 1124 bool 1125 operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT 1126 { 1127 return !(__x == __y); 1128 } 1129 1130 template<class _Tp, class _Up> 1131 inline _LIBCPP_INLINE_VISIBILITY 1132 bool 1133 operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT 1134 { 1135 #if _LIBCPP_STD_VER <= 11 1136 typedef typename common_type<_Tp*, _Up*>::type _Vp; 1137 return less<_Vp>()(__x.get(), __y.get()); 1138 #else 1139 return less<>()(__x.get(), __y.get()); 1140 #endif 1141 1142 } 1143 1144 template<class _Tp, class _Up> 1145 inline _LIBCPP_INLINE_VISIBILITY 1146 bool 1147 operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT 1148 { 1149 return __y < __x; 1150 } 1151 1152 template<class _Tp, class _Up> 1153 inline _LIBCPP_INLINE_VISIBILITY 1154 bool 1155 operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT 1156 { 1157 return !(__y < __x); 1158 } 1159 1160 template<class _Tp, class _Up> 1161 inline _LIBCPP_INLINE_VISIBILITY 1162 bool 1163 operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT 1164 { 1165 return !(__x < __y); 1166 } 1167 1168 template<class _Tp> 1169 inline _LIBCPP_INLINE_VISIBILITY 1170 bool 1171 operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1172 { 1173 return !__x; 1174 } 1175 1176 template<class _Tp> 1177 inline _LIBCPP_INLINE_VISIBILITY 1178 bool 1179 operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1180 { 1181 return !__x; 1182 } 1183 1184 template<class _Tp> 1185 inline _LIBCPP_INLINE_VISIBILITY 1186 bool 1187 operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1188 { 1189 return static_cast<bool>(__x); 1190 } 1191 1192 template<class _Tp> 1193 inline _LIBCPP_INLINE_VISIBILITY 1194 bool 1195 operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1196 { 1197 return static_cast<bool>(__x); 1198 } 1199 1200 template<class _Tp> 1201 inline _LIBCPP_INLINE_VISIBILITY 1202 bool 1203 operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1204 { 1205 return less<_Tp*>()(__x.get(), nullptr); 1206 } 1207 1208 template<class _Tp> 1209 inline _LIBCPP_INLINE_VISIBILITY 1210 bool 1211 operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1212 { 1213 return less<_Tp*>()(nullptr, __x.get()); 1214 } 1215 1216 template<class _Tp> 1217 inline _LIBCPP_INLINE_VISIBILITY 1218 bool 1219 operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1220 { 1221 return nullptr < __x; 1222 } 1223 1224 template<class _Tp> 1225 inline _LIBCPP_INLINE_VISIBILITY 1226 bool 1227 operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1228 { 1229 return __x < nullptr; 1230 } 1231 1232 template<class _Tp> 1233 inline _LIBCPP_INLINE_VISIBILITY 1234 bool 1235 operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1236 { 1237 return !(nullptr < __x); 1238 } 1239 1240 template<class _Tp> 1241 inline _LIBCPP_INLINE_VISIBILITY 1242 bool 1243 operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1244 { 1245 return !(__x < nullptr); 1246 } 1247 1248 template<class _Tp> 1249 inline _LIBCPP_INLINE_VISIBILITY 1250 bool 1251 operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1252 { 1253 return !(__x < nullptr); 1254 } 1255 1256 template<class _Tp> 1257 inline _LIBCPP_INLINE_VISIBILITY 1258 bool 1259 operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1260 { 1261 return !(nullptr < __x); 1262 } 1263 1264 template<class _Tp> 1265 inline _LIBCPP_INLINE_VISIBILITY 1266 void 1267 swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT 1268 { 1269 __x.swap(__y); 1270 } 1271 1272 template<class _Tp, class _Up> 1273 inline _LIBCPP_INLINE_VISIBILITY 1274 shared_ptr<_Tp> 1275 static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT 1276 { 1277 return shared_ptr<_Tp>(__r, 1278 static_cast< 1279 typename shared_ptr<_Tp>::element_type*>(__r.get())); 1280 } 1281 1282 template<class _Tp, class _Up> 1283 inline _LIBCPP_INLINE_VISIBILITY 1284 shared_ptr<_Tp> 1285 dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT 1286 { 1287 typedef typename shared_ptr<_Tp>::element_type _ET; 1288 _ET* __p = dynamic_cast<_ET*>(__r.get()); 1289 return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>(); 1290 } 1291 1292 template<class _Tp, class _Up> 1293 shared_ptr<_Tp> 1294 const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT 1295 { 1296 typedef typename shared_ptr<_Tp>::element_type _RTp; 1297 return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get())); 1298 } 1299 1300 template<class _Tp, class _Up> 1301 shared_ptr<_Tp> 1302 reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT 1303 { 1304 return shared_ptr<_Tp>(__r, 1305 reinterpret_cast< 1306 typename shared_ptr<_Tp>::element_type*>(__r.get())); 1307 } 1308 1309 #ifndef _LIBCPP_NO_RTTI 1310 1311 template<class _Dp, class _Tp> 1312 inline _LIBCPP_INLINE_VISIBILITY 1313 _Dp* 1314 get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT 1315 { 1316 return __p.template __get_deleter<_Dp>(); 1317 } 1318 1319 #endif // _LIBCPP_NO_RTTI 1320 1321 template<class _Tp> 1322 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr 1323 { 1324 public: 1325 typedef _Tp element_type; 1326 private: 1327 element_type* __ptr_; 1328 __shared_weak_count* __cntrl_; 1329 1330 public: 1331 _LIBCPP_INLINE_VISIBILITY 1332 _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT; 1333 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r, 1334 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0) 1335 _NOEXCEPT; 1336 _LIBCPP_INLINE_VISIBILITY 1337 weak_ptr(weak_ptr const& __r) _NOEXCEPT; 1338 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r, 1339 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0) 1340 _NOEXCEPT; 1341 1342 _LIBCPP_INLINE_VISIBILITY 1343 weak_ptr(weak_ptr&& __r) _NOEXCEPT; 1344 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r, 1345 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0) 1346 _NOEXCEPT; 1347 ~weak_ptr(); 1348 1349 _LIBCPP_INLINE_VISIBILITY 1350 weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT; 1351 template<class _Yp> 1352 typename enable_if 1353 < 1354 is_convertible<_Yp*, element_type*>::value, 1355 weak_ptr& 1356 >::type 1357 _LIBCPP_INLINE_VISIBILITY 1358 operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT; 1359 1360 _LIBCPP_INLINE_VISIBILITY 1361 weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT; 1362 template<class _Yp> 1363 typename enable_if 1364 < 1365 is_convertible<_Yp*, element_type*>::value, 1366 weak_ptr& 1367 >::type 1368 _LIBCPP_INLINE_VISIBILITY 1369 operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT; 1370 1371 template<class _Yp> 1372 typename enable_if 1373 < 1374 is_convertible<_Yp*, element_type*>::value, 1375 weak_ptr& 1376 >::type 1377 _LIBCPP_INLINE_VISIBILITY 1378 operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT; 1379 1380 _LIBCPP_INLINE_VISIBILITY 1381 void swap(weak_ptr& __r) _NOEXCEPT; 1382 _LIBCPP_INLINE_VISIBILITY 1383 void reset() _NOEXCEPT; 1384 1385 _LIBCPP_INLINE_VISIBILITY 1386 long use_count() const _NOEXCEPT 1387 {return __cntrl_ ? __cntrl_->use_count() : 0;} 1388 _LIBCPP_INLINE_VISIBILITY 1389 bool expired() const _NOEXCEPT 1390 {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;} 1391 shared_ptr<_Tp> lock() const _NOEXCEPT; 1392 template<class _Up> 1393 _LIBCPP_INLINE_VISIBILITY 1394 bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT 1395 {return __cntrl_ < __r.__cntrl_;} 1396 template<class _Up> 1397 _LIBCPP_INLINE_VISIBILITY 1398 bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT 1399 {return __cntrl_ < __r.__cntrl_;} 1400 1401 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr; 1402 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr; 1403 }; 1404 1405 #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES 1406 template<class _Tp> 1407 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; 1408 #endif 1409 1410 template<class _Tp> 1411 inline 1412 _LIBCPP_CONSTEXPR 1413 weak_ptr<_Tp>::weak_ptr() _NOEXCEPT 1414 : __ptr_(nullptr), 1415 __cntrl_(nullptr) 1416 { 1417 } 1418 1419 template<class _Tp> 1420 inline 1421 weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT 1422 : __ptr_(__r.__ptr_), 1423 __cntrl_(__r.__cntrl_) 1424 { 1425 if (__cntrl_) 1426 __cntrl_->__add_weak(); 1427 } 1428 1429 template<class _Tp> 1430 template<class _Yp> 1431 inline 1432 weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r, 1433 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type) 1434 _NOEXCEPT 1435 : __ptr_(__r.__ptr_), 1436 __cntrl_(__r.__cntrl_) 1437 { 1438 if (__cntrl_) 1439 __cntrl_->__add_weak(); 1440 } 1441 1442 template<class _Tp> 1443 template<class _Yp> 1444 inline 1445 weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r, 1446 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type) 1447 _NOEXCEPT 1448 : __ptr_(__r.__ptr_), 1449 __cntrl_(__r.__cntrl_) 1450 { 1451 if (__cntrl_) 1452 __cntrl_->__add_weak(); 1453 } 1454 1455 template<class _Tp> 1456 inline 1457 weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT 1458 : __ptr_(__r.__ptr_), 1459 __cntrl_(__r.__cntrl_) 1460 { 1461 __r.__ptr_ = nullptr; 1462 __r.__cntrl_ = nullptr; 1463 } 1464 1465 template<class _Tp> 1466 template<class _Yp> 1467 inline 1468 weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r, 1469 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type) 1470 _NOEXCEPT 1471 : __ptr_(__r.__ptr_), 1472 __cntrl_(__r.__cntrl_) 1473 { 1474 __r.__ptr_ = nullptr; 1475 __r.__cntrl_ = nullptr; 1476 } 1477 1478 template<class _Tp> 1479 weak_ptr<_Tp>::~weak_ptr() 1480 { 1481 if (__cntrl_) 1482 __cntrl_->__release_weak(); 1483 } 1484 1485 template<class _Tp> 1486 inline 1487 weak_ptr<_Tp>& 1488 weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT 1489 { 1490 weak_ptr(__r).swap(*this); 1491 return *this; 1492 } 1493 1494 template<class _Tp> 1495 template<class _Yp> 1496 inline 1497 typename enable_if 1498 < 1499 is_convertible<_Yp*, _Tp*>::value, 1500 weak_ptr<_Tp>& 1501 >::type 1502 weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT 1503 { 1504 weak_ptr(__r).swap(*this); 1505 return *this; 1506 } 1507 1508 template<class _Tp> 1509 inline 1510 weak_ptr<_Tp>& 1511 weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT 1512 { 1513 weak_ptr(_VSTD::move(__r)).swap(*this); 1514 return *this; 1515 } 1516 1517 template<class _Tp> 1518 template<class _Yp> 1519 inline 1520 typename enable_if 1521 < 1522 is_convertible<_Yp*, _Tp*>::value, 1523 weak_ptr<_Tp>& 1524 >::type 1525 weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT 1526 { 1527 weak_ptr(_VSTD::move(__r)).swap(*this); 1528 return *this; 1529 } 1530 1531 template<class _Tp> 1532 template<class _Yp> 1533 inline 1534 typename enable_if 1535 < 1536 is_convertible<_Yp*, _Tp*>::value, 1537 weak_ptr<_Tp>& 1538 >::type 1539 weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT 1540 { 1541 weak_ptr(__r).swap(*this); 1542 return *this; 1543 } 1544 1545 template<class _Tp> 1546 inline 1547 void 1548 weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT 1549 { 1550 _VSTD::swap(__ptr_, __r.__ptr_); 1551 _VSTD::swap(__cntrl_, __r.__cntrl_); 1552 } 1553 1554 template<class _Tp> 1555 inline _LIBCPP_INLINE_VISIBILITY 1556 void 1557 swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT 1558 { 1559 __x.swap(__y); 1560 } 1561 1562 template<class _Tp> 1563 inline 1564 void 1565 weak_ptr<_Tp>::reset() _NOEXCEPT 1566 { 1567 weak_ptr().swap(*this); 1568 } 1569 1570 template<class _Tp> 1571 template<class _Yp> 1572 shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r, 1573 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) 1574 : __ptr_(__r.__ptr_), 1575 __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_) 1576 { 1577 if (__cntrl_ == nullptr) 1578 __throw_bad_weak_ptr(); 1579 } 1580 1581 template<class _Tp> 1582 shared_ptr<_Tp> 1583 weak_ptr<_Tp>::lock() const _NOEXCEPT 1584 { 1585 shared_ptr<_Tp> __r; 1586 __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_; 1587 if (__r.__cntrl_) 1588 __r.__ptr_ = __ptr_; 1589 return __r; 1590 } 1591 1592 #if _LIBCPP_STD_VER > 14 1593 template <class _Tp = void> struct owner_less; 1594 #else 1595 template <class _Tp> struct owner_less; 1596 #endif 1597 1598 1599 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 1600 template <class _Tp> 1601 struct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> > 1602 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 1603 : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool> 1604 #endif 1605 { 1606 _LIBCPP_SUPPRESS_DEPRECATED_POP 1607 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 1608 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; 1609 _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> first_argument_type; 1610 _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> second_argument_type; 1611 #endif 1612 _LIBCPP_INLINE_VISIBILITY 1613 bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT 1614 {return __x.owner_before(__y);} 1615 _LIBCPP_INLINE_VISIBILITY 1616 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT 1617 {return __x.owner_before(__y);} 1618 _LIBCPP_INLINE_VISIBILITY 1619 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT 1620 {return __x.owner_before(__y);} 1621 }; 1622 1623 _LIBCPP_SUPPRESS_DEPRECATED_PUSH 1624 template <class _Tp> 1625 struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> > 1626 #if !defined(_LIBCPP_ABI_NO_BINDER_BASES) 1627 : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool> 1628 #endif 1629 { 1630 _LIBCPP_SUPPRESS_DEPRECATED_POP 1631 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 1632 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type; 1633 _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> first_argument_type; 1634 _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> second_argument_type; 1635 #endif 1636 _LIBCPP_INLINE_VISIBILITY 1637 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT 1638 {return __x.owner_before(__y);} 1639 _LIBCPP_INLINE_VISIBILITY 1640 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT 1641 {return __x.owner_before(__y);} 1642 _LIBCPP_INLINE_VISIBILITY 1643 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT 1644 {return __x.owner_before(__y);} 1645 }; 1646 1647 #if _LIBCPP_STD_VER > 14 1648 template <> 1649 struct _LIBCPP_TEMPLATE_VIS owner_less<void> 1650 { 1651 template <class _Tp, class _Up> 1652 _LIBCPP_INLINE_VISIBILITY 1653 bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT 1654 {return __x.owner_before(__y);} 1655 template <class _Tp, class _Up> 1656 _LIBCPP_INLINE_VISIBILITY 1657 bool operator()( shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT 1658 {return __x.owner_before(__y);} 1659 template <class _Tp, class _Up> 1660 _LIBCPP_INLINE_VISIBILITY 1661 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT 1662 {return __x.owner_before(__y);} 1663 template <class _Tp, class _Up> 1664 _LIBCPP_INLINE_VISIBILITY 1665 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT 1666 {return __x.owner_before(__y);} 1667 typedef void is_transparent; 1668 }; 1669 #endif 1670 1671 template<class _Tp> 1672 class _LIBCPP_TEMPLATE_VIS enable_shared_from_this 1673 { 1674 mutable weak_ptr<_Tp> __weak_this_; 1675 protected: 1676 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1677 enable_shared_from_this() _NOEXCEPT {} 1678 _LIBCPP_INLINE_VISIBILITY 1679 enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {} 1680 _LIBCPP_INLINE_VISIBILITY 1681 enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT 1682 {return *this;} 1683 _LIBCPP_INLINE_VISIBILITY 1684 ~enable_shared_from_this() {} 1685 public: 1686 _LIBCPP_INLINE_VISIBILITY 1687 shared_ptr<_Tp> shared_from_this() 1688 {return shared_ptr<_Tp>(__weak_this_);} 1689 _LIBCPP_INLINE_VISIBILITY 1690 shared_ptr<_Tp const> shared_from_this() const 1691 {return shared_ptr<const _Tp>(__weak_this_);} 1692 1693 #if _LIBCPP_STD_VER > 14 1694 _LIBCPP_INLINE_VISIBILITY 1695 weak_ptr<_Tp> weak_from_this() _NOEXCEPT 1696 { return __weak_this_; } 1697 1698 _LIBCPP_INLINE_VISIBILITY 1699 weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT 1700 { return __weak_this_; } 1701 #endif // _LIBCPP_STD_VER > 14 1702 1703 template <class _Up> friend class shared_ptr; 1704 }; 1705 1706 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash; 1707 1708 template <class _Tp> 1709 struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> > 1710 { 1711 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 1712 _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> argument_type; 1713 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 1714 #endif 1715 1716 _LIBCPP_INLINE_VISIBILITY 1717 size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT 1718 { 1719 return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get()); 1720 } 1721 }; 1722 1723 template<class _CharT, class _Traits, class _Yp> 1724 inline _LIBCPP_INLINE_VISIBILITY 1725 basic_ostream<_CharT, _Traits>& 1726 operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p); 1727 1728 1729 #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) 1730 1731 class _LIBCPP_TYPE_VIS __sp_mut 1732 { 1733 void* __lx; 1734 public: 1735 void lock() _NOEXCEPT; 1736 void unlock() _NOEXCEPT; 1737 1738 private: 1739 _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT; 1740 __sp_mut(const __sp_mut&); 1741 __sp_mut& operator=(const __sp_mut&); 1742 1743 friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*); 1744 }; 1745 1746 _LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1747 __sp_mut& __get_sp_mut(const void*); 1748 1749 template <class _Tp> 1750 inline _LIBCPP_INLINE_VISIBILITY 1751 bool 1752 atomic_is_lock_free(const shared_ptr<_Tp>*) 1753 { 1754 return false; 1755 } 1756 1757 template <class _Tp> 1758 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1759 shared_ptr<_Tp> 1760 atomic_load(const shared_ptr<_Tp>* __p) 1761 { 1762 __sp_mut& __m = __get_sp_mut(__p); 1763 __m.lock(); 1764 shared_ptr<_Tp> __q = *__p; 1765 __m.unlock(); 1766 return __q; 1767 } 1768 1769 template <class _Tp> 1770 inline _LIBCPP_INLINE_VISIBILITY 1771 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1772 shared_ptr<_Tp> 1773 atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order) 1774 { 1775 return atomic_load(__p); 1776 } 1777 1778 template <class _Tp> 1779 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1780 void 1781 atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) 1782 { 1783 __sp_mut& __m = __get_sp_mut(__p); 1784 __m.lock(); 1785 __p->swap(__r); 1786 __m.unlock(); 1787 } 1788 1789 template <class _Tp> 1790 inline _LIBCPP_INLINE_VISIBILITY 1791 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1792 void 1793 atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) 1794 { 1795 atomic_store(__p, __r); 1796 } 1797 1798 template <class _Tp> 1799 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1800 shared_ptr<_Tp> 1801 atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) 1802 { 1803 __sp_mut& __m = __get_sp_mut(__p); 1804 __m.lock(); 1805 __p->swap(__r); 1806 __m.unlock(); 1807 return __r; 1808 } 1809 1810 template <class _Tp> 1811 inline _LIBCPP_INLINE_VISIBILITY 1812 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1813 shared_ptr<_Tp> 1814 atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) 1815 { 1816 return atomic_exchange(__p, __r); 1817 } 1818 1819 template <class _Tp> 1820 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1821 bool 1822 atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) 1823 { 1824 shared_ptr<_Tp> __temp; 1825 __sp_mut& __m = __get_sp_mut(__p); 1826 __m.lock(); 1827 if (__p->__owner_equivalent(*__v)) 1828 { 1829 _VSTD::swap(__temp, *__p); 1830 *__p = __w; 1831 __m.unlock(); 1832 return true; 1833 } 1834 _VSTD::swap(__temp, *__v); 1835 *__v = *__p; 1836 __m.unlock(); 1837 return false; 1838 } 1839 1840 template <class _Tp> 1841 inline _LIBCPP_INLINE_VISIBILITY 1842 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1843 bool 1844 atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) 1845 { 1846 return atomic_compare_exchange_strong(__p, __v, __w); 1847 } 1848 1849 template <class _Tp> 1850 inline _LIBCPP_INLINE_VISIBILITY 1851 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1852 bool 1853 atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, 1854 shared_ptr<_Tp> __w, memory_order, memory_order) 1855 { 1856 return atomic_compare_exchange_strong(__p, __v, __w); 1857 } 1858 1859 template <class _Tp> 1860 inline _LIBCPP_INLINE_VISIBILITY 1861 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1862 bool 1863 atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, 1864 shared_ptr<_Tp> __w, memory_order, memory_order) 1865 { 1866 return atomic_compare_exchange_weak(__p, __v, __w); 1867 } 1868 1869 #endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) 1870 1871 _LIBCPP_END_NAMESPACE_STD 1872 1873 _LIBCPP_POP_MACROS 1874 1875 #endif // _LIBCPP___MEMORY_SHARED_PTR_H 1876