1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP___MEMORY_SHARED_PTR_H 11 #define _LIBCPP___MEMORY_SHARED_PTR_H 12 13 #include <__availability> 14 #include <__config> 15 #include <__functional_base> // std::less, std::binary_function 16 #include <__memory/addressof.h> 17 #include <__memory/allocation_guard.h> 18 #include <__memory/allocator.h> 19 #include <__memory/allocator_traits.h> 20 #include <__memory/compressed_pair.h> 21 #include <__memory/pointer_traits.h> 22 #include <__memory/unique_ptr.h> 23 #include <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 _Ptr, class = void> 383 struct __is_deletable : false_type { }; 384 template <class _Ptr> 385 struct __is_deletable<_Ptr, decltype(delete declval<_Ptr>())> : true_type { }; 386 387 template <class _Ptr, class = void> 388 struct __is_array_deletable : false_type { }; 389 template <class _Ptr> 390 struct __is_array_deletable<_Ptr, decltype(delete[] declval<_Ptr>())> : true_type { }; 391 392 template <class _Dp, class _Pt, 393 class = decltype(declval<_Dp>()(declval<_Pt>()))> 394 static true_type __well_formed_deleter_test(int); 395 396 template <class, class> 397 static false_type __well_formed_deleter_test(...); 398 399 template <class _Dp, class _Pt> 400 struct __well_formed_deleter : decltype(__well_formed_deleter_test<_Dp, _Pt>(0)) {}; 401 402 template<class _Dp, class _Tp, class _Yp> 403 struct __shared_ptr_deleter_ctor_reqs 404 { 405 static const bool value = __compatible_with<_Tp, _Yp>::value && 406 is_move_constructible<_Dp>::value && 407 __well_formed_deleter<_Dp, _Tp*>::value; 408 }; 409 410 #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI) 411 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi)) 412 #else 413 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI 414 #endif 415 416 template<class _Tp> 417 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr 418 { 419 public: 420 #if _LIBCPP_STD_VER > 14 421 typedef weak_ptr<_Tp> weak_type; 422 typedef remove_extent_t<_Tp> element_type; 423 #else 424 typedef _Tp element_type; 425 #endif 426 427 private: 428 element_type* __ptr_; 429 __shared_weak_count* __cntrl_; 430 431 struct __nat {int __for_bool_;}; 432 public: 433 _LIBCPP_INLINE_VISIBILITY 434 _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT; 435 _LIBCPP_INLINE_VISIBILITY 436 _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT; 437 438 template<class _Yp, class = _EnableIf< 439 _And< 440 __compatible_with<_Yp, _Tp> 441 // In C++03 we get errors when trying to do SFINAE with the 442 // delete operator, so we always pretend that it's deletable. 443 // The same happens on GCC. 444 #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC) 445 , _If<is_array<_Tp>::value, __is_array_deletable<_Yp*>, __is_deletable<_Yp*> > 446 #endif 447 >::value 448 > > 449 explicit shared_ptr(_Yp* __p) : __ptr_(__p) { 450 unique_ptr<_Yp> __hold(__p); 451 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 452 typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk; 453 __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT()); 454 __hold.release(); 455 __enable_weak_this(__p, __p); 456 } 457 458 template<class _Yp, class _Dp> 459 shared_ptr(_Yp* __p, _Dp __d, 460 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat()); 461 template<class _Yp, class _Dp, class _Alloc> 462 shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, 463 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat()); 464 template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d); 465 template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a); 466 template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT; 467 _LIBCPP_INLINE_VISIBILITY 468 shared_ptr(const shared_ptr& __r) _NOEXCEPT; 469 template<class _Yp> 470 _LIBCPP_INLINE_VISIBILITY 471 shared_ptr(const shared_ptr<_Yp>& __r, 472 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat()) 473 _NOEXCEPT; 474 _LIBCPP_INLINE_VISIBILITY 475 shared_ptr(shared_ptr&& __r) _NOEXCEPT; 476 template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(shared_ptr<_Yp>&& __r, 477 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat()) 478 _NOEXCEPT; 479 template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r, 480 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat()); 481 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 482 template<class _Yp> 483 shared_ptr(auto_ptr<_Yp>&& __r, 484 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat()); 485 #endif 486 template <class _Yp, class _Dp> 487 shared_ptr(unique_ptr<_Yp, _Dp>&&, 488 typename enable_if 489 < 490 !is_lvalue_reference<_Dp>::value && 491 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 492 __nat 493 >::type = __nat()); 494 template <class _Yp, class _Dp> 495 shared_ptr(unique_ptr<_Yp, _Dp>&&, 496 typename enable_if 497 < 498 is_lvalue_reference<_Dp>::value && 499 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 500 __nat 501 >::type = __nat()); 502 503 ~shared_ptr(); 504 505 _LIBCPP_INLINE_VISIBILITY 506 shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT; 507 template<class _Yp> 508 typename enable_if 509 < 510 __compatible_with<_Yp, element_type>::value, 511 shared_ptr& 512 >::type 513 _LIBCPP_INLINE_VISIBILITY 514 operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT; 515 _LIBCPP_INLINE_VISIBILITY 516 shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT; 517 template<class _Yp> 518 typename enable_if 519 < 520 __compatible_with<_Yp, element_type>::value, 521 shared_ptr& 522 >::type 523 _LIBCPP_INLINE_VISIBILITY 524 operator=(shared_ptr<_Yp>&& __r); 525 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 526 template<class _Yp> 527 _LIBCPP_INLINE_VISIBILITY 528 typename enable_if 529 < 530 !is_array<_Yp>::value && 531 is_convertible<_Yp*, element_type*>::value, 532 shared_ptr 533 >::type& 534 operator=(auto_ptr<_Yp>&& __r); 535 #endif 536 template <class _Yp, class _Dp> 537 typename enable_if 538 < 539 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 540 shared_ptr& 541 >::type 542 _LIBCPP_INLINE_VISIBILITY 543 operator=(unique_ptr<_Yp, _Dp>&& __r); 544 545 _LIBCPP_INLINE_VISIBILITY 546 void swap(shared_ptr& __r) _NOEXCEPT; 547 _LIBCPP_INLINE_VISIBILITY 548 void reset() _NOEXCEPT; 549 template<class _Yp> 550 typename enable_if 551 < 552 __compatible_with<_Yp, element_type>::value, 553 void 554 >::type 555 _LIBCPP_INLINE_VISIBILITY 556 reset(_Yp* __p); 557 template<class _Yp, class _Dp> 558 typename enable_if 559 < 560 __compatible_with<_Yp, element_type>::value, 561 void 562 >::type 563 _LIBCPP_INLINE_VISIBILITY 564 reset(_Yp* __p, _Dp __d); 565 template<class _Yp, class _Dp, class _Alloc> 566 typename enable_if 567 < 568 __compatible_with<_Yp, element_type>::value, 569 void 570 >::type 571 _LIBCPP_INLINE_VISIBILITY 572 reset(_Yp* __p, _Dp __d, _Alloc __a); 573 574 _LIBCPP_INLINE_VISIBILITY 575 element_type* get() const _NOEXCEPT {return __ptr_;} 576 _LIBCPP_INLINE_VISIBILITY 577 typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT 578 {return *__ptr_;} 579 _LIBCPP_INLINE_VISIBILITY 580 element_type* operator->() const _NOEXCEPT 581 { 582 static_assert(!is_array<_Tp>::value, 583 "std::shared_ptr<T>::operator-> is only valid when T is not an array type."); 584 return __ptr_; 585 } 586 _LIBCPP_INLINE_VISIBILITY 587 long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;} 588 _LIBCPP_INLINE_VISIBILITY 589 bool unique() const _NOEXCEPT {return use_count() == 1;} 590 _LIBCPP_INLINE_VISIBILITY 591 _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return get() != nullptr;} 592 template <class _Up> 593 _LIBCPP_INLINE_VISIBILITY 594 bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT 595 {return __cntrl_ < __p.__cntrl_;} 596 template <class _Up> 597 _LIBCPP_INLINE_VISIBILITY 598 bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT 599 {return __cntrl_ < __p.__cntrl_;} 600 _LIBCPP_INLINE_VISIBILITY 601 bool 602 __owner_equivalent(const shared_ptr& __p) const 603 {return __cntrl_ == __p.__cntrl_;} 604 605 #if _LIBCPP_STD_VER > 14 606 typename add_lvalue_reference<element_type>::type 607 _LIBCPP_INLINE_VISIBILITY 608 operator[](ptrdiff_t __i) const 609 { 610 static_assert(is_array<_Tp>::value, 611 "std::shared_ptr<T>::operator[] is only valid when T is an array type."); 612 return __ptr_[__i]; 613 } 614 #endif 615 616 #ifndef _LIBCPP_NO_RTTI 617 template <class _Dp> 618 _LIBCPP_INLINE_VISIBILITY 619 _Dp* __get_deleter() const _NOEXCEPT 620 {return static_cast<_Dp*>(__cntrl_ 621 ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp))) 622 : nullptr);} 623 #endif // _LIBCPP_NO_RTTI 624 625 template<class _Yp, class _CntrlBlk> 626 static shared_ptr<_Tp> 627 __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT 628 { 629 shared_ptr<_Tp> __r; 630 __r.__ptr_ = __p; 631 __r.__cntrl_ = __cntrl; 632 __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); 633 return __r; 634 } 635 636 private: 637 template <class _Yp, bool = is_function<_Yp>::value> 638 struct __shared_ptr_default_allocator 639 { 640 typedef allocator<_Yp> type; 641 }; 642 643 template <class _Yp> 644 struct __shared_ptr_default_allocator<_Yp, true> 645 { 646 typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type; 647 }; 648 649 template <class _Yp, class _OrigPtr> 650 _LIBCPP_INLINE_VISIBILITY 651 typename enable_if<is_convertible<_OrigPtr*, 652 const enable_shared_from_this<_Yp>* 653 >::value, 654 void>::type 655 __enable_weak_this(const enable_shared_from_this<_Yp>* __e, 656 _OrigPtr* __ptr) _NOEXCEPT 657 { 658 typedef typename remove_cv<_Yp>::type _RawYp; 659 if (__e && __e->__weak_this_.expired()) 660 { 661 __e->__weak_this_ = shared_ptr<_RawYp>(*this, 662 const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr))); 663 } 664 } 665 666 _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {} 667 668 template <class, class _Yp> 669 struct __shared_ptr_default_delete 670 : default_delete<_Yp> {}; 671 672 template <class _Yp, class _Un, size_t _Sz> 673 struct __shared_ptr_default_delete<_Yp[_Sz], _Un> 674 : default_delete<_Yp[]> {}; 675 676 template <class _Yp, class _Un> 677 struct __shared_ptr_default_delete<_Yp[], _Un> 678 : default_delete<_Yp[]> {}; 679 680 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr; 681 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr; 682 }; 683 684 #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES 685 template<class _Tp> 686 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; 687 template<class _Tp, class _Dp> 688 shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>; 689 #endif 690 691 template<class _Tp> 692 inline 693 _LIBCPP_CONSTEXPR 694 shared_ptr<_Tp>::shared_ptr() _NOEXCEPT 695 : __ptr_(nullptr), 696 __cntrl_(nullptr) 697 { 698 } 699 700 template<class _Tp> 701 inline 702 _LIBCPP_CONSTEXPR 703 shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT 704 : __ptr_(nullptr), 705 __cntrl_(nullptr) 706 { 707 } 708 709 template<class _Tp> 710 template<class _Yp, class _Dp> 711 shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, 712 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type) 713 : __ptr_(__p) 714 { 715 #ifndef _LIBCPP_NO_EXCEPTIONS 716 try 717 { 718 #endif // _LIBCPP_NO_EXCEPTIONS 719 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 720 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk; 721 #ifndef _LIBCPP_CXX03_LANG 722 __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT()); 723 #else 724 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); 725 #endif // not _LIBCPP_CXX03_LANG 726 __enable_weak_this(__p, __p); 727 #ifndef _LIBCPP_NO_EXCEPTIONS 728 } 729 catch (...) 730 { 731 __d(__p); 732 throw; 733 } 734 #endif // _LIBCPP_NO_EXCEPTIONS 735 } 736 737 template<class _Tp> 738 template<class _Dp> 739 shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d) 740 : __ptr_(nullptr) 741 { 742 #ifndef _LIBCPP_NO_EXCEPTIONS 743 try 744 { 745 #endif // _LIBCPP_NO_EXCEPTIONS 746 typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT; 747 typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk; 748 #ifndef _LIBCPP_CXX03_LANG 749 __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT()); 750 #else 751 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); 752 #endif // not _LIBCPP_CXX03_LANG 753 #ifndef _LIBCPP_NO_EXCEPTIONS 754 } 755 catch (...) 756 { 757 __d(__p); 758 throw; 759 } 760 #endif // _LIBCPP_NO_EXCEPTIONS 761 } 762 763 template<class _Tp> 764 template<class _Yp, class _Dp, class _Alloc> 765 shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, 766 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type) 767 : __ptr_(__p) 768 { 769 #ifndef _LIBCPP_NO_EXCEPTIONS 770 try 771 { 772 #endif // _LIBCPP_NO_EXCEPTIONS 773 typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk; 774 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; 775 typedef __allocator_destructor<_A2> _D2; 776 _A2 __a2(__a); 777 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); 778 ::new ((void*)_VSTD::addressof(*__hold2.get())) 779 #ifndef _LIBCPP_CXX03_LANG 780 _CntrlBlk(__p, _VSTD::move(__d), __a); 781 #else 782 _CntrlBlk(__p, __d, __a); 783 #endif // not _LIBCPP_CXX03_LANG 784 __cntrl_ = _VSTD::addressof(*__hold2.release()); 785 __enable_weak_this(__p, __p); 786 #ifndef _LIBCPP_NO_EXCEPTIONS 787 } 788 catch (...) 789 { 790 __d(__p); 791 throw; 792 } 793 #endif // _LIBCPP_NO_EXCEPTIONS 794 } 795 796 template<class _Tp> 797 template<class _Dp, class _Alloc> 798 shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a) 799 : __ptr_(nullptr) 800 { 801 #ifndef _LIBCPP_NO_EXCEPTIONS 802 try 803 { 804 #endif // _LIBCPP_NO_EXCEPTIONS 805 typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk; 806 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; 807 typedef __allocator_destructor<_A2> _D2; 808 _A2 __a2(__a); 809 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); 810 ::new ((void*)_VSTD::addressof(*__hold2.get())) 811 #ifndef _LIBCPP_CXX03_LANG 812 _CntrlBlk(__p, _VSTD::move(__d), __a); 813 #else 814 _CntrlBlk(__p, __d, __a); 815 #endif // not _LIBCPP_CXX03_LANG 816 __cntrl_ = _VSTD::addressof(*__hold2.release()); 817 #ifndef _LIBCPP_NO_EXCEPTIONS 818 } 819 catch (...) 820 { 821 __d(__p); 822 throw; 823 } 824 #endif // _LIBCPP_NO_EXCEPTIONS 825 } 826 827 template<class _Tp> 828 template<class _Yp> 829 inline 830 shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT 831 : __ptr_(__p), 832 __cntrl_(__r.__cntrl_) 833 { 834 if (__cntrl_) 835 __cntrl_->__add_shared(); 836 } 837 838 template<class _Tp> 839 inline 840 shared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT 841 : __ptr_(__r.__ptr_), 842 __cntrl_(__r.__cntrl_) 843 { 844 if (__cntrl_) 845 __cntrl_->__add_shared(); 846 } 847 848 template<class _Tp> 849 template<class _Yp> 850 inline 851 shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, 852 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type) 853 _NOEXCEPT 854 : __ptr_(__r.__ptr_), 855 __cntrl_(__r.__cntrl_) 856 { 857 if (__cntrl_) 858 __cntrl_->__add_shared(); 859 } 860 861 template<class _Tp> 862 inline 863 shared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT 864 : __ptr_(__r.__ptr_), 865 __cntrl_(__r.__cntrl_) 866 { 867 __r.__ptr_ = nullptr; 868 __r.__cntrl_ = nullptr; 869 } 870 871 template<class _Tp> 872 template<class _Yp> 873 inline 874 shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r, 875 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type) 876 _NOEXCEPT 877 : __ptr_(__r.__ptr_), 878 __cntrl_(__r.__cntrl_) 879 { 880 __r.__ptr_ = nullptr; 881 __r.__cntrl_ = nullptr; 882 } 883 884 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 885 template<class _Tp> 886 template<class _Yp> 887 shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r, 888 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) 889 : __ptr_(__r.get()) 890 { 891 typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk; 892 __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>()); 893 __enable_weak_this(__r.get(), __r.get()); 894 __r.release(); 895 } 896 #endif 897 898 template<class _Tp> 899 template <class _Yp, class _Dp> 900 shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, 901 typename enable_if 902 < 903 !is_lvalue_reference<_Dp>::value && 904 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 905 __nat 906 >::type) 907 : __ptr_(__r.get()) 908 { 909 #if _LIBCPP_STD_VER > 11 910 if (__ptr_ == nullptr) 911 __cntrl_ = nullptr; 912 else 913 #endif 914 { 915 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 916 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT > _CntrlBlk; 917 __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT()); 918 __enable_weak_this(__r.get(), __r.get()); 919 } 920 __r.release(); 921 } 922 923 template<class _Tp> 924 template <class _Yp, class _Dp> 925 shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, 926 typename enable_if 927 < 928 is_lvalue_reference<_Dp>::value && 929 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 930 __nat 931 >::type) 932 : __ptr_(__r.get()) 933 { 934 #if _LIBCPP_STD_VER > 11 935 if (__ptr_ == nullptr) 936 __cntrl_ = nullptr; 937 else 938 #endif 939 { 940 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 941 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, 942 reference_wrapper<typename remove_reference<_Dp>::type>, 943 _AllocT > _CntrlBlk; 944 __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT()); 945 __enable_weak_this(__r.get(), __r.get()); 946 } 947 __r.release(); 948 } 949 950 template<class _Tp> 951 shared_ptr<_Tp>::~shared_ptr() 952 { 953 if (__cntrl_) 954 __cntrl_->__release_shared(); 955 } 956 957 template<class _Tp> 958 inline 959 shared_ptr<_Tp>& 960 shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT 961 { 962 shared_ptr(__r).swap(*this); 963 return *this; 964 } 965 966 template<class _Tp> 967 template<class _Yp> 968 inline 969 typename enable_if 970 < 971 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, 972 shared_ptr<_Tp>& 973 >::type 974 shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT 975 { 976 shared_ptr(__r).swap(*this); 977 return *this; 978 } 979 980 template<class _Tp> 981 inline 982 shared_ptr<_Tp>& 983 shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT 984 { 985 shared_ptr(_VSTD::move(__r)).swap(*this); 986 return *this; 987 } 988 989 template<class _Tp> 990 template<class _Yp> 991 inline 992 typename enable_if 993 < 994 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, 995 shared_ptr<_Tp>& 996 >::type 997 shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r) 998 { 999 shared_ptr(_VSTD::move(__r)).swap(*this); 1000 return *this; 1001 } 1002 1003 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 1004 template<class _Tp> 1005 template<class _Yp> 1006 inline 1007 typename enable_if 1008 < 1009 !is_array<_Yp>::value && 1010 is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, 1011 shared_ptr<_Tp> 1012 >::type& 1013 shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r) 1014 { 1015 shared_ptr(_VSTD::move(__r)).swap(*this); 1016 return *this; 1017 } 1018 #endif 1019 1020 template<class _Tp> 1021 template <class _Yp, class _Dp> 1022 inline 1023 typename enable_if 1024 < 1025 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, 1026 typename shared_ptr<_Tp>::element_type*>::value, 1027 shared_ptr<_Tp>& 1028 >::type 1029 shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r) 1030 { 1031 shared_ptr(_VSTD::move(__r)).swap(*this); 1032 return *this; 1033 } 1034 1035 template<class _Tp> 1036 inline 1037 void 1038 shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT 1039 { 1040 _VSTD::swap(__ptr_, __r.__ptr_); 1041 _VSTD::swap(__cntrl_, __r.__cntrl_); 1042 } 1043 1044 template<class _Tp> 1045 inline 1046 void 1047 shared_ptr<_Tp>::reset() _NOEXCEPT 1048 { 1049 shared_ptr().swap(*this); 1050 } 1051 1052 template<class _Tp> 1053 template<class _Yp> 1054 inline 1055 typename enable_if 1056 < 1057 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, 1058 void 1059 >::type 1060 shared_ptr<_Tp>::reset(_Yp* __p) 1061 { 1062 shared_ptr(__p).swap(*this); 1063 } 1064 1065 template<class _Tp> 1066 template<class _Yp, class _Dp> 1067 inline 1068 typename enable_if 1069 < 1070 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, 1071 void 1072 >::type 1073 shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d) 1074 { 1075 shared_ptr(__p, __d).swap(*this); 1076 } 1077 1078 template<class _Tp> 1079 template<class _Yp, class _Dp, class _Alloc> 1080 inline 1081 typename enable_if 1082 < 1083 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, 1084 void 1085 >::type 1086 shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a) 1087 { 1088 shared_ptr(__p, __d, __a).swap(*this); 1089 } 1090 1091 // 1092 // std::allocate_shared and std::make_shared 1093 // 1094 template<class _Tp, class _Alloc, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> > 1095 _LIBCPP_HIDE_FROM_ABI 1096 shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args) 1097 { 1098 using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>; 1099 using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type; 1100 __allocation_guard<_ControlBlockAllocator> __guard(__a, 1); 1101 ::new ((void*)_VSTD::addressof(*__guard.__get())) _ControlBlock(__a, _VSTD::forward<_Args>(__args)...); 1102 auto __control_block = __guard.__release_ptr(); 1103 return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block)); 1104 } 1105 1106 template<class _Tp, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> > 1107 _LIBCPP_HIDE_FROM_ABI 1108 shared_ptr<_Tp> make_shared(_Args&& ...__args) 1109 { 1110 return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...); 1111 } 1112 1113 template<class _Tp, class _Up> 1114 inline _LIBCPP_INLINE_VISIBILITY 1115 bool 1116 operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT 1117 { 1118 return __x.get() == __y.get(); 1119 } 1120 1121 template<class _Tp, class _Up> 1122 inline _LIBCPP_INLINE_VISIBILITY 1123 bool 1124 operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT 1125 { 1126 return !(__x == __y); 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 #if _LIBCPP_STD_VER <= 11 1135 typedef typename common_type<_Tp*, _Up*>::type _Vp; 1136 return less<_Vp>()(__x.get(), __y.get()); 1137 #else 1138 return less<>()(__x.get(), __y.get()); 1139 #endif 1140 1141 } 1142 1143 template<class _Tp, class _Up> 1144 inline _LIBCPP_INLINE_VISIBILITY 1145 bool 1146 operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT 1147 { 1148 return __y < __x; 1149 } 1150 1151 template<class _Tp, class _Up> 1152 inline _LIBCPP_INLINE_VISIBILITY 1153 bool 1154 operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT 1155 { 1156 return !(__y < __x); 1157 } 1158 1159 template<class _Tp, class _Up> 1160 inline _LIBCPP_INLINE_VISIBILITY 1161 bool 1162 operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT 1163 { 1164 return !(__x < __y); 1165 } 1166 1167 template<class _Tp> 1168 inline _LIBCPP_INLINE_VISIBILITY 1169 bool 1170 operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1171 { 1172 return !__x; 1173 } 1174 1175 template<class _Tp> 1176 inline _LIBCPP_INLINE_VISIBILITY 1177 bool 1178 operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1179 { 1180 return !__x; 1181 } 1182 1183 template<class _Tp> 1184 inline _LIBCPP_INLINE_VISIBILITY 1185 bool 1186 operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1187 { 1188 return static_cast<bool>(__x); 1189 } 1190 1191 template<class _Tp> 1192 inline _LIBCPP_INLINE_VISIBILITY 1193 bool 1194 operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1195 { 1196 return static_cast<bool>(__x); 1197 } 1198 1199 template<class _Tp> 1200 inline _LIBCPP_INLINE_VISIBILITY 1201 bool 1202 operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1203 { 1204 return less<_Tp*>()(__x.get(), nullptr); 1205 } 1206 1207 template<class _Tp> 1208 inline _LIBCPP_INLINE_VISIBILITY 1209 bool 1210 operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1211 { 1212 return less<_Tp*>()(nullptr, __x.get()); 1213 } 1214 1215 template<class _Tp> 1216 inline _LIBCPP_INLINE_VISIBILITY 1217 bool 1218 operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1219 { 1220 return nullptr < __x; 1221 } 1222 1223 template<class _Tp> 1224 inline _LIBCPP_INLINE_VISIBILITY 1225 bool 1226 operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1227 { 1228 return __x < nullptr; 1229 } 1230 1231 template<class _Tp> 1232 inline _LIBCPP_INLINE_VISIBILITY 1233 bool 1234 operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1235 { 1236 return !(nullptr < __x); 1237 } 1238 1239 template<class _Tp> 1240 inline _LIBCPP_INLINE_VISIBILITY 1241 bool 1242 operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1243 { 1244 return !(__x < nullptr); 1245 } 1246 1247 template<class _Tp> 1248 inline _LIBCPP_INLINE_VISIBILITY 1249 bool 1250 operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT 1251 { 1252 return !(__x < nullptr); 1253 } 1254 1255 template<class _Tp> 1256 inline _LIBCPP_INLINE_VISIBILITY 1257 bool 1258 operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT 1259 { 1260 return !(nullptr < __x); 1261 } 1262 1263 template<class _Tp> 1264 inline _LIBCPP_INLINE_VISIBILITY 1265 void 1266 swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT 1267 { 1268 __x.swap(__y); 1269 } 1270 1271 template<class _Tp, class _Up> 1272 inline _LIBCPP_INLINE_VISIBILITY 1273 shared_ptr<_Tp> 1274 static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT 1275 { 1276 return shared_ptr<_Tp>(__r, 1277 static_cast< 1278 typename shared_ptr<_Tp>::element_type*>(__r.get())); 1279 } 1280 1281 template<class _Tp, class _Up> 1282 inline _LIBCPP_INLINE_VISIBILITY 1283 shared_ptr<_Tp> 1284 dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT 1285 { 1286 typedef typename shared_ptr<_Tp>::element_type _ET; 1287 _ET* __p = dynamic_cast<_ET*>(__r.get()); 1288 return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>(); 1289 } 1290 1291 template<class _Tp, class _Up> 1292 shared_ptr<_Tp> 1293 const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT 1294 { 1295 typedef typename shared_ptr<_Tp>::element_type _RTp; 1296 return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get())); 1297 } 1298 1299 template<class _Tp, class _Up> 1300 shared_ptr<_Tp> 1301 reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT 1302 { 1303 return shared_ptr<_Tp>(__r, 1304 reinterpret_cast< 1305 typename shared_ptr<_Tp>::element_type*>(__r.get())); 1306 } 1307 1308 #ifndef _LIBCPP_NO_RTTI 1309 1310 template<class _Dp, class _Tp> 1311 inline _LIBCPP_INLINE_VISIBILITY 1312 _Dp* 1313 get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT 1314 { 1315 return __p.template __get_deleter<_Dp>(); 1316 } 1317 1318 #endif // _LIBCPP_NO_RTTI 1319 1320 template<class _Tp> 1321 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr 1322 { 1323 public: 1324 typedef _Tp element_type; 1325 private: 1326 element_type* __ptr_; 1327 __shared_weak_count* __cntrl_; 1328 1329 public: 1330 _LIBCPP_INLINE_VISIBILITY 1331 _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT; 1332 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r, 1333 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0) 1334 _NOEXCEPT; 1335 _LIBCPP_INLINE_VISIBILITY 1336 weak_ptr(weak_ptr const& __r) _NOEXCEPT; 1337 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r, 1338 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0) 1339 _NOEXCEPT; 1340 1341 _LIBCPP_INLINE_VISIBILITY 1342 weak_ptr(weak_ptr&& __r) _NOEXCEPT; 1343 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r, 1344 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0) 1345 _NOEXCEPT; 1346 ~weak_ptr(); 1347 1348 _LIBCPP_INLINE_VISIBILITY 1349 weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT; 1350 template<class _Yp> 1351 typename enable_if 1352 < 1353 is_convertible<_Yp*, element_type*>::value, 1354 weak_ptr& 1355 >::type 1356 _LIBCPP_INLINE_VISIBILITY 1357 operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT; 1358 1359 _LIBCPP_INLINE_VISIBILITY 1360 weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT; 1361 template<class _Yp> 1362 typename enable_if 1363 < 1364 is_convertible<_Yp*, element_type*>::value, 1365 weak_ptr& 1366 >::type 1367 _LIBCPP_INLINE_VISIBILITY 1368 operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT; 1369 1370 template<class _Yp> 1371 typename enable_if 1372 < 1373 is_convertible<_Yp*, element_type*>::value, 1374 weak_ptr& 1375 >::type 1376 _LIBCPP_INLINE_VISIBILITY 1377 operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT; 1378 1379 _LIBCPP_INLINE_VISIBILITY 1380 void swap(weak_ptr& __r) _NOEXCEPT; 1381 _LIBCPP_INLINE_VISIBILITY 1382 void reset() _NOEXCEPT; 1383 1384 _LIBCPP_INLINE_VISIBILITY 1385 long use_count() const _NOEXCEPT 1386 {return __cntrl_ ? __cntrl_->use_count() : 0;} 1387 _LIBCPP_INLINE_VISIBILITY 1388 bool expired() const _NOEXCEPT 1389 {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;} 1390 shared_ptr<_Tp> lock() const _NOEXCEPT; 1391 template<class _Up> 1392 _LIBCPP_INLINE_VISIBILITY 1393 bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT 1394 {return __cntrl_ < __r.__cntrl_;} 1395 template<class _Up> 1396 _LIBCPP_INLINE_VISIBILITY 1397 bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT 1398 {return __cntrl_ < __r.__cntrl_;} 1399 1400 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr; 1401 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr; 1402 }; 1403 1404 #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES 1405 template<class _Tp> 1406 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; 1407 #endif 1408 1409 template<class _Tp> 1410 inline 1411 _LIBCPP_CONSTEXPR 1412 weak_ptr<_Tp>::weak_ptr() _NOEXCEPT 1413 : __ptr_(nullptr), 1414 __cntrl_(nullptr) 1415 { 1416 } 1417 1418 template<class _Tp> 1419 inline 1420 weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT 1421 : __ptr_(__r.__ptr_), 1422 __cntrl_(__r.__cntrl_) 1423 { 1424 if (__cntrl_) 1425 __cntrl_->__add_weak(); 1426 } 1427 1428 template<class _Tp> 1429 template<class _Yp> 1430 inline 1431 weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r, 1432 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type) 1433 _NOEXCEPT 1434 : __ptr_(__r.__ptr_), 1435 __cntrl_(__r.__cntrl_) 1436 { 1437 if (__cntrl_) 1438 __cntrl_->__add_weak(); 1439 } 1440 1441 template<class _Tp> 1442 template<class _Yp> 1443 inline 1444 weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r, 1445 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type) 1446 _NOEXCEPT 1447 : __ptr_(__r.__ptr_), 1448 __cntrl_(__r.__cntrl_) 1449 { 1450 if (__cntrl_) 1451 __cntrl_->__add_weak(); 1452 } 1453 1454 template<class _Tp> 1455 inline 1456 weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT 1457 : __ptr_(__r.__ptr_), 1458 __cntrl_(__r.__cntrl_) 1459 { 1460 __r.__ptr_ = nullptr; 1461 __r.__cntrl_ = nullptr; 1462 } 1463 1464 template<class _Tp> 1465 template<class _Yp> 1466 inline 1467 weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r, 1468 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type) 1469 _NOEXCEPT 1470 : __ptr_(__r.__ptr_), 1471 __cntrl_(__r.__cntrl_) 1472 { 1473 __r.__ptr_ = nullptr; 1474 __r.__cntrl_ = nullptr; 1475 } 1476 1477 template<class _Tp> 1478 weak_ptr<_Tp>::~weak_ptr() 1479 { 1480 if (__cntrl_) 1481 __cntrl_->__release_weak(); 1482 } 1483 1484 template<class _Tp> 1485 inline 1486 weak_ptr<_Tp>& 1487 weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT 1488 { 1489 weak_ptr(__r).swap(*this); 1490 return *this; 1491 } 1492 1493 template<class _Tp> 1494 template<class _Yp> 1495 inline 1496 typename enable_if 1497 < 1498 is_convertible<_Yp*, _Tp*>::value, 1499 weak_ptr<_Tp>& 1500 >::type 1501 weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT 1502 { 1503 weak_ptr(__r).swap(*this); 1504 return *this; 1505 } 1506 1507 template<class _Tp> 1508 inline 1509 weak_ptr<_Tp>& 1510 weak_ptr<_Tp>::operator=(weak_ptr&& __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=(weak_ptr<_Yp>&& __r) _NOEXCEPT 1525 { 1526 weak_ptr(_VSTD::move(__r)).swap(*this); 1527 return *this; 1528 } 1529 1530 template<class _Tp> 1531 template<class _Yp> 1532 inline 1533 typename enable_if 1534 < 1535 is_convertible<_Yp*, _Tp*>::value, 1536 weak_ptr<_Tp>& 1537 >::type 1538 weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT 1539 { 1540 weak_ptr(__r).swap(*this); 1541 return *this; 1542 } 1543 1544 template<class _Tp> 1545 inline 1546 void 1547 weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT 1548 { 1549 _VSTD::swap(__ptr_, __r.__ptr_); 1550 _VSTD::swap(__cntrl_, __r.__cntrl_); 1551 } 1552 1553 template<class _Tp> 1554 inline _LIBCPP_INLINE_VISIBILITY 1555 void 1556 swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT 1557 { 1558 __x.swap(__y); 1559 } 1560 1561 template<class _Tp> 1562 inline 1563 void 1564 weak_ptr<_Tp>::reset() _NOEXCEPT 1565 { 1566 weak_ptr().swap(*this); 1567 } 1568 1569 template<class _Tp> 1570 template<class _Yp> 1571 shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r, 1572 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) 1573 : __ptr_(__r.__ptr_), 1574 __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_) 1575 { 1576 if (__cntrl_ == nullptr) 1577 __throw_bad_weak_ptr(); 1578 } 1579 1580 template<class _Tp> 1581 shared_ptr<_Tp> 1582 weak_ptr<_Tp>::lock() const _NOEXCEPT 1583 { 1584 shared_ptr<_Tp> __r; 1585 __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_; 1586 if (__r.__cntrl_) 1587 __r.__ptr_ = __ptr_; 1588 return __r; 1589 } 1590 1591 #if _LIBCPP_STD_VER > 14 1592 template <class _Tp = void> struct owner_less; 1593 #else 1594 template <class _Tp> struct owner_less; 1595 #endif 1596 1597 template <class _Tp> 1598 struct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> > 1599 : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool> 1600 { 1601 typedef bool result_type; 1602 _LIBCPP_INLINE_VISIBILITY 1603 bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT 1604 {return __x.owner_before(__y);} 1605 _LIBCPP_INLINE_VISIBILITY 1606 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT 1607 {return __x.owner_before(__y);} 1608 _LIBCPP_INLINE_VISIBILITY 1609 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT 1610 {return __x.owner_before(__y);} 1611 }; 1612 1613 template <class _Tp> 1614 struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> > 1615 : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool> 1616 { 1617 typedef bool result_type; 1618 _LIBCPP_INLINE_VISIBILITY 1619 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT 1620 {return __x.owner_before(__y);} 1621 _LIBCPP_INLINE_VISIBILITY 1622 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT 1623 {return __x.owner_before(__y);} 1624 _LIBCPP_INLINE_VISIBILITY 1625 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT 1626 {return __x.owner_before(__y);} 1627 }; 1628 1629 #if _LIBCPP_STD_VER > 14 1630 template <> 1631 struct _LIBCPP_TEMPLATE_VIS owner_less<void> 1632 { 1633 template <class _Tp, class _Up> 1634 _LIBCPP_INLINE_VISIBILITY 1635 bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT 1636 {return __x.owner_before(__y);} 1637 template <class _Tp, class _Up> 1638 _LIBCPP_INLINE_VISIBILITY 1639 bool operator()( shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT 1640 {return __x.owner_before(__y);} 1641 template <class _Tp, class _Up> 1642 _LIBCPP_INLINE_VISIBILITY 1643 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT 1644 {return __x.owner_before(__y);} 1645 template <class _Tp, class _Up> 1646 _LIBCPP_INLINE_VISIBILITY 1647 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT 1648 {return __x.owner_before(__y);} 1649 typedef void is_transparent; 1650 }; 1651 #endif 1652 1653 template<class _Tp> 1654 class _LIBCPP_TEMPLATE_VIS enable_shared_from_this 1655 { 1656 mutable weak_ptr<_Tp> __weak_this_; 1657 protected: 1658 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1659 enable_shared_from_this() _NOEXCEPT {} 1660 _LIBCPP_INLINE_VISIBILITY 1661 enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {} 1662 _LIBCPP_INLINE_VISIBILITY 1663 enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT 1664 {return *this;} 1665 _LIBCPP_INLINE_VISIBILITY 1666 ~enable_shared_from_this() {} 1667 public: 1668 _LIBCPP_INLINE_VISIBILITY 1669 shared_ptr<_Tp> shared_from_this() 1670 {return shared_ptr<_Tp>(__weak_this_);} 1671 _LIBCPP_INLINE_VISIBILITY 1672 shared_ptr<_Tp const> shared_from_this() const 1673 {return shared_ptr<const _Tp>(__weak_this_);} 1674 1675 #if _LIBCPP_STD_VER > 14 1676 _LIBCPP_INLINE_VISIBILITY 1677 weak_ptr<_Tp> weak_from_this() _NOEXCEPT 1678 { return __weak_this_; } 1679 1680 _LIBCPP_INLINE_VISIBILITY 1681 weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT 1682 { return __weak_this_; } 1683 #endif // _LIBCPP_STD_VER > 14 1684 1685 template <class _Up> friend class shared_ptr; 1686 }; 1687 1688 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash; 1689 1690 template <class _Tp> 1691 struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> > 1692 { 1693 typedef shared_ptr<_Tp> argument_type; 1694 typedef size_t result_type; 1695 1696 _LIBCPP_INLINE_VISIBILITY 1697 result_type operator()(const argument_type& __ptr) const _NOEXCEPT 1698 { 1699 return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get()); 1700 } 1701 }; 1702 1703 template<class _CharT, class _Traits, class _Yp> 1704 inline _LIBCPP_INLINE_VISIBILITY 1705 basic_ostream<_CharT, _Traits>& 1706 operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p); 1707 1708 1709 #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) 1710 1711 class _LIBCPP_TYPE_VIS __sp_mut 1712 { 1713 void* __lx; 1714 public: 1715 void lock() _NOEXCEPT; 1716 void unlock() _NOEXCEPT; 1717 1718 private: 1719 _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT; 1720 __sp_mut(const __sp_mut&); 1721 __sp_mut& operator=(const __sp_mut&); 1722 1723 friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*); 1724 }; 1725 1726 _LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1727 __sp_mut& __get_sp_mut(const void*); 1728 1729 template <class _Tp> 1730 inline _LIBCPP_INLINE_VISIBILITY 1731 bool 1732 atomic_is_lock_free(const shared_ptr<_Tp>*) 1733 { 1734 return false; 1735 } 1736 1737 template <class _Tp> 1738 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1739 shared_ptr<_Tp> 1740 atomic_load(const shared_ptr<_Tp>* __p) 1741 { 1742 __sp_mut& __m = __get_sp_mut(__p); 1743 __m.lock(); 1744 shared_ptr<_Tp> __q = *__p; 1745 __m.unlock(); 1746 return __q; 1747 } 1748 1749 template <class _Tp> 1750 inline _LIBCPP_INLINE_VISIBILITY 1751 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1752 shared_ptr<_Tp> 1753 atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order) 1754 { 1755 return atomic_load(__p); 1756 } 1757 1758 template <class _Tp> 1759 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1760 void 1761 atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) 1762 { 1763 __sp_mut& __m = __get_sp_mut(__p); 1764 __m.lock(); 1765 __p->swap(__r); 1766 __m.unlock(); 1767 } 1768 1769 template <class _Tp> 1770 inline _LIBCPP_INLINE_VISIBILITY 1771 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1772 void 1773 atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) 1774 { 1775 atomic_store(__p, __r); 1776 } 1777 1778 template <class _Tp> 1779 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1780 shared_ptr<_Tp> 1781 atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) 1782 { 1783 __sp_mut& __m = __get_sp_mut(__p); 1784 __m.lock(); 1785 __p->swap(__r); 1786 __m.unlock(); 1787 return __r; 1788 } 1789 1790 template <class _Tp> 1791 inline _LIBCPP_INLINE_VISIBILITY 1792 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1793 shared_ptr<_Tp> 1794 atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) 1795 { 1796 return atomic_exchange(__p, __r); 1797 } 1798 1799 template <class _Tp> 1800 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1801 bool 1802 atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) 1803 { 1804 shared_ptr<_Tp> __temp; 1805 __sp_mut& __m = __get_sp_mut(__p); 1806 __m.lock(); 1807 if (__p->__owner_equivalent(*__v)) 1808 { 1809 _VSTD::swap(__temp, *__p); 1810 *__p = __w; 1811 __m.unlock(); 1812 return true; 1813 } 1814 _VSTD::swap(__temp, *__v); 1815 *__v = *__p; 1816 __m.unlock(); 1817 return false; 1818 } 1819 1820 template <class _Tp> 1821 inline _LIBCPP_INLINE_VISIBILITY 1822 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1823 bool 1824 atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) 1825 { 1826 return atomic_compare_exchange_strong(__p, __v, __w); 1827 } 1828 1829 template <class _Tp> 1830 inline _LIBCPP_INLINE_VISIBILITY 1831 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1832 bool 1833 atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, 1834 shared_ptr<_Tp> __w, memory_order, memory_order) 1835 { 1836 return atomic_compare_exchange_strong(__p, __v, __w); 1837 } 1838 1839 template <class _Tp> 1840 inline _LIBCPP_INLINE_VISIBILITY 1841 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR 1842 bool 1843 atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, 1844 shared_ptr<_Tp> __w, memory_order, memory_order) 1845 { 1846 return atomic_compare_exchange_weak(__p, __v, __w); 1847 } 1848 1849 #endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) 1850 1851 _LIBCPP_END_NAMESPACE_STD 1852 1853 _LIBCPP_POP_MACROS 1854 1855 #endif // _LIBCPP___MEMORY_SHARED_PTR_H 1856