Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/bits/shared_ptr_base.h
$ cat -n /usr/include/c++/13/bits/shared_ptr_base.h 1 // shared_ptr and weak_ptr implementation details -*- C++ -*- 2 3 // Copyright (C) 2007-2023 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 //
. 24 25 // GCC Note: Based on files from version 1.32.0 of the Boost library. 26 27 // shared_count.hpp 28 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 29 30 // shared_ptr.hpp 31 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. 32 // Copyright (C) 2001, 2002, 2003 Peter Dimov 33 34 // weak_ptr.hpp 35 // Copyright (C) 2001, 2002, 2003 Peter Dimov 36 37 // enable_shared_from_this.hpp 38 // Copyright (C) 2002 Peter Dimov 39 40 // Distributed under the Boost Software License, Version 1.0. (See 41 // accompanying file LICENSE_1_0.txt or copy at 42 // http://www.boost.org/LICENSE_1_0.txt) 43 44 /** @file bits/shared_ptr_base.h 45 * This is an internal header file, included by other library headers. 46 * Do not attempt to use it directly. @headername{memory} 47 */ 48 49 #ifndef _SHARED_PTR_BASE_H 50 #define _SHARED_PTR_BASE_H 1 51 52 #include
53 #include
54 #include
55 #include
56 #include
57 #include
58 #include
// std::less 59 #include
60 #include
61 #include
62 #include
63 #if __cplusplus >= 202002L 64 # include
// __bit_floor 65 # include
66 # include
// std::align 67 # include
68 #endif 69 70 namespace std _GLIBCXX_VISIBILITY(default) 71 { 72 _GLIBCXX_BEGIN_NAMESPACE_VERSION 73 74 #if _GLIBCXX_USE_DEPRECATED 75 #pragma GCC diagnostic push 76 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 77 template
class auto_ptr; 78 #pragma GCC diagnostic pop 79 #endif 80 81 /** 82 * @brief Exception possibly thrown by @c shared_ptr. 83 * @ingroup exceptions 84 */ 85 class bad_weak_ptr : public std::exception 86 { 87 public: 88 virtual char const* what() const noexcept; 89 90 virtual ~bad_weak_ptr() noexcept; 91 }; 92 93 // Substitute for bad_weak_ptr object in the case of -fno-exceptions. 94 inline void 95 __throw_bad_weak_ptr() 96 { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); } 97 98 using __gnu_cxx::_Lock_policy; 99 using __gnu_cxx::__default_lock_policy; 100 using __gnu_cxx::_S_single; 101 using __gnu_cxx::_S_mutex; 102 using __gnu_cxx::_S_atomic; 103 104 // Empty helper class except when the template argument is _S_mutex. 105 template<_Lock_policy _Lp> 106 class _Mutex_base 107 { 108 protected: 109 // The atomic policy uses fully-fenced builtins, single doesn't care. 110 enum { _S_need_barriers = 0 }; 111 }; 112 113 template<> 114 class _Mutex_base<_S_mutex> 115 : public __gnu_cxx::__mutex 116 { 117 protected: 118 // This policy is used when atomic builtins are not available. 119 // The replacement atomic operations might not have the necessary 120 // memory barriers. 121 enum { _S_need_barriers = 1 }; 122 }; 123 124 template<_Lock_policy _Lp = __default_lock_policy> 125 class _Sp_counted_base 126 : public _Mutex_base<_Lp> 127 { 128 public: 129 _Sp_counted_base() noexcept 130 : _M_use_count(1), _M_weak_count(1) { } 131 132 virtual 133 ~_Sp_counted_base() noexcept 134 { } 135 136 // Called when _M_use_count drops to zero, to release the resources 137 // managed by *this. 138 virtual void 139 _M_dispose() noexcept = 0; 140 141 // Called when _M_weak_count drops to zero. 142 virtual void 143 _M_destroy() noexcept 144 { delete this; } 145 146 virtual void* 147 _M_get_deleter(const std::type_info&) noexcept = 0; 148 149 // Increment the use count (used when the count is greater than zero). 150 void 151 _M_add_ref_copy() 152 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } 153 154 // Increment the use count if it is non-zero, throw otherwise. 155 void 156 _M_add_ref_lock() 157 { 158 if (!_M_add_ref_lock_nothrow()) 159 __throw_bad_weak_ptr(); 160 } 161 162 // Increment the use count if it is non-zero. 163 bool 164 _M_add_ref_lock_nothrow() noexcept; 165 166 // Decrement the use count. 167 void 168 _M_release() noexcept; 169 170 // Called by _M_release() when the use count reaches zero. 171 void 172 _M_release_last_use() noexcept 173 { 174 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); 175 _M_dispose(); 176 // There must be a memory barrier between dispose() and destroy() 177 // to ensure that the effects of dispose() are observed in the 178 // thread that runs destroy(). 179 // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html 180 if (_Mutex_base<_Lp>::_S_need_barriers) 181 { 182 __atomic_thread_fence (__ATOMIC_ACQ_REL); 183 } 184 185 // Be race-detector-friendly. For more info see bits/c++config. 186 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 187 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, 188 -1) == 1) 189 { 190 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 191 _M_destroy(); 192 } 193 } 194 195 // As above, but 'noinline' to reduce code size on the cold path. 196 __attribute__((__noinline__)) 197 void 198 _M_release_last_use_cold() noexcept 199 { _M_release_last_use(); } 200 201 // Increment the weak count. 202 void 203 _M_weak_add_ref() noexcept 204 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } 205 206 // Decrement the weak count. 207 void 208 _M_weak_release() noexcept 209 { 210 // Be race-detector-friendly. For more info see bits/c++config. 211 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 212 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) 213 { 214 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 215 if (_Mutex_base<_Lp>::_S_need_barriers) 216 { 217 // See _M_release(), 218 // destroy() must observe results of dispose() 219 __atomic_thread_fence (__ATOMIC_ACQ_REL); 220 } 221 _M_destroy(); 222 } 223 } 224 225 long 226 _M_get_use_count() const noexcept 227 { 228 // No memory barrier is used here so there is no synchronization 229 // with other threads. 230 return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED); 231 } 232 233 private: 234 _Sp_counted_base(_Sp_counted_base const&) = delete; 235 _Sp_counted_base& operator=(_Sp_counted_base const&) = delete; 236 237 _Atomic_word _M_use_count; // #shared 238 _Atomic_word _M_weak_count; // #weak + (#shared != 0) 239 }; 240 241 template<> 242 inline bool 243 _Sp_counted_base<_S_single>:: 244 _M_add_ref_lock_nothrow() noexcept 245 { 246 if (_M_use_count == 0) 247 return false; 248 ++_M_use_count; 249 return true; 250 } 251 252 template<> 253 inline bool 254 _Sp_counted_base<_S_mutex>:: 255 _M_add_ref_lock_nothrow() noexcept 256 { 257 __gnu_cxx::__scoped_lock sentry(*this); 258 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 259 { 260 _M_use_count = 0; 261 return false; 262 } 263 return true; 264 } 265 266 template<> 267 inline bool 268 _Sp_counted_base<_S_atomic>:: 269 _M_add_ref_lock_nothrow() noexcept 270 { 271 // Perform lock-free add-if-not-zero operation. 272 _Atomic_word __count = _M_get_use_count(); 273 do 274 { 275 if (__count == 0) 276 return false; 277 // Replace the current counter value with the old value + 1, as 278 // long as it's not changed meanwhile. 279 } 280 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, 281 true, __ATOMIC_ACQ_REL, 282 __ATOMIC_RELAXED)); 283 return true; 284 } 285 286 template<> 287 inline void 288 _Sp_counted_base<_S_single>::_M_add_ref_copy() 289 { ++_M_use_count; } 290 291 template<> 292 inline void 293 _Sp_counted_base<_S_single>::_M_release() noexcept 294 { 295 if (--_M_use_count == 0) 296 { 297 _M_dispose(); 298 if (--_M_weak_count == 0) 299 _M_destroy(); 300 } 301 } 302 303 template<> 304 inline void 305 _Sp_counted_base<_S_mutex>::_M_release() noexcept 306 { 307 // Be race-detector-friendly. For more info see bits/c++config. 308 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); 309 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) 310 { 311 _M_release_last_use(); 312 } 313 } 314 315 template<> 316 inline void 317 _Sp_counted_base<_S_atomic>::_M_release() noexcept 318 { 319 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); 320 #if ! _GLIBCXX_TSAN 321 constexpr bool __lock_free 322 = __atomic_always_lock_free(sizeof(long long), 0) 323 && __atomic_always_lock_free(sizeof(_Atomic_word), 0); 324 constexpr bool __double_word 325 = sizeof(long long) == 2 * sizeof(_Atomic_word); 326 // The ref-count members follow the vptr, so are aligned to 327 // alignof(void*). 328 constexpr bool __aligned = __alignof(long long) <= alignof(void*); 329 if _GLIBCXX17_CONSTEXPR (__lock_free && __double_word && __aligned) 330 { 331 constexpr int __wordbits = __CHAR_BIT__ * sizeof(_Atomic_word); 332 constexpr int __shiftbits = __double_word ? __wordbits : 0; 333 constexpr long long __unique_ref = 1LL + (1LL << __shiftbits); 334 auto __both_counts = reinterpret_cast
(&_M_use_count); 335 336 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 337 if (__atomic_load_n(__both_counts, __ATOMIC_ACQUIRE) == __unique_ref) 338 { 339 // Both counts are 1, so there are no weak references and 340 // we are releasing the last strong reference. No other 341 // threads can observe the effects of this _M_release() 342 // call (e.g. calling use_count()) without a data race. 343 _M_weak_count = _M_use_count = 0; 344 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); 345 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 346 _M_dispose(); 347 _M_destroy(); 348 return; 349 } 350 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) 351 [[__unlikely__]] 352 { 353 _M_release_last_use_cold(); 354 return; 355 } 356 } 357 else 358 #endif 359 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) 360 { 361 _M_release_last_use(); 362 } 363 } 364 365 template<> 366 inline void 367 _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept 368 { ++_M_weak_count; } 369 370 template<> 371 inline void 372 _Sp_counted_base<_S_single>::_M_weak_release() noexcept 373 { 374 if (--_M_weak_count == 0) 375 _M_destroy(); 376 } 377 378 template<> 379 inline long 380 _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept 381 { return _M_use_count; } 382 383 384 // Forward declarations. 385 template
386 class __shared_ptr; 387 388 template
389 class __weak_ptr; 390 391 template
392 class __enable_shared_from_this; 393 394 template
395 class shared_ptr; 396 397 template
398 class weak_ptr; 399 400 template
401 struct owner_less; 402 403 template
404 class enable_shared_from_this; 405 406 template<_Lock_policy _Lp = __default_lock_policy> 407 class __weak_count; 408 409 template<_Lock_policy _Lp = __default_lock_policy> 410 class __shared_count; 411 412 #if __cplusplus >= 202002L 413 template
414 class _Sp_atomic; 415 #endif 416 417 // Counted ptr with no deleter or allocator support 418 template
419 class _Sp_counted_ptr final : public _Sp_counted_base<_Lp> 420 { 421 public: 422 explicit 423 _Sp_counted_ptr(_Ptr __p) noexcept 424 : _M_ptr(__p) { } 425 426 virtual void 427 _M_dispose() noexcept 428 { delete _M_ptr; } 429 430 virtual void 431 _M_destroy() noexcept 432 { delete this; } 433 434 virtual void* 435 _M_get_deleter(const std::type_info&) noexcept 436 { return nullptr; } 437 438 _Sp_counted_ptr(const _Sp_counted_ptr&) = delete; 439 _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete; 440 441 private: 442 _Ptr _M_ptr; 443 }; 444 445 template<> 446 inline void 447 _Sp_counted_ptr
::_M_dispose() noexcept { } 448 449 template<> 450 inline void 451 _Sp_counted_ptr
::_M_dispose() noexcept { } 452 453 template<> 454 inline void 455 _Sp_counted_ptr
::_M_dispose() noexcept { } 456 457 // FIXME: once __has_cpp_attribute(__no_unique_address__)) is true for 458 // all supported compilers we can greatly simplify _Sp_ebo_helper. 459 // N.B. unconditionally applying the attribute could change layout for 460 // final types, which currently cannot use EBO so have a unique address. 461 462 template
464 struct _Sp_ebo_helper; 465 466 /// Specialization using EBO. 467 template
468 struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp 469 { 470 explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { } 471 explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { } 472 473 static _Tp& 474 _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); } 475 }; 476 477 /// Specialization not using EBO. 478 template
479 struct _Sp_ebo_helper<_Nm, _Tp, false> 480 { 481 explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { } 482 explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(std::move(__tp)) { } 483 484 static _Tp& 485 _S_get(_Sp_ebo_helper& __eboh) 486 { return __eboh._M_tp; } 487 488 private: 489 _Tp _M_tp; 490 }; 491 492 // Support for custom deleter and/or allocator 493 template
494 class _Sp_counted_deleter final : public _Sp_counted_base<_Lp> 495 { 496 class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc> 497 { 498 typedef _Sp_ebo_helper<0, _Deleter> _Del_base; 499 typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base; 500 501 public: 502 _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept 503 : _Del_base(std::move(__d)), _Alloc_base(__a), _M_ptr(__p) 504 { } 505 506 _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); } 507 _Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); } 508 509 _Ptr _M_ptr; 510 }; 511 512 public: 513 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>; 514 515 // __d(__p) must not throw. 516 _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept 517 : _M_impl(__p, std::move(__d), _Alloc()) { } 518 519 // __d(__p) must not throw. 520 _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept 521 : _M_impl(__p, std::move(__d), __a) { } 522 523 ~_Sp_counted_deleter() noexcept { } 524 525 virtual void 526 _M_dispose() noexcept 527 { _M_impl._M_del()(_M_impl._M_ptr); } 528 529 virtual void 530 _M_destroy() noexcept 531 { 532 __allocator_type __a(_M_impl._M_alloc()); 533 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; 534 this->~_Sp_counted_deleter(); 535 } 536 537 virtual void* 538 _M_get_deleter(const type_info& __ti [[__gnu__::__unused__]]) noexcept 539 { 540 #if __cpp_rtti 541 // _GLIBCXX_RESOLVE_LIB_DEFECTS 542 // 2400. shared_ptr's get_deleter() should use addressof() 543 return __ti == typeid(_Deleter) 544 ? std::__addressof(_M_impl._M_del()) 545 : nullptr; 546 #else 547 return nullptr; 548 #endif 549 } 550 551 private: 552 _Impl _M_impl; 553 }; 554 555 // helpers for make_shared / allocate_shared 556 557 struct _Sp_make_shared_tag 558 { 559 private: 560 template
561 friend class _Sp_counted_ptr_inplace; 562 563 static const type_info& 564 _S_ti() noexcept _GLIBCXX_VISIBILITY(default) 565 { 566 alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { }; 567 return reinterpret_cast
(__tag); 568 } 569 570 static bool _S_eq(const type_info&) noexcept; 571 }; 572 573 template
574 struct _Sp_alloc_shared_tag 575 { 576 const _Alloc& _M_a; 577 }; 578 579 template
580 class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> 581 { 582 class _Impl : _Sp_ebo_helper<0, _Alloc> 583 { 584 typedef _Sp_ebo_helper<0, _Alloc> _A_base; 585 586 public: 587 explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { } 588 589 _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); } 590 591 __gnu_cxx::__aligned_buffer<_Tp> _M_storage; 592 }; 593 594 public: 595 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>; 596 597 // Alloc parameter is not a reference so doesn't alias anything in __args 598 template
599 _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args) 600 : _M_impl(__a) 601 { 602 // _GLIBCXX_RESOLVE_LIB_DEFECTS 603 // 2070. allocate_shared should use allocator_traits
::construct 604 allocator_traits<_Alloc>::construct(__a, _M_ptr(), 605 std::forward<_Args>(__args)...); // might throw 606 } 607 608 ~_Sp_counted_ptr_inplace() noexcept { } 609 610 virtual void 611 _M_dispose() noexcept 612 { 613 allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr()); 614 } 615 616 // Override because the allocator needs to know the dynamic type 617 virtual void 618 _M_destroy() noexcept 619 { 620 __allocator_type __a(_M_impl._M_alloc()); 621 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; 622 this->~_Sp_counted_ptr_inplace(); 623 } 624 625 private: 626 friend class __shared_count<_Lp>; // To be able to call _M_ptr(). 627 628 // No longer used, but code compiled against old libstdc++ headers 629 // might still call it from __shared_ptr ctor to get the pointer out. 630 virtual void* 631 _M_get_deleter(const std::type_info& __ti) noexcept override 632 { 633 auto __ptr = const_cast
::type*>(_M_ptr()); 634 // Check for the fake type_info first, so we don't try to access it 635 // as a real type_info object. Otherwise, check if it's the real 636 // type_info for this class. With RTTI enabled we can check directly, 637 // or call a library function to do it. 638 if (&__ti == &_Sp_make_shared_tag::_S_ti() 639 || 640 #if __cpp_rtti 641 __ti == typeid(_Sp_make_shared_tag) 642 #else 643 _Sp_make_shared_tag::_S_eq(__ti) 644 #endif 645 ) 646 return __ptr; 647 return nullptr; 648 } 649 650 _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); } 651 652 _Impl _M_impl; 653 }; 654 655 #if __cplusplus >= 202002L 656 # define __cpp_lib_smart_ptr_for_overwrite 202002L 657 struct _Sp_overwrite_tag { }; 658 659 // Partial specialization used for make_shared_for_overwrite
(). 660 // This partial specialization is used when the allocator's value type 661 // is the special _Sp_overwrite_tag type. 662 #if __cpp_concepts 663 template
664 requires is_same_v
665 class _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> final 666 #else 667 template
class _Alloc, _Lock_policy _Lp> 668 class _Sp_counted_ptr_inplace<_Tp, _Alloc<_Sp_overwrite_tag>, _Lp> final 669 #endif 670 : public _Sp_counted_base<_Lp> 671 { 672 [[no_unique_address]] _Alloc _M_alloc; 673 674 union { 675 _Tp _M_obj; 676 char _M_unused; 677 }; 678 679 friend class __shared_count<_Lp>; // To be able to call _M_ptr(). 680 681 _Tp* _M_ptr() noexcept { return std::__addressof(_M_obj); } 682 683 public: 684 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>; 685 686 _Sp_counted_ptr_inplace(const _Alloc& __a) 687 : _M_alloc(__a) 688 { 689 ::new((void*)_M_ptr()) _Tp; // default-initialized, for overwrite. 690 } 691 692 ~_Sp_counted_ptr_inplace() noexcept { } 693 694 virtual void 695 _M_dispose() noexcept 696 { 697 _M_obj.~_Tp(); 698 } 699 700 // Override because the allocator needs to know the dynamic type 701 virtual void 702 _M_destroy() noexcept 703 { 704 using pointer = typename allocator_traits<__allocator_type>::pointer; 705 __allocator_type __a(_M_alloc); 706 auto __p = pointer_traits
::pointer_to(*this); 707 __allocated_ptr<__allocator_type> __guard_ptr{ __a, __p }; 708 this->~_Sp_counted_ptr_inplace(); 709 } 710 711 void* 712 _M_get_deleter(const std::type_info&) noexcept override 713 { return nullptr; } 714 }; 715 #endif // C++20 716 717 #if __cplusplus <= 201703L 718 # define __cpp_lib_shared_ptr_arrays 201611L 719 #else 720 # define __cpp_lib_shared_ptr_arrays 201707L 721 722 struct _Sp_overwrite_tag; 723 724 // For make_shared
, make_shared
, allocate_shared
etc. 725 template
726 struct _Sp_counted_array_base 727 { 728 [[no_unique_address]] _Alloc _M_alloc{}; 729 size_t _M_n = 0; 730 bool _M_overwrite = false; 731 732 typename allocator_traits<_Alloc>::pointer 733 _M_alloc_array(size_t __tail) 734 { 735 return allocator_traits<_Alloc>::allocate(_M_alloc, _M_n + __tail); 736 } 737 738 void 739 _M_dealloc_array(typename allocator_traits<_Alloc>::pointer __p, 740 size_t __tail) 741 { 742 allocator_traits<_Alloc>::deallocate(_M_alloc, __p, _M_n + __tail); 743 } 744 745 // Init the array elements 746 template
747 void 748 _M_init(typename allocator_traits<_Alloc>::value_type* __p, 749 _Init __init) 750 { 751 using _Tp = remove_pointer_t<_Init>; 752 using _Up = typename allocator_traits<_Alloc>::value_type; 753 754 if constexpr (is_same_v<_Init, _Sp_overwrite_tag>) 755 { 756 std::uninitialized_default_construct_n(__p, _M_n); 757 _M_overwrite = true; 758 } 759 else if (__init == nullptr) 760 std::__uninitialized_default_n_a(__p, _M_n, _M_alloc); 761 else if constexpr (!is_array_v<_Tp>) 762 std::__uninitialized_fill_n_a(__p, _M_n, *__init, _M_alloc); 763 else 764 { 765 #pragma GCC diagnostic push 766 #pragma GCC diagnostic ignored "-Wunused-local-typedefs" 767 struct _Iter 768 { 769 using value_type = _Up; 770 using difference_type = ptrdiff_t; 771 using pointer = const _Up*; 772 using reference = const _Up&; 773 using iterator_category = forward_iterator_tag; 774 775 const _Up* _M_p; 776 size_t _M_len; 777 size_t _M_pos; 778 779 _Iter& operator++() { ++_M_pos; return *this; } 780 _Iter operator++(int) { auto __i(*this); ++_M_pos; return __i; } 781 782 reference operator*() const { return _M_p[_M_pos % _M_len]; } 783 pointer operator->() const { return _M_p + (_M_pos % _M_len); } 784 785 bool operator==(const _Iter& __i) const 786 { return _M_pos == __i._M_pos; } 787 }; 788 #pragma GCC diagnostic pop 789 790 _Iter __first{_S_first_elem(__init), sizeof(_Tp) / sizeof(_Up)}; 791 _Iter __last = __first; 792 __last._M_pos = _M_n; 793 std::__uninitialized_copy_a(__first, __last, __p, _M_alloc); 794 } 795 } 796 797 protected: 798 // Destroy the array elements 799 void 800 _M_dispose_array(typename allocator_traits<_Alloc>::value_type* __p) 801 { 802 if (_M_overwrite) 803 std::destroy_n(__p, _M_n); 804 else 805 { 806 size_t __n = _M_n; 807 while (__n--) 808 allocator_traits<_Alloc>::destroy(_M_alloc, __p + __n); 809 } 810 } 811 812 private: 813 template
814 static _Tp* 815 _S_first_elem(_Tp* __p) { return __p; } 816 817 template
818 static auto 819 _S_first_elem(_Tp (*__p)[_Nm]) { return _S_first_elem(*__p); } 820 }; 821 822 // Control block for make_shared
, make_shared
etc. that will be 823 // placed into unused memory at the end of the array. 824 template
825 class _Sp_counted_array final 826 : public _Sp_counted_base<_Lp>, _Sp_counted_array_base<_Alloc> 827 { 828 using pointer = typename allocator_traits<_Alloc>::pointer; 829 830 pointer _M_alloc_ptr; 831 832 auto _M_ptr() const noexcept { return std::to_address(_M_alloc_ptr); } 833 834 friend class __shared_count<_Lp>; // To be able to call _M_ptr(). 835 836 public: 837 _Sp_counted_array(const _Sp_counted_array_base<_Alloc>& __a, 838 pointer __p) noexcept 839 : _Sp_counted_array_base<_Alloc>(__a), _M_alloc_ptr(__p) 840 { } 841 842 ~_Sp_counted_array() = default; 843 844 virtual void 845 _M_dispose() noexcept 846 { 847 if (this->_M_n) 848 this->_M_dispose_array(_M_ptr()); 849 } 850 851 // Override because the allocator needs to know the dynamic type 852 virtual void 853 _M_destroy() noexcept 854 { 855 _Sp_counted_array_base<_Alloc> __a = *this; 856 pointer __p = _M_alloc_ptr; 857 this->~_Sp_counted_array(); 858 __a._M_dealloc_array(__p, _S_tail()); 859 } 860 861 // Returns the number of additional array elements that must be 862 // allocated in order to store a _Sp_counted_array at the end. 863 static constexpr size_t 864 _S_tail() 865 { 866 // The array elemenent type. 867 using _Tp = typename allocator_traits<_Alloc>::value_type; 868 869 // The space needed to store a _Sp_counted_array object. 870 size_t __bytes = sizeof(_Sp_counted_array); 871 872 // Add any padding needed for manual alignment within the buffer. 873 if constexpr (alignof(_Tp) < alignof(_Sp_counted_array)) 874 __bytes += alignof(_Sp_counted_array) - alignof(_Tp); 875 876 return (__bytes + sizeof(_Tp) - 1) / sizeof(_Tp); 877 } 878 879 void* 880 _M_get_deleter(const std::type_info&) noexcept override 881 { return nullptr; } 882 }; 883 #endif // C++20 884 885 // The default deleter for shared_ptr
and shared_ptr
. 886 struct __sp_array_delete 887 { 888 template
889 void operator()(_Yp* __p) const { delete[] __p; } 890 }; 891 892 template<_Lock_policy _Lp> 893 class __shared_count 894 { 895 // Prevent _Sp_alloc_shared_tag from matching the shared_ptr(P, D) ctor. 896 template
897 struct __not_alloc_shared_tag { using type = void; }; 898 899 template
900 struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { }; 901 902 #if __cpp_lib_shared_ptr_arrays >= 201707L 903 template
904 struct __not_alloc_shared_tag<_Sp_counted_array_base<_Alloc>> { }; 905 #endif 906 907 public: 908 constexpr __shared_count() noexcept : _M_pi(0) 909 { } 910 911 template
912 explicit 913 __shared_count(_Ptr __p) : _M_pi(0) 914 { 915 __try 916 { 917 _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); 918 } 919 __catch(...) 920 { 921 delete __p; 922 __throw_exception_again; 923 } 924 } 925 926 template
927 __shared_count(_Ptr __p, /* is_array = */ false_type) 928 : __shared_count(__p) 929 { } 930 931 template
932 __shared_count(_Ptr __p, /* is_array = */ true_type) 933 : __shared_count(__p, __sp_array_delete{}, allocator
()) 934 { } 935 936 template
::type> 938 __shared_count(_Ptr __p, _Deleter __d) 939 : __shared_count(__p, std::move(__d), allocator
()) 940 { } 941 942 template
::type> 944 __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) 945 { 946 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; 947 __try 948 { 949 typename _Sp_cd_type::__allocator_type __a2(__a); 950 auto __guard = std::__allocate_guarded(__a2); 951 _Sp_cd_type* __mem = __guard.get(); 952 ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a)); 953 _M_pi = __mem; 954 __guard = nullptr; 955 } 956 __catch(...) 957 { 958 __d(__p); // Call _Deleter on __p. 959 __throw_exception_again; 960 } 961 } 962 963 template
964 __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a, 965 _Args&&... __args) 966 { 967 typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type; 968 typename _Sp_cp_type::__allocator_type __a2(__a._M_a); 969 auto __guard = std::__allocate_guarded(__a2); 970 _Sp_cp_type* __mem = __guard.get(); 971 auto __pi = ::new (__mem) 972 _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...); 973 __guard = nullptr; 974 _M_pi = __pi; 975 __p = __pi->_M_ptr(); 976 } 977 978 #if __cpp_lib_shared_ptr_arrays >= 201707L 979 template
980 __shared_count(_Tp*& __p, const _Sp_counted_array_base<_Alloc>& __a, 981 _Init __init) 982 { 983 using _Up = remove_all_extents_t<_Tp>; 984 static_assert(is_same_v<_Up, typename _Alloc::value_type>); 985 986 using _Sp_ca_type = _Sp_counted_array<_Alloc, _Lp>; 987 const size_t __tail = _Sp_ca_type::_S_tail(); 988 989 struct _Guarded_ptr : _Sp_counted_array_base<_Alloc> 990 { 991 typename allocator_traits<_Alloc>::pointer _M_ptr; 992 993 _Guarded_ptr(_Sp_counted_array_base<_Alloc> __a) 994 : _Sp_counted_array_base<_Alloc>(__a), 995 _M_ptr(this->_M_alloc_array(_Sp_ca_type::_S_tail())) 996 { } 997 998 ~_Guarded_ptr() 999 { 1000 if (_M_ptr) 1001 this->_M_dealloc_array(_M_ptr, _Sp_ca_type::_S_tail()); 1002 } 1003 }; 1004 1005 _Guarded_ptr __guard{__a}; 1006 _Up* const __raw = std::to_address(__guard._M_ptr); 1007 __guard._M_init(__raw, __init); // might throw 1008 1009 void* __c = __raw + __a._M_n; 1010 if constexpr (alignof(_Up) < alignof(_Sp_ca_type)) 1011 { 1012 size_t __space = sizeof(_Up) * __tail; 1013 __c = std::align(alignof(_Sp_ca_type), sizeof(_Sp_ca_type), 1014 __c, __space); 1015 } 1016 auto __pi = ::new(__c) _Sp_ca_type(__guard, __guard._M_ptr); 1017 __guard._M_ptr = nullptr; 1018 _M_pi = __pi; 1019 __p = reinterpret_cast<_Tp*>(__raw); 1020 } 1021 #endif 1022 1023 #if _GLIBCXX_USE_DEPRECATED 1024 #pragma GCC diagnostic push 1025 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 1026 // Special case for auto_ptr<_Tp> to provide the strong guarantee. 1027 template
1028 explicit 1029 __shared_count(std::auto_ptr<_Tp>&& __r); 1030 #pragma GCC diagnostic pop 1031 #endif 1032 1033 // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee. 1034 template
1035 explicit 1036 __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0) 1037 { 1038 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1039 // 2415. Inconsistency between unique_ptr and shared_ptr 1040 if (__r.get() == nullptr) 1041 return; 1042 1043 using _Ptr = typename unique_ptr<_Tp, _Del>::pointer; 1044 using _Del2 = __conditional_t
::value, 1045 reference_wrapper
::type>, 1046 _Del>; 1047 using _Sp_cd_type 1048 = _Sp_counted_deleter<_Ptr, _Del2, allocator
, _Lp>; 1049 using _Alloc = allocator<_Sp_cd_type>; 1050 using _Alloc_traits = allocator_traits<_Alloc>; 1051 _Alloc __a; 1052 _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1); 1053 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1054 // 3548. shared_ptr construction from unique_ptr should move 1055 // (not copy) the deleter 1056 _Alloc_traits::construct(__a, __mem, __r.release(), 1057 std::forward<_Del>(__r.get_deleter())); 1058 _M_pi = __mem; 1059 } 1060 1061 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 1062 explicit __shared_count(const __weak_count<_Lp>& __r); 1063 1064 // Does not throw if __r._M_get_use_count() == 0, caller must check. 1065 explicit 1066 __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept; 1067 1068 ~__shared_count() noexcept 1069 { 1070 if (_M_pi != nullptr) 1071 _M_pi->_M_release(); 1072 } 1073 1074 __shared_count(const __shared_count& __r) noexcept 1075 : _M_pi(__r._M_pi) 1076 { 1077 if (_M_pi != nullptr) 1078 _M_pi->_M_add_ref_copy(); 1079 } 1080 1081 __shared_count& 1082 operator=(const __shared_count& __r) noexcept 1083 { 1084 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 1085 if (__tmp != _M_pi) 1086 { 1087 if (__tmp != nullptr) 1088 __tmp->_M_add_ref_copy(); 1089 if (_M_pi != nullptr) 1090 _M_pi->_M_release(); 1091 _M_pi = __tmp; 1092 } 1093 return *this; 1094 } 1095 1096 void 1097 _M_swap(__shared_count& __r) noexcept 1098 { 1099 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 1100 __r._M_pi = _M_pi; 1101 _M_pi = __tmp; 1102 } 1103 1104 long 1105 _M_get_use_count() const noexcept 1106 { return _M_pi ? _M_pi->_M_get_use_count() : 0; } 1107 1108 bool 1109 _M_unique() const noexcept 1110 { return this->_M_get_use_count() == 1; } 1111 1112 void* 1113 _M_get_deleter(const std::type_info& __ti) const noexcept 1114 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; } 1115 1116 bool 1117 _M_less(const __shared_count& __rhs) const noexcept 1118 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 1119 1120 bool 1121 _M_less(const __weak_count<_Lp>& __rhs) const noexcept 1122 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 1123 1124 // Friend function injected into enclosing namespace and found by ADL 1125 friend inline bool 1126 operator==(const __shared_count& __a, const __shared_count& __b) noexcept 1127 { return __a._M_pi == __b._M_pi; } 1128 1129 private: 1130 friend class __weak_count<_Lp>; 1131 #if __cplusplus >= 202002L 1132 template
friend class _Sp_atomic; 1133 #endif 1134 1135 _Sp_counted_base<_Lp>* _M_pi; 1136 }; 1137 1138 1139 template<_Lock_policy _Lp> 1140 class __weak_count 1141 { 1142 public: 1143 constexpr __weak_count() noexcept : _M_pi(nullptr) 1144 { } 1145 1146 __weak_count(const __shared_count<_Lp>& __r) noexcept 1147 : _M_pi(__r._M_pi) 1148 { 1149 if (_M_pi != nullptr) 1150 _M_pi->_M_weak_add_ref(); 1151 } 1152 1153 __weak_count(const __weak_count& __r) noexcept 1154 : _M_pi(__r._M_pi) 1155 { 1156 if (_M_pi != nullptr) 1157 _M_pi->_M_weak_add_ref(); 1158 } 1159 1160 __weak_count(__weak_count&& __r) noexcept 1161 : _M_pi(__r._M_pi) 1162 { __r._M_pi = nullptr; } 1163 1164 ~__weak_count() noexcept 1165 { 1166 if (_M_pi != nullptr) 1167 _M_pi->_M_weak_release(); 1168 } 1169 1170 __weak_count& 1171 operator=(const __shared_count<_Lp>& __r) noexcept 1172 { 1173 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 1174 if (__tmp != nullptr) 1175 __tmp->_M_weak_add_ref(); 1176 if (_M_pi != nullptr) 1177 _M_pi->_M_weak_release(); 1178 _M_pi = __tmp; 1179 return *this; 1180 } 1181 1182 __weak_count& 1183 operator=(const __weak_count& __r) noexcept 1184 { 1185 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 1186 if (__tmp != nullptr) 1187 __tmp->_M_weak_add_ref(); 1188 if (_M_pi != nullptr) 1189 _M_pi->_M_weak_release(); 1190 _M_pi = __tmp; 1191 return *this; 1192 } 1193 1194 __weak_count& 1195 operator=(__weak_count&& __r) noexcept 1196 { 1197 if (_M_pi != nullptr) 1198 _M_pi->_M_weak_release(); 1199 _M_pi = __r._M_pi; 1200 __r._M_pi = nullptr; 1201 return *this; 1202 } 1203 1204 void 1205 _M_swap(__weak_count& __r) noexcept 1206 { 1207 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 1208 __r._M_pi = _M_pi; 1209 _M_pi = __tmp; 1210 } 1211 1212 long 1213 _M_get_use_count() const noexcept 1214 { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; } 1215 1216 bool 1217 _M_less(const __weak_count& __rhs) const noexcept 1218 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 1219 1220 bool 1221 _M_less(const __shared_count<_Lp>& __rhs) const noexcept 1222 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 1223 1224 // Friend function injected into enclosing namespace and found by ADL 1225 friend inline bool 1226 operator==(const __weak_count& __a, const __weak_count& __b) noexcept 1227 { return __a._M_pi == __b._M_pi; } 1228 1229 private: 1230 friend class __shared_count<_Lp>; 1231 #if __cplusplus >= 202002L 1232 template
friend class _Sp_atomic; 1233 #endif 1234 1235 _Sp_counted_base<_Lp>* _M_pi; 1236 }; 1237 1238 // Now that __weak_count is defined we can define this constructor: 1239 template<_Lock_policy _Lp> 1240 inline 1241 __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r) 1242 : _M_pi(__r._M_pi) 1243 { 1244 if (_M_pi == nullptr || !_M_pi->_M_add_ref_lock_nothrow()) 1245 __throw_bad_weak_ptr(); 1246 } 1247 1248 // Now that __weak_count is defined we can define this constructor: 1249 template<_Lock_policy _Lp> 1250 inline 1251 __shared_count<_Lp>:: 1252 __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept 1253 : _M_pi(__r._M_pi) 1254 { 1255 if (_M_pi && !_M_pi->_M_add_ref_lock_nothrow()) 1256 _M_pi = nullptr; 1257 } 1258 1259 // Helper traits for shared_ptr of array: 1260 1261 // A pointer type Y* is said to be compatible with a pointer type T* when 1262 // either Y* is convertible to T* or Y is U[N] and T is U cv []. 1263 template
1264 struct __sp_compatible_with 1265 : false_type 1266 { }; 1267 1268 template
1269 struct __sp_compatible_with<_Yp*, _Tp*> 1270 : is_convertible<_Yp*, _Tp*>::type 1271 { }; 1272 1273 template
1274 struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]> 1275 : true_type 1276 { }; 1277 1278 template
1279 struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]> 1280 : true_type 1281 { }; 1282 1283 template
1284 struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]> 1285 : true_type 1286 { }; 1287 1288 template
1289 struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]> 1290 : true_type 1291 { }; 1292 1293 // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N]. 1294 template
1295 struct __sp_is_constructible_arrN 1296 : false_type 1297 { }; 1298 1299 template
1300 struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>> 1301 : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type 1302 { }; 1303 1304 // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[]. 1305 template
1306 struct __sp_is_constructible_arr 1307 : false_type 1308 { }; 1309 1310 template
1311 struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>> 1312 : is_convertible<_Yp(*)[], _Up(*)[]>::type 1313 { }; 1314 1315 // Trait to check if shared_ptr
can be constructed from Y*. 1316 template
1317 struct __sp_is_constructible; 1318 1319 // When T is U[N], Y(*)[N] shall be convertible to T*; 1320 template
1321 struct __sp_is_constructible<_Up[_Nm], _Yp> 1322 : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type 1323 { }; 1324 1325 // when T is U[], Y(*)[] shall be convertible to T*; 1326 template
1327 struct __sp_is_constructible<_Up[], _Yp> 1328 : __sp_is_constructible_arr<_Up, _Yp>::type 1329 { }; 1330 1331 // otherwise, Y* shall be convertible to T*. 1332 template
1333 struct __sp_is_constructible 1334 : is_convertible<_Yp*, _Tp*>::type 1335 { }; 1336 1337 1338 // Define operator* and operator-> for shared_ptr
. 1339 template
::value, bool = is_void<_Tp>::value> 1341 class __shared_ptr_access 1342 { 1343 public: 1344 using element_type = _Tp; 1345 1346 element_type& 1347 operator*() const noexcept 1348 { 1349 __glibcxx_assert(_M_get() != nullptr); 1350 return *_M_get(); 1351 } 1352 1353 element_type* 1354 operator->() const noexcept 1355 { 1356 _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr); 1357 return _M_get(); 1358 } 1359 1360 private: 1361 element_type* 1362 _M_get() const noexcept 1363 { return static_cast
*>(this)->get(); } 1364 }; 1365 1366 // Define operator-> for shared_ptr
. 1367 template
1368 class __shared_ptr_access<_Tp, _Lp, false, true> 1369 { 1370 public: 1371 using element_type = _Tp; 1372 1373 element_type* 1374 operator->() const noexcept 1375 { 1376 auto __ptr = static_cast
*>(this)->get(); 1377 _GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr); 1378 return __ptr; 1379 } 1380 }; 1381 1382 // Define operator[] for shared_ptr
and shared_ptr
. 1383 template
1384 class __shared_ptr_access<_Tp, _Lp, true, false> 1385 { 1386 public: 1387 using element_type = typename remove_extent<_Tp>::type; 1388 1389 #if __cplusplus <= 201402L 1390 [[__deprecated__("shared_ptr
::operator* is absent from C++17")]] 1391 element_type& 1392 operator*() const noexcept 1393 { 1394 __glibcxx_assert(_M_get() != nullptr); 1395 return *_M_get(); 1396 } 1397 1398 [[__deprecated__("shared_ptr
::operator-> is absent from C++17")]] 1399 element_type* 1400 operator->() const noexcept 1401 { 1402 _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr); 1403 return _M_get(); 1404 } 1405 #endif 1406 1407 element_type& 1408 operator[](ptrdiff_t __i) const noexcept 1409 { 1410 __glibcxx_assert(_M_get() != nullptr); 1411 __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value); 1412 return _M_get()[__i]; 1413 } 1414 1415 private: 1416 element_type* 1417 _M_get() const noexcept 1418 { return static_cast
*>(this)->get(); } 1419 }; 1420 1421 template
1422 class __shared_ptr 1423 : public __shared_ptr_access<_Tp, _Lp> 1424 { 1425 public: 1426 using element_type = typename remove_extent<_Tp>::type; 1427 1428 private: 1429 // Constraint for taking ownership of a pointer of type _Yp*: 1430 template
1431 using _SafeConv 1432 = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type; 1433 1434 // Constraint for construction from shared_ptr and weak_ptr: 1435 template
1436 using _Compatible = typename 1437 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type; 1438 1439 // Constraint for assignment from shared_ptr and weak_ptr: 1440 template
1441 using _Assignable = _Compatible<_Yp, __shared_ptr&>; 1442 1443 // Constraint for construction from unique_ptr: 1444 template
::pointer> 1446 using _UniqCompatible = __enable_if_t<__and_< 1447 __sp_compatible_with<_Yp*, _Tp*>, 1448 is_convertible<_Ptr, element_type*>, 1449 is_move_constructible<_Del> 1450 >::value, _Res>; 1451 1452 // Constraint for assignment from unique_ptr: 1453 template
1454 using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>; 1455 1456 public: 1457 1458 #if __cplusplus > 201402L 1459 using weak_type = __weak_ptr<_Tp, _Lp>; 1460 #endif 1461 1462 constexpr __shared_ptr() noexcept 1463 : _M_ptr(0), _M_refcount() 1464 { } 1465 1466 template
> 1467 explicit 1468 __shared_ptr(_Yp* __p) 1469 : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type()) 1470 { 1471 static_assert( !is_void<_Yp>::value, "incomplete type" ); 1472 static_assert( sizeof(_Yp) > 0, "incomplete type" ); 1473 _M_enable_shared_from_this_with(__p); 1474 } 1475 1476 template
> 1477 __shared_ptr(_Yp* __p, _Deleter __d) 1478 : _M_ptr(__p), _M_refcount(__p, std::move(__d)) 1479 { 1480 static_assert(__is_invocable<_Deleter&, _Yp*&>::value, 1481 "deleter expression d(p) is well-formed"); 1482 _M_enable_shared_from_this_with(__p); 1483 } 1484 1485 template
> 1487 __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a) 1488 : _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a)) 1489 { 1490 static_assert(__is_invocable<_Deleter&, _Yp*&>::value, 1491 "deleter expression d(p) is well-formed"); 1492 _M_enable_shared_from_this_with(__p); 1493 } 1494 1495 template
1496 __shared_ptr(nullptr_t __p, _Deleter __d) 1497 : _M_ptr(0), _M_refcount(__p, std::move(__d)) 1498 { } 1499 1500 template
1501 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 1502 : _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a)) 1503 { } 1504 1505 // Aliasing constructor 1506 template
1507 __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r, 1508 element_type* __p) noexcept 1509 : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws 1510 { } 1511 1512 // Aliasing constructor 1513 template
1514 __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r, 1515 element_type* __p) noexcept 1516 : _M_ptr(__p), _M_refcount() 1517 { 1518 _M_refcount._M_swap(__r._M_refcount); 1519 __r._M_ptr = nullptr; 1520 } 1521 1522 __shared_ptr(const __shared_ptr&) noexcept = default; 1523 __shared_ptr& operator=(const __shared_ptr&) noexcept = default; 1524 ~__shared_ptr() = default; 1525 1526 template
> 1527 __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept 1528 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 1529 { } 1530 1531 __shared_ptr(__shared_ptr&& __r) noexcept 1532 : _M_ptr(__r._M_ptr), _M_refcount() 1533 { 1534 _M_refcount._M_swap(__r._M_refcount); 1535 __r._M_ptr = nullptr; 1536 } 1537 1538 template
> 1539 __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept 1540 : _M_ptr(__r._M_ptr), _M_refcount() 1541 { 1542 _M_refcount._M_swap(__r._M_refcount); 1543 __r._M_ptr = nullptr; 1544 } 1545 1546 template
> 1547 explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r) 1548 : _M_refcount(__r._M_refcount) // may throw 1549 { 1550 // It is now safe to copy __r._M_ptr, as 1551 // _M_refcount(__r._M_refcount) did not throw. 1552 _M_ptr = __r._M_ptr; 1553 } 1554 1555 // If an exception is thrown this constructor has no effect. 1556 template
> 1558 __shared_ptr(unique_ptr<_Yp, _Del>&& __r) 1559 : _M_ptr(__r.get()), _M_refcount() 1560 { 1561 auto __raw = __to_address(__r.get()); 1562 _M_refcount = __shared_count<_Lp>(std::move(__r)); 1563 _M_enable_shared_from_this_with(__raw); 1564 } 1565 1566 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED 1567 protected: 1568 // If an exception is thrown this constructor has no effect. 1569 template
>, is_array<_Tp1>, 1572 is_convertible
::pointer, _Tp*> 1573 >::value, bool>::type = true> 1574 __shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete) 1575 : _M_ptr(__r.get()), _M_refcount() 1576 { 1577 auto __raw = __to_address(__r.get()); 1578 _M_refcount = __shared_count<_Lp>(std::move(__r)); 1579 _M_enable_shared_from_this_with(__raw); 1580 } 1581 public: 1582 #endif 1583 1584 #if _GLIBCXX_USE_DEPRECATED 1585 #pragma GCC diagnostic push 1586 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 1587 // Postcondition: use_count() == 1 and __r.get() == 0 1588 template
> 1589 __shared_ptr(auto_ptr<_Yp>&& __r); 1590 #pragma GCC diagnostic pop 1591 #endif 1592 1593 constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { } 1594 1595 template
1596 _Assignable<_Yp> 1597 operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept 1598 { 1599 _M_ptr = __r._M_ptr; 1600 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 1601 return *this; 1602 } 1603 1604 #if _GLIBCXX_USE_DEPRECATED 1605 #pragma GCC diagnostic push 1606 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 1607 template
1608 _Assignable<_Yp> 1609 operator=(auto_ptr<_Yp>&& __r) 1610 { 1611 __shared_ptr(std::move(__r)).swap(*this); 1612 return *this; 1613 } 1614 #pragma GCC diagnostic pop 1615 #endif 1616 1617 __shared_ptr& 1618 operator=(__shared_ptr&& __r) noexcept 1619 { 1620 __shared_ptr(std::move(__r)).swap(*this); 1621 return *this; 1622 } 1623 1624 template
1625 _Assignable<_Yp> 1626 operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept 1627 { 1628 __shared_ptr(std::move(__r)).swap(*this); 1629 return *this; 1630 } 1631 1632 template
1633 _UniqAssignable<_Yp, _Del> 1634 operator=(unique_ptr<_Yp, _Del>&& __r) 1635 { 1636 __shared_ptr(std::move(__r)).swap(*this); 1637 return *this; 1638 } 1639 1640 void 1641 reset() noexcept 1642 { __shared_ptr().swap(*this); } 1643 1644 template
1645 _SafeConv<_Yp> 1646 reset(_Yp* __p) // _Yp must be complete. 1647 { 1648 // Catch self-reset errors. 1649 __glibcxx_assert(__p == nullptr || __p != _M_ptr); 1650 __shared_ptr(__p).swap(*this); 1651 } 1652 1653 template
1654 _SafeConv<_Yp> 1655 reset(_Yp* __p, _Deleter __d) 1656 { __shared_ptr(__p, std::move(__d)).swap(*this); } 1657 1658 template
1659 _SafeConv<_Yp> 1660 reset(_Yp* __p, _Deleter __d, _Alloc __a) 1661 { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); } 1662 1663 /// Return the stored pointer. 1664 element_type* 1665 get() const noexcept 1666 { return _M_ptr; } 1667 1668 /// Return true if the stored pointer is not null. 1669 explicit operator bool() const noexcept 1670 { return _M_ptr != nullptr; } 1671 1672 /// Return true if use_count() == 1. 1673 bool 1674 unique() const noexcept 1675 { return _M_refcount._M_unique(); } 1676 1677 /// If *this owns a pointer, return the number of owners, otherwise zero. 1678 long 1679 use_count() const noexcept 1680 { return _M_refcount._M_get_use_count(); } 1681 1682 /// Exchange both the owned pointer and the stored pointer. 1683 void 1684 swap(__shared_ptr<_Tp, _Lp>& __other) noexcept 1685 { 1686 std::swap(_M_ptr, __other._M_ptr); 1687 _M_refcount._M_swap(__other._M_refcount); 1688 } 1689 1690 /** @brief Define an ordering based on ownership. 1691 * 1692 * This function defines a strict weak ordering between two shared_ptr 1693 * or weak_ptr objects, such that one object is less than the other 1694 * unless they share ownership of the same pointer, or are both empty. 1695 * @{ 1696 */ 1697 template
1698 bool 1699 owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept 1700 { return _M_refcount._M_less(__rhs._M_refcount); } 1701 1702 template
1703 bool 1704 owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept 1705 { return _M_refcount._M_less(__rhs._M_refcount); } 1706 /// @} 1707 1708 protected: 1709 // This constructor is non-standard, it is used by allocate_shared. 1710 template
1711 __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) 1712 : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...) 1713 { _M_enable_shared_from_this_with(_M_ptr); } 1714 1715 template
1717 friend __shared_ptr<_Tp1, _Lp1> 1718 __allocate_shared(const _Alloc& __a, _Args&&... __args); 1719 1720 #if __cpp_lib_shared_ptr_arrays >= 201707L 1721 // This constructor is non-standard, it is used by allocate_shared
. 1722 template
*> 1723 __shared_ptr(const _Sp_counted_array_base<_Alloc>& __a, 1724 _Init __init = nullptr) 1725 : _M_ptr(), _M_refcount(_M_ptr, __a, __init) 1726 { } 1727 #endif 1728 1729 // This constructor is used by __weak_ptr::lock() and 1730 // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t). 1731 __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) noexcept 1732 : _M_refcount(__r._M_refcount, std::nothrow) 1733 { 1734 _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr; 1735 } 1736 1737 friend class __weak_ptr<_Tp, _Lp>; 1738 1739 private: 1740 1741 template
1742 using __esft_base_t = decltype(__enable_shared_from_this_base( 1743 std::declval
&>(), 1744 std::declval<_Yp*>())); 1745 1746 // Detect an accessible and unambiguous enable_shared_from_this base. 1747 template
1748 struct __has_esft_base 1749 : false_type { }; 1750 1751 template
1752 struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>> 1753 : __not_
> { }; // No enable shared_from_this for arrays 1754 1755 template
::type> 1756 typename enable_if<__has_esft_base<_Yp2>::value>::type 1757 _M_enable_shared_from_this_with(_Yp* __p) noexcept 1758 { 1759 if (auto __base = __enable_shared_from_this_base(_M_refcount, __p)) 1760 __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount); 1761 } 1762 1763 template
::type> 1764 typename enable_if::value>::type 1765 _M_enable_shared_from_this_with(_Yp*) noexcept 1766 { } 1767 1768 void* 1769 _M_get_deleter(const std::type_info& __ti) const noexcept 1770 { return _M_refcount._M_get_deleter(__ti); } 1771 1772 template
friend class __shared_ptr; 1773 template
friend class __weak_ptr; 1774 1775 template
1776 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept; 1777 1778 template
1779 friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept; 1780 1781 #if __cplusplus >= 202002L 1782 friend _Sp_atomic
>; 1783 #endif 1784 1785 element_type* _M_ptr; // Contained pointer. 1786 __shared_count<_Lp> _M_refcount; // Reference counter. 1787 }; 1788 1789 1790 // 20.7.2.2.7 shared_ptr comparisons 1791 template
1792 inline bool 1793 operator==(const __shared_ptr<_Tp1, _Lp>& __a, 1794 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1795 { return __a.get() == __b.get(); } 1796 1797 template
1798 inline bool 1799 operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1800 { return !__a; } 1801 1802 #ifdef __cpp_lib_three_way_comparison 1803 template
1804 inline strong_ordering 1805 operator<=>(const __shared_ptr<_Tp, _Lp>& __a, 1806 const __shared_ptr<_Up, _Lp>& __b) noexcept 1807 { return compare_three_way()(__a.get(), __b.get()); } 1808 1809 template
1810 inline strong_ordering 1811 operator<=>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1812 { 1813 using pointer = typename __shared_ptr<_Tp, _Lp>::element_type*; 1814 return compare_three_way()(__a.get(), static_cast
(nullptr)); 1815 } 1816 #else 1817 template
1818 inline bool 1819 operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1820 { return !__a; } 1821 1822 template
1823 inline bool 1824 operator!=(const __shared_ptr<_Tp1, _Lp>& __a, 1825 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1826 { return __a.get() != __b.get(); } 1827 1828 template
1829 inline bool 1830 operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1831 { return (bool)__a; } 1832 1833 template
1834 inline bool 1835 operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1836 { return (bool)__a; } 1837 1838 template
1839 inline bool 1840 operator<(const __shared_ptr<_Tp, _Lp>& __a, 1841 const __shared_ptr<_Up, _Lp>& __b) noexcept 1842 { 1843 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 1844 using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type; 1845 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; 1846 return less<_Vp>()(__a.get(), __b.get()); 1847 } 1848 1849 template
1850 inline bool 1851 operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1852 { 1853 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 1854 return less<_Tp_elt*>()(__a.get(), nullptr); 1855 } 1856 1857 template
1858 inline bool 1859 operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1860 { 1861 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 1862 return less<_Tp_elt*>()(nullptr, __a.get()); 1863 } 1864 1865 template
1866 inline bool 1867 operator<=(const __shared_ptr<_Tp1, _Lp>& __a, 1868 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1869 { return !(__b < __a); } 1870 1871 template
1872 inline bool 1873 operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1874 { return !(nullptr < __a); } 1875 1876 template
1877 inline bool 1878 operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1879 { return !(__a < nullptr); } 1880 1881 template
1882 inline bool 1883 operator>(const __shared_ptr<_Tp1, _Lp>& __a, 1884 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1885 { return (__b < __a); } 1886 1887 template
1888 inline bool 1889 operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1890 { return nullptr < __a; } 1891 1892 template
1893 inline bool 1894 operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1895 { return __a < nullptr; } 1896 1897 template
1898 inline bool 1899 operator>=(const __shared_ptr<_Tp1, _Lp>& __a, 1900 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1901 { return !(__a < __b); } 1902 1903 template
1904 inline bool 1905 operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1906 { return !(__a < nullptr); } 1907 1908 template
1909 inline bool 1910 operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1911 { return !(nullptr < __a); } 1912 #endif // three-way comparison 1913 1914 // 20.7.2.2.8 shared_ptr specialized algorithms. 1915 template
1916 inline void 1917 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept 1918 { __a.swap(__b); } 1919 1920 // 20.7.2.2.9 shared_ptr casts 1921 1922 // The seemingly equivalent code: 1923 // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) 1924 // will eventually result in undefined behaviour, attempting to 1925 // delete the same object twice. 1926 /// static_pointer_cast 1927 template
1928 inline __shared_ptr<_Tp, _Lp> 1929 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1930 { 1931 using _Sp = __shared_ptr<_Tp, _Lp>; 1932 return _Sp(__r, static_cast
(__r.get())); 1933 } 1934 1935 // The seemingly equivalent code: 1936 // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) 1937 // will eventually result in undefined behaviour, attempting to 1938 // delete the same object twice. 1939 /// const_pointer_cast 1940 template
1941 inline __shared_ptr<_Tp, _Lp> 1942 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1943 { 1944 using _Sp = __shared_ptr<_Tp, _Lp>; 1945 return _Sp(__r, const_cast
(__r.get())); 1946 } 1947 1948 // The seemingly equivalent code: 1949 // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) 1950 // will eventually result in undefined behaviour, attempting to 1951 // delete the same object twice. 1952 /// dynamic_pointer_cast 1953 template
1954 inline __shared_ptr<_Tp, _Lp> 1955 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1956 { 1957 using _Sp = __shared_ptr<_Tp, _Lp>; 1958 if (auto* __p = dynamic_cast
(__r.get())) 1959 return _Sp(__r, __p); 1960 return _Sp(); 1961 } 1962 1963 #if __cplusplus > 201402L 1964 template
1965 inline __shared_ptr<_Tp, _Lp> 1966 reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1967 { 1968 using _Sp = __shared_ptr<_Tp, _Lp>; 1969 return _Sp(__r, reinterpret_cast
(__r.get())); 1970 } 1971 #endif 1972 1973 template
1974 class __weak_ptr 1975 { 1976 template
1977 using _Compatible = typename 1978 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type; 1979 1980 // Constraint for assignment from shared_ptr and weak_ptr: 1981 template
1982 using _Assignable = _Compatible<_Yp, __weak_ptr&>; 1983 1984 public: 1985 using element_type = typename remove_extent<_Tp>::type; 1986 1987 constexpr __weak_ptr() noexcept 1988 : _M_ptr(nullptr), _M_refcount() 1989 { } 1990 1991 __weak_ptr(const __weak_ptr&) noexcept = default; 1992 1993 ~__weak_ptr() = default; 1994 1995 // The "obvious" converting constructor implementation: 1996 // 1997 // template
1998 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 1999 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 2000 // { } 2001 // 2002 // has a serious problem. 2003 // 2004 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 2005 // conversion may require access to *__r._M_ptr (virtual inheritance). 2006 // 2007 // It is not possible to avoid spurious access violations since 2008 // in multithreaded programs __r._M_ptr may be invalidated at any point. 2009 template
> 2010 __weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept 2011 : _M_refcount(__r._M_refcount) 2012 { _M_ptr = __r.lock().get(); } 2013 2014 template
> 2015 __weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept 2016 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 2017 { } 2018 2019 __weak_ptr(__weak_ptr&& __r) noexcept 2020 : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount)) 2021 { __r._M_ptr = nullptr; } 2022 2023 template
> 2024 __weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept 2025 : _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount)) 2026 { __r._M_ptr = nullptr; } 2027 2028 __weak_ptr& 2029 operator=(const __weak_ptr& __r) noexcept = default; 2030 2031 template
2032 _Assignable<_Yp> 2033 operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept 2034 { 2035 _M_ptr = __r.lock().get(); 2036 _M_refcount = __r._M_refcount; 2037 return *this; 2038 } 2039 2040 template
2041 _Assignable<_Yp> 2042 operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept 2043 { 2044 _M_ptr = __r._M_ptr; 2045 _M_refcount = __r._M_refcount; 2046 return *this; 2047 } 2048 2049 __weak_ptr& 2050 operator=(__weak_ptr&& __r) noexcept 2051 { 2052 __weak_ptr(std::move(__r)).swap(*this); 2053 return *this; 2054 } 2055 2056 template
2057 _Assignable<_Yp> 2058 operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept 2059 { 2060 _M_ptr = __r.lock().get(); 2061 _M_refcount = std::move(__r._M_refcount); 2062 __r._M_ptr = nullptr; 2063 return *this; 2064 } 2065 2066 __shared_ptr<_Tp, _Lp> 2067 lock() const noexcept 2068 { return __shared_ptr
(*this, std::nothrow); } 2069 2070 long 2071 use_count() const noexcept 2072 { return _M_refcount._M_get_use_count(); } 2073 2074 bool 2075 expired() const noexcept 2076 { return _M_refcount._M_get_use_count() == 0; } 2077 2078 template
2079 bool 2080 owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept 2081 { return _M_refcount._M_less(__rhs._M_refcount); } 2082 2083 template
2084 bool 2085 owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept 2086 { return _M_refcount._M_less(__rhs._M_refcount); } 2087 2088 void 2089 reset() noexcept 2090 { __weak_ptr().swap(*this); } 2091 2092 void 2093 swap(__weak_ptr& __s) noexcept 2094 { 2095 std::swap(_M_ptr, __s._M_ptr); 2096 _M_refcount._M_swap(__s._M_refcount); 2097 } 2098 2099 private: 2100 // Used by __enable_shared_from_this. 2101 void 2102 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept 2103 { 2104 if (use_count() == 0) 2105 { 2106 _M_ptr = __ptr; 2107 _M_refcount = __refcount; 2108 } 2109 } 2110 2111 template
friend class __shared_ptr; 2112 template
friend class __weak_ptr; 2113 friend class __enable_shared_from_this<_Tp, _Lp>; 2114 friend class enable_shared_from_this<_Tp>; 2115 #if __cplusplus >= 202002L 2116 friend _Sp_atomic
>; 2117 #endif 2118 2119 element_type* _M_ptr; // Contained pointer. 2120 __weak_count<_Lp> _M_refcount; // Reference counter. 2121 }; 2122 2123 // 20.7.2.3.6 weak_ptr specialized algorithms. 2124 template
2125 inline void 2126 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept 2127 { __a.swap(__b); } 2128 2129 #pragma GCC diagnostic push 2130 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 2131 template
2132 struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool> 2133 { 2134 bool 2135 operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept 2136 { return __lhs.owner_before(__rhs); } 2137 2138 bool 2139 operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept 2140 { return __lhs.owner_before(__rhs); } 2141 2142 bool 2143 operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept 2144 { return __lhs.owner_before(__rhs); } 2145 }; 2146 #pragma GCC diagnostic pop 2147 2148 template<> 2149 struct _Sp_owner_less
2150 { 2151 template
2152 auto 2153 operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept 2154 -> decltype(__lhs.owner_before(__rhs)) 2155 { return __lhs.owner_before(__rhs); } 2156 2157 using is_transparent = void; 2158 }; 2159 2160 template
2161 struct owner_less<__shared_ptr<_Tp, _Lp>> 2162 : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>> 2163 { }; 2164 2165 template
2166 struct owner_less<__weak_ptr<_Tp, _Lp>> 2167 : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>> 2168 { }; 2169 2170 2171 template
2172 class __enable_shared_from_this 2173 { 2174 protected: 2175 constexpr __enable_shared_from_this() noexcept { } 2176 2177 __enable_shared_from_this(const __enable_shared_from_this&) noexcept { } 2178 2179 __enable_shared_from_this& 2180 operator=(const __enable_shared_from_this&) noexcept 2181 { return *this; } 2182 2183 ~__enable_shared_from_this() { } 2184 2185 public: 2186 __shared_ptr<_Tp, _Lp> 2187 shared_from_this() 2188 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 2189 2190 __shared_ptr
2191 shared_from_this() const 2192 { return __shared_ptr
(this->_M_weak_this); } 2193 2194 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 2195 __weak_ptr<_Tp, _Lp> 2196 weak_from_this() noexcept 2197 { return this->_M_weak_this; } 2198 2199 __weak_ptr
2200 weak_from_this() const noexcept 2201 { return this->_M_weak_this; } 2202 #endif 2203 2204 private: 2205 template
2206 void 2207 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept 2208 { _M_weak_this._M_assign(__p, __n); } 2209 2210 friend const __enable_shared_from_this* 2211 __enable_shared_from_this_base(const __shared_count<_Lp>&, 2212 const __enable_shared_from_this* __p) 2213 { return __p; } 2214 2215 template
2216 friend class __shared_ptr; 2217 2218 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 2219 }; 2220 2221 template
2223 inline __shared_ptr<_Tp, _Lp> 2224 __allocate_shared(const _Alloc& __a, _Args&&... __args) 2225 { 2226 static_assert(!is_array<_Tp>::value, "make_shared
not supported"); 2227 2228 return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a}, 2229 std::forward<_Args>(__args)...); 2230 } 2231 2232 template
2234 inline __shared_ptr<_Tp, _Lp> 2235 __make_shared(_Args&&... __args) 2236 { 2237 typedef typename std::remove_const<_Tp>::type _Tp_nc; 2238 return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(), 2239 std::forward<_Args>(__args)...); 2240 } 2241 2242 /// std::hash specialization for __shared_ptr. 2243 template
2244 struct hash<__shared_ptr<_Tp, _Lp>> 2245 : public __hash_base
> 2246 { 2247 size_t 2248 operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept 2249 { 2250 return hash
::element_type*>()( 2251 __s.get()); 2252 } 2253 }; 2254 2255 _GLIBCXX_END_NAMESPACE_VERSION 2256 } // namespace 2257 2258 #endif // _SHARED_PTR_BASE_H
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™