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