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