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