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