Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/11/bits/shared_ptr_base.h
$ cat -n /usr/include/c++/11/bits/shared_ptr_base.h 1 // shared_ptr and weak_ptr implementation details -*- C++ -*- 2 3 // Copyright (C) 2007-2021 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 > 201703L 64 # include
65 #endif 66 67 namespace std _GLIBCXX_VISIBILITY(default) 68 { 69 _GLIBCXX_BEGIN_NAMESPACE_VERSION 70 71 #if _GLIBCXX_USE_DEPRECATED 72 #pragma GCC diagnostic push 73 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 74 template
class auto_ptr; 75 #pragma GCC diagnostic pop 76 #endif 77 78 /** 79 * @brief Exception possibly thrown by @c shared_ptr. 80 * @ingroup exceptions 81 */ 82 class bad_weak_ptr : public std::exception 83 { 84 public: 85 virtual char const* what() const noexcept; 86 87 virtual ~bad_weak_ptr() noexcept; 88 }; 89 90 // Substitute for bad_weak_ptr object in the case of -fno-exceptions. 91 inline void 92 __throw_bad_weak_ptr() 93 { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); } 94 95 using __gnu_cxx::_Lock_policy; 96 using __gnu_cxx::__default_lock_policy; 97 using __gnu_cxx::_S_single; 98 using __gnu_cxx::_S_mutex; 99 using __gnu_cxx::_S_atomic; 100 101 // Empty helper class except when the template argument is _S_mutex. 102 template<_Lock_policy _Lp> 103 class _Mutex_base 104 { 105 protected: 106 // The atomic policy uses fully-fenced builtins, single doesn't care. 107 enum { _S_need_barriers = 0 }; 108 }; 109 110 template<> 111 class _Mutex_base<_S_mutex> 112 : public __gnu_cxx::__mutex 113 { 114 protected: 115 // This policy is used when atomic builtins are not available. 116 // The replacement atomic operations might not have the necessary 117 // memory barriers. 118 enum { _S_need_barriers = 1 }; 119 }; 120 121 template<_Lock_policy _Lp = __default_lock_policy> 122 class _Sp_counted_base 123 : public _Mutex_base<_Lp> 124 { 125 public: 126 _Sp_counted_base() noexcept 127 : _M_use_count(1), _M_weak_count(1) { } 128 129 virtual 130 ~_Sp_counted_base() noexcept 131 { } 132 133 // Called when _M_use_count drops to zero, to release the resources 134 // managed by *this. 135 virtual void 136 _M_dispose() noexcept = 0; 137 138 // Called when _M_weak_count drops to zero. 139 virtual void 140 _M_destroy() noexcept 141 { delete this; } 142 143 virtual void* 144 _M_get_deleter(const std::type_info&) noexcept = 0; 145 146 void 147 _M_add_ref_copy() 148 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } 149 150 void 151 _M_add_ref_lock() 152 { 153 if (!_M_add_ref_lock_nothrow()) 154 __throw_bad_weak_ptr(); 155 } 156 157 bool 158 _M_add_ref_lock_nothrow() noexcept; 159 160 void 161 _M_release() noexcept 162 { 163 // Be race-detector-friendly. For more info see bits/c++config. 164 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); 165 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) 166 { 167 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); 168 _M_dispose(); 169 // There must be a memory barrier between dispose() and destroy() 170 // to ensure that the effects of dispose() are observed in the 171 // thread that runs destroy(). 172 // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html 173 if (_Mutex_base<_Lp>::_S_need_barriers) 174 { 175 __atomic_thread_fence (__ATOMIC_ACQ_REL); 176 } 177 178 // Be race-detector-friendly. For more info see bits/c++config. 179 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 180 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, 181 -1) == 1) 182 { 183 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 184 _M_destroy(); 185 } 186 } 187 } 188 189 void 190 _M_weak_add_ref() noexcept 191 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } 192 193 void 194 _M_weak_release() noexcept 195 { 196 // Be race-detector-friendly. For more info see bits/c++config. 197 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 198 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) 199 { 200 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 201 if (_Mutex_base<_Lp>::_S_need_barriers) 202 { 203 // See _M_release(), 204 // destroy() must observe results of dispose() 205 __atomic_thread_fence (__ATOMIC_ACQ_REL); 206 } 207 _M_destroy(); 208 } 209 } 210 211 long 212 _M_get_use_count() const noexcept 213 { 214 // No memory barrier is used here so there is no synchronization 215 // with other threads. 216 return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED); 217 } 218 219 private: 220 _Sp_counted_base(_Sp_counted_base const&) = delete; 221 _Sp_counted_base& operator=(_Sp_counted_base const&) = delete; 222 223 _Atomic_word _M_use_count; // #shared 224 _Atomic_word _M_weak_count; // #weak + (#shared != 0) 225 }; 226 227 template<> 228 inline bool 229 _Sp_counted_base<_S_single>:: 230 _M_add_ref_lock_nothrow() noexcept 231 { 232 if (_M_use_count == 0) 233 return false; 234 ++_M_use_count; 235 return true; 236 } 237 238 template<> 239 inline bool 240 _Sp_counted_base<_S_mutex>:: 241 _M_add_ref_lock_nothrow() noexcept 242 { 243 __gnu_cxx::__scoped_lock sentry(*this); 244 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 245 { 246 _M_use_count = 0; 247 return false; 248 } 249 return true; 250 } 251 252 template<> 253 inline bool 254 _Sp_counted_base<_S_atomic>:: 255 _M_add_ref_lock_nothrow() noexcept 256 { 257 // Perform lock-free add-if-not-zero operation. 258 _Atomic_word __count = _M_get_use_count(); 259 do 260 { 261 if (__count == 0) 262 return false; 263 // Replace the current counter value with the old value + 1, as 264 // long as it's not changed meanwhile. 265 } 266 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, 267 true, __ATOMIC_ACQ_REL, 268 __ATOMIC_RELAXED)); 269 return true; 270 } 271 272 template<> 273 inline void 274 _Sp_counted_base<_S_single>::_M_add_ref_copy() 275 { ++_M_use_count; } 276 277 template<> 278 inline void 279 _Sp_counted_base<_S_single>::_M_release() noexcept 280 { 281 if (--_M_use_count == 0) 282 { 283 _M_dispose(); 284 if (--_M_weak_count == 0) 285 _M_destroy(); 286 } 287 } 288 289 template<> 290 inline void 291 _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept 292 { ++_M_weak_count; } 293 294 template<> 295 inline void 296 _Sp_counted_base<_S_single>::_M_weak_release() noexcept 297 { 298 if (--_M_weak_count == 0) 299 _M_destroy(); 300 } 301 302 template<> 303 inline long 304 _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept 305 { return _M_use_count; } 306 307 308 // Forward declarations. 309 template
310 class __shared_ptr; 311 312 template
313 class __weak_ptr; 314 315 template
316 class __enable_shared_from_this; 317 318 template
319 class shared_ptr; 320 321 template
322 class weak_ptr; 323 324 template
325 struct owner_less; 326 327 template
328 class enable_shared_from_this; 329 330 template<_Lock_policy _Lp = __default_lock_policy> 331 class __weak_count; 332 333 template<_Lock_policy _Lp = __default_lock_policy> 334 class __shared_count; 335 336 337 // Counted ptr with no deleter or allocator support 338 template
339 class _Sp_counted_ptr final : public _Sp_counted_base<_Lp> 340 { 341 public: 342 explicit 343 _Sp_counted_ptr(_Ptr __p) noexcept 344 : _M_ptr(__p) { } 345 346 virtual void 347 _M_dispose() noexcept 348 { delete _M_ptr; } 349 350 virtual void 351 _M_destroy() noexcept 352 { delete this; } 353 354 virtual void* 355 _M_get_deleter(const std::type_info&) noexcept 356 { return nullptr; } 357 358 _Sp_counted_ptr(const _Sp_counted_ptr&) = delete; 359 _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete; 360 361 private: 362 _Ptr _M_ptr; 363 }; 364 365 template<> 366 inline void 367 _Sp_counted_ptr
::_M_dispose() noexcept { } 368 369 template<> 370 inline void 371 _Sp_counted_ptr
::_M_dispose() noexcept { } 372 373 template<> 374 inline void 375 _Sp_counted_ptr
::_M_dispose() noexcept { } 376 377 template
379 struct _Sp_ebo_helper; 380 381 /// Specialization using EBO. 382 template
383 struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp 384 { 385 explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { } 386 explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { } 387 388 static _Tp& 389 _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); } 390 }; 391 392 /// Specialization not using EBO. 393 template
394 struct _Sp_ebo_helper<_Nm, _Tp, false> 395 { 396 explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { } 397 explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(std::move(__tp)) { } 398 399 static _Tp& 400 _S_get(_Sp_ebo_helper& __eboh) 401 { return __eboh._M_tp; } 402 403 private: 404 _Tp _M_tp; 405 }; 406 407 // Support for custom deleter and/or allocator 408 template
409 class _Sp_counted_deleter final : public _Sp_counted_base<_Lp> 410 { 411 class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc> 412 { 413 typedef _Sp_ebo_helper<0, _Deleter> _Del_base; 414 typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base; 415 416 public: 417 _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept 418 : _Del_base(std::move(__d)), _Alloc_base(__a), _M_ptr(__p) 419 { } 420 421 _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); } 422 _Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); } 423 424 _Ptr _M_ptr; 425 }; 426 427 public: 428 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>; 429 430 // __d(__p) must not throw. 431 _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept 432 : _M_impl(__p, std::move(__d), _Alloc()) { } 433 434 // __d(__p) must not throw. 435 _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept 436 : _M_impl(__p, std::move(__d), __a) { } 437 438 ~_Sp_counted_deleter() noexcept { } 439 440 virtual void 441 _M_dispose() noexcept 442 { _M_impl._M_del()(_M_impl._M_ptr); } 443 444 virtual void 445 _M_destroy() noexcept 446 { 447 __allocator_type __a(_M_impl._M_alloc()); 448 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; 449 this->~_Sp_counted_deleter(); 450 } 451 452 virtual void* 453 _M_get_deleter(const type_info& __ti [[__gnu__::__unused__]]) noexcept 454 { 455 #if __cpp_rtti 456 // _GLIBCXX_RESOLVE_LIB_DEFECTS 457 // 2400. shared_ptr's get_deleter() should use addressof() 458 return __ti == typeid(_Deleter) 459 ? std::__addressof(_M_impl._M_del()) 460 : nullptr; 461 #else 462 return nullptr; 463 #endif 464 } 465 466 private: 467 _Impl _M_impl; 468 }; 469 470 // helpers for make_shared / allocate_shared 471 472 struct _Sp_make_shared_tag 473 { 474 private: 475 template
476 friend class _Sp_counted_ptr_inplace; 477 478 static const type_info& 479 _S_ti() noexcept _GLIBCXX_VISIBILITY(default) 480 { 481 alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { }; 482 return reinterpret_cast
(__tag); 483 } 484 485 static bool _S_eq(const type_info&) noexcept; 486 }; 487 488 template
489 struct _Sp_alloc_shared_tag 490 { 491 const _Alloc& _M_a; 492 }; 493 494 template
495 class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> 496 { 497 class _Impl : _Sp_ebo_helper<0, _Alloc> 498 { 499 typedef _Sp_ebo_helper<0, _Alloc> _A_base; 500 501 public: 502 explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { } 503 504 _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); } 505 506 __gnu_cxx::__aligned_buffer<_Tp> _M_storage; 507 }; 508 509 public: 510 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>; 511 512 // Alloc parameter is not a reference so doesn't alias anything in __args 513 template
514 _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args) 515 : _M_impl(__a) 516 { 517 // _GLIBCXX_RESOLVE_LIB_DEFECTS 518 // 2070. allocate_shared should use allocator_traits
::construct 519 allocator_traits<_Alloc>::construct(__a, _M_ptr(), 520 std::forward<_Args>(__args)...); // might throw 521 } 522 523 ~_Sp_counted_ptr_inplace() noexcept { } 524 525 virtual void 526 _M_dispose() noexcept 527 { 528 allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr()); 529 } 530 531 // Override because the allocator needs to know the dynamic type 532 virtual void 533 _M_destroy() noexcept 534 { 535 __allocator_type __a(_M_impl._M_alloc()); 536 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; 537 this->~_Sp_counted_ptr_inplace(); 538 } 539 540 private: 541 friend class __shared_count<_Lp>; // To be able to call _M_ptr(). 542 543 // No longer used, but code compiled against old libstdc++ headers 544 // might still call it from __shared_ptr ctor to get the pointer out. 545 virtual void* 546 _M_get_deleter(const std::type_info& __ti) noexcept override 547 { 548 auto __ptr = const_cast
::type*>(_M_ptr()); 549 // Check for the fake type_info first, so we don't try to access it 550 // as a real type_info object. Otherwise, check if it's the real 551 // type_info for this class. With RTTI enabled we can check directly, 552 // or call a library function to do it. 553 if (&__ti == &_Sp_make_shared_tag::_S_ti() 554 || 555 #if __cpp_rtti 556 __ti == typeid(_Sp_make_shared_tag) 557 #else 558 _Sp_make_shared_tag::_S_eq(__ti) 559 #endif 560 ) 561 return __ptr; 562 return nullptr; 563 } 564 565 _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); } 566 567 _Impl _M_impl; 568 }; 569 570 // The default deleter for shared_ptr
and shared_ptr
. 571 struct __sp_array_delete 572 { 573 template
574 void operator()(_Yp* __p) const { delete[] __p; } 575 }; 576 577 template<_Lock_policy _Lp> 578 class __shared_count 579 { 580 template
581 struct __not_alloc_shared_tag { using type = void; }; 582 583 template
584 struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { }; 585 586 public: 587 constexpr __shared_count() noexcept : _M_pi(0) 588 { } 589 590 template
591 explicit 592 __shared_count(_Ptr __p) : _M_pi(0) 593 { 594 __try 595 { 596 _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); 597 } 598 __catch(...) 599 { 600 delete __p; 601 __throw_exception_again; 602 } 603 } 604 605 template
606 __shared_count(_Ptr __p, /* is_array = */ false_type) 607 : __shared_count(__p) 608 { } 609 610 template
611 __shared_count(_Ptr __p, /* is_array = */ true_type) 612 : __shared_count(__p, __sp_array_delete{}, allocator
()) 613 { } 614 615 template
::type> 617 __shared_count(_Ptr __p, _Deleter __d) 618 : __shared_count(__p, std::move(__d), allocator
()) 619 { } 620 621 template
::type> 623 __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) 624 { 625 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; 626 __try 627 { 628 typename _Sp_cd_type::__allocator_type __a2(__a); 629 auto __guard = std::__allocate_guarded(__a2); 630 _Sp_cd_type* __mem = __guard.get(); 631 ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a)); 632 _M_pi = __mem; 633 __guard = nullptr; 634 } 635 __catch(...) 636 { 637 __d(__p); // Call _Deleter on __p. 638 __throw_exception_again; 639 } 640 } 641 642 template
643 __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a, 644 _Args&&... __args) 645 { 646 typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type; 647 typename _Sp_cp_type::__allocator_type __a2(__a._M_a); 648 auto __guard = std::__allocate_guarded(__a2); 649 _Sp_cp_type* __mem = __guard.get(); 650 auto __pi = ::new (__mem) 651 _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...); 652 __guard = nullptr; 653 _M_pi = __pi; 654 __p = __pi->_M_ptr(); 655 } 656 657 #if _GLIBCXX_USE_DEPRECATED 658 #pragma GCC diagnostic push 659 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 660 // Special case for auto_ptr<_Tp> to provide the strong guarantee. 661 template
662 explicit 663 __shared_count(std::auto_ptr<_Tp>&& __r); 664 #pragma GCC diagnostic pop 665 #endif 666 667 // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee. 668 template
669 explicit 670 __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0) 671 { 672 // _GLIBCXX_RESOLVE_LIB_DEFECTS 673 // 2415. Inconsistency between unique_ptr and shared_ptr 674 if (__r.get() == nullptr) 675 return; 676 677 using _Ptr = typename unique_ptr<_Tp, _Del>::pointer; 678 using _Del2 = typename conditional
::value, 679 reference_wrapper
::type>, 680 _Del>::type; 681 using _Sp_cd_type 682 = _Sp_counted_deleter<_Ptr, _Del2, allocator
, _Lp>; 683 using _Alloc = allocator<_Sp_cd_type>; 684 using _Alloc_traits = allocator_traits<_Alloc>; 685 _Alloc __a; 686 _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1); 687 // _GLIBCXX_RESOLVE_LIB_DEFECTS 688 // 3548. shared_ptr construction from unique_ptr should move 689 // (not copy) the deleter 690 _Alloc_traits::construct(__a, __mem, __r.release(), 691 std::forward<_Del>(__r.get_deleter())); 692 _M_pi = __mem; 693 } 694 695 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 696 explicit __shared_count(const __weak_count<_Lp>& __r); 697 698 // Does not throw if __r._M_get_use_count() == 0, caller must check. 699 explicit 700 __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept; 701 702 ~__shared_count() noexcept 703 { 704 if (_M_pi != nullptr) 705 _M_pi->_M_release(); 706 } 707 708 __shared_count(const __shared_count& __r) noexcept 709 : _M_pi(__r._M_pi) 710 { 711 if (_M_pi != nullptr) 712 _M_pi->_M_add_ref_copy(); 713 } 714 715 __shared_count& 716 operator=(const __shared_count& __r) noexcept 717 { 718 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 719 if (__tmp != _M_pi) 720 { 721 if (__tmp != nullptr) 722 __tmp->_M_add_ref_copy(); 723 if (_M_pi != nullptr) 724 _M_pi->_M_release(); 725 _M_pi = __tmp; 726 } 727 return *this; 728 } 729 730 void 731 _M_swap(__shared_count& __r) noexcept 732 { 733 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 734 __r._M_pi = _M_pi; 735 _M_pi = __tmp; 736 } 737 738 long 739 _M_get_use_count() const noexcept 740 { return _M_pi ? _M_pi->_M_get_use_count() : 0; } 741 742 bool 743 _M_unique() const noexcept 744 { return this->_M_get_use_count() == 1; } 745 746 void* 747 _M_get_deleter(const std::type_info& __ti) const noexcept 748 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; } 749 750 bool 751 _M_less(const __shared_count& __rhs) const noexcept 752 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 753 754 bool 755 _M_less(const __weak_count<_Lp>& __rhs) const noexcept 756 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 757 758 // Friend function injected into enclosing namespace and found by ADL 759 friend inline bool 760 operator==(const __shared_count& __a, const __shared_count& __b) noexcept 761 { return __a._M_pi == __b._M_pi; } 762 763 private: 764 friend class __weak_count<_Lp>; 765 766 _Sp_counted_base<_Lp>* _M_pi; 767 }; 768 769 770 template<_Lock_policy _Lp> 771 class __weak_count 772 { 773 public: 774 constexpr __weak_count() noexcept : _M_pi(nullptr) 775 { } 776 777 __weak_count(const __shared_count<_Lp>& __r) noexcept 778 : _M_pi(__r._M_pi) 779 { 780 if (_M_pi != nullptr) 781 _M_pi->_M_weak_add_ref(); 782 } 783 784 __weak_count(const __weak_count& __r) noexcept 785 : _M_pi(__r._M_pi) 786 { 787 if (_M_pi != nullptr) 788 _M_pi->_M_weak_add_ref(); 789 } 790 791 __weak_count(__weak_count&& __r) noexcept 792 : _M_pi(__r._M_pi) 793 { __r._M_pi = nullptr; } 794 795 ~__weak_count() noexcept 796 { 797 if (_M_pi != nullptr) 798 _M_pi->_M_weak_release(); 799 } 800 801 __weak_count& 802 operator=(const __shared_count<_Lp>& __r) noexcept 803 { 804 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 805 if (__tmp != nullptr) 806 __tmp->_M_weak_add_ref(); 807 if (_M_pi != nullptr) 808 _M_pi->_M_weak_release(); 809 _M_pi = __tmp; 810 return *this; 811 } 812 813 __weak_count& 814 operator=(const __weak_count& __r) noexcept 815 { 816 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 817 if (__tmp != nullptr) 818 __tmp->_M_weak_add_ref(); 819 if (_M_pi != nullptr) 820 _M_pi->_M_weak_release(); 821 _M_pi = __tmp; 822 return *this; 823 } 824 825 __weak_count& 826 operator=(__weak_count&& __r) noexcept 827 { 828 if (_M_pi != nullptr) 829 _M_pi->_M_weak_release(); 830 _M_pi = __r._M_pi; 831 __r._M_pi = nullptr; 832 return *this; 833 } 834 835 void 836 _M_swap(__weak_count& __r) noexcept 837 { 838 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 839 __r._M_pi = _M_pi; 840 _M_pi = __tmp; 841 } 842 843 long 844 _M_get_use_count() const noexcept 845 { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; } 846 847 bool 848 _M_less(const __weak_count& __rhs) const noexcept 849 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 850 851 bool 852 _M_less(const __shared_count<_Lp>& __rhs) const noexcept 853 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 854 855 // Friend function injected into enclosing namespace and found by ADL 856 friend inline bool 857 operator==(const __weak_count& __a, const __weak_count& __b) noexcept 858 { return __a._M_pi == __b._M_pi; } 859 860 private: 861 friend class __shared_count<_Lp>; 862 863 _Sp_counted_base<_Lp>* _M_pi; 864 }; 865 866 // Now that __weak_count is defined we can define this constructor: 867 template<_Lock_policy _Lp> 868 inline 869 __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r) 870 : _M_pi(__r._M_pi) 871 { 872 if (_M_pi == nullptr || !_M_pi->_M_add_ref_lock_nothrow()) 873 __throw_bad_weak_ptr(); 874 } 875 876 // Now that __weak_count is defined we can define this constructor: 877 template<_Lock_policy _Lp> 878 inline 879 __shared_count<_Lp>:: 880 __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept 881 : _M_pi(__r._M_pi) 882 { 883 if (_M_pi && !_M_pi->_M_add_ref_lock_nothrow()) 884 _M_pi = nullptr; 885 } 886 887 #define __cpp_lib_shared_ptr_arrays 201611L 888 889 // Helper traits for shared_ptr of array: 890 891 // A pointer type Y* is said to be compatible with a pointer type T* when 892 // either Y* is convertible to T* or Y is U[N] and T is U cv []. 893 template
894 struct __sp_compatible_with 895 : false_type 896 { }; 897 898 template
899 struct __sp_compatible_with<_Yp*, _Tp*> 900 : is_convertible<_Yp*, _Tp*>::type 901 { }; 902 903 template
904 struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]> 905 : true_type 906 { }; 907 908 template
909 struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]> 910 : true_type 911 { }; 912 913 template
914 struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]> 915 : true_type 916 { }; 917 918 template
919 struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]> 920 : true_type 921 { }; 922 923 // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N]. 924 template
925 struct __sp_is_constructible_arrN 926 : false_type 927 { }; 928 929 template
930 struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>> 931 : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type 932 { }; 933 934 // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[]. 935 template
936 struct __sp_is_constructible_arr 937 : false_type 938 { }; 939 940 template
941 struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>> 942 : is_convertible<_Yp(*)[], _Up(*)[]>::type 943 { }; 944 945 // Trait to check if shared_ptr
can be constructed from Y*. 946 template
947 struct __sp_is_constructible; 948 949 // When T is U[N], Y(*)[N] shall be convertible to T*; 950 template
951 struct __sp_is_constructible<_Up[_Nm], _Yp> 952 : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type 953 { }; 954 955 // when T is U[], Y(*)[] shall be convertible to T*; 956 template
957 struct __sp_is_constructible<_Up[], _Yp> 958 : __sp_is_constructible_arr<_Up, _Yp>::type 959 { }; 960 961 // otherwise, Y* shall be convertible to T*. 962 template
963 struct __sp_is_constructible 964 : is_convertible<_Yp*, _Tp*>::type 965 { }; 966 967 968 // Define operator* and operator-> for shared_ptr
. 969 template
::value, bool = is_void<_Tp>::value> 971 class __shared_ptr_access 972 { 973 public: 974 using element_type = _Tp; 975 976 element_type& 977 operator*() const noexcept 978 { 979 __glibcxx_assert(_M_get() != nullptr); 980 return *_M_get(); 981 } 982 983 element_type* 984 operator->() const noexcept 985 { 986 _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr); 987 return _M_get(); 988 } 989 990 private: 991 element_type* 992 _M_get() const noexcept 993 { return static_cast
*>(this)->get(); } 994 }; 995 996 // Define operator-> for shared_ptr
. 997 template
998 class __shared_ptr_access<_Tp, _Lp, false, true> 999 { 1000 public: 1001 using element_type = _Tp; 1002 1003 element_type* 1004 operator->() const noexcept 1005 { 1006 auto __ptr = static_cast
*>(this)->get(); 1007 _GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr); 1008 return __ptr; 1009 } 1010 }; 1011 1012 // Define operator[] for shared_ptr
and shared_ptr
. 1013 template
1014 class __shared_ptr_access<_Tp, _Lp, true, false> 1015 { 1016 public: 1017 using element_type = typename remove_extent<_Tp>::type; 1018 1019 #if __cplusplus <= 201402L 1020 [[__deprecated__("shared_ptr
::operator* is absent from C++17")]] 1021 element_type& 1022 operator*() const noexcept 1023 { 1024 __glibcxx_assert(_M_get() != nullptr); 1025 return *_M_get(); 1026 } 1027 1028 [[__deprecated__("shared_ptr
::operator-> is absent from C++17")]] 1029 element_type* 1030 operator->() const noexcept 1031 { 1032 _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr); 1033 return _M_get(); 1034 } 1035 #endif 1036 1037 element_type& 1038 operator[](ptrdiff_t __i) const 1039 { 1040 __glibcxx_assert(_M_get() != nullptr); 1041 __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value); 1042 return _M_get()[__i]; 1043 } 1044 1045 private: 1046 element_type* 1047 _M_get() const noexcept 1048 { return static_cast
*>(this)->get(); } 1049 }; 1050 1051 template
1052 class __shared_ptr 1053 : public __shared_ptr_access<_Tp, _Lp> 1054 { 1055 public: 1056 using element_type = typename remove_extent<_Tp>::type; 1057 1058 private: 1059 // Constraint for taking ownership of a pointer of type _Yp*: 1060 template
1061 using _SafeConv 1062 = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type; 1063 1064 // Constraint for construction from shared_ptr and weak_ptr: 1065 template
1066 using _Compatible = typename 1067 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type; 1068 1069 // Constraint for assignment from shared_ptr and weak_ptr: 1070 template
1071 using _Assignable = _Compatible<_Yp, __shared_ptr&>; 1072 1073 // Constraint for construction from unique_ptr: 1074 template
::pointer> 1076 using _UniqCompatible = __enable_if_t<__and_< 1077 __sp_compatible_with<_Yp*, _Tp*>, 1078 is_convertible<_Ptr, element_type*>, 1079 is_move_constructible<_Del> 1080 >::value, _Res>; 1081 1082 // Constraint for assignment from unique_ptr: 1083 template
1084 using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>; 1085 1086 public: 1087 1088 #if __cplusplus > 201402L 1089 using weak_type = __weak_ptr<_Tp, _Lp>; 1090 #endif 1091 1092 constexpr __shared_ptr() noexcept 1093 : _M_ptr(0), _M_refcount() 1094 { } 1095 1096 template
> 1097 explicit 1098 __shared_ptr(_Yp* __p) 1099 : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type()) 1100 { 1101 static_assert( !is_void<_Yp>::value, "incomplete type" ); 1102 static_assert( sizeof(_Yp) > 0, "incomplete type" ); 1103 _M_enable_shared_from_this_with(__p); 1104 } 1105 1106 template
> 1107 __shared_ptr(_Yp* __p, _Deleter __d) 1108 : _M_ptr(__p), _M_refcount(__p, std::move(__d)) 1109 { 1110 static_assert(__is_invocable<_Deleter&, _Yp*&>::value, 1111 "deleter expression d(p) is well-formed"); 1112 _M_enable_shared_from_this_with(__p); 1113 } 1114 1115 template
> 1117 __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a) 1118 : _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a)) 1119 { 1120 static_assert(__is_invocable<_Deleter&, _Yp*&>::value, 1121 "deleter expression d(p) is well-formed"); 1122 _M_enable_shared_from_this_with(__p); 1123 } 1124 1125 template
1126 __shared_ptr(nullptr_t __p, _Deleter __d) 1127 : _M_ptr(0), _M_refcount(__p, std::move(__d)) 1128 { } 1129 1130 template
1131 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 1132 : _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a)) 1133 { } 1134 1135 // Aliasing constructor 1136 template
1137 __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r, 1138 element_type* __p) noexcept 1139 : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws 1140 { } 1141 1142 // Aliasing constructor 1143 template
1144 __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r, 1145 element_type* __p) noexcept 1146 : _M_ptr(__p), _M_refcount() 1147 { 1148 _M_refcount._M_swap(__r._M_refcount); 1149 __r._M_ptr = nullptr; 1150 } 1151 1152 __shared_ptr(const __shared_ptr&) noexcept = default; 1153 __shared_ptr& operator=(const __shared_ptr&) noexcept = default; 1154 ~__shared_ptr() = default; 1155 1156 template
> 1157 __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept 1158 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 1159 { } 1160 1161 __shared_ptr(__shared_ptr&& __r) noexcept 1162 : _M_ptr(__r._M_ptr), _M_refcount() 1163 { 1164 _M_refcount._M_swap(__r._M_refcount); 1165 __r._M_ptr = nullptr; 1166 } 1167 1168 template
> 1169 __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept 1170 : _M_ptr(__r._M_ptr), _M_refcount() 1171 { 1172 _M_refcount._M_swap(__r._M_refcount); 1173 __r._M_ptr = nullptr; 1174 } 1175 1176 template
> 1177 explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r) 1178 : _M_refcount(__r._M_refcount) // may throw 1179 { 1180 // It is now safe to copy __r._M_ptr, as 1181 // _M_refcount(__r._M_refcount) did not throw. 1182 _M_ptr = __r._M_ptr; 1183 } 1184 1185 // If an exception is thrown this constructor has no effect. 1186 template
> 1188 __shared_ptr(unique_ptr<_Yp, _Del>&& __r) 1189 : _M_ptr(__r.get()), _M_refcount() 1190 { 1191 auto __raw = __to_address(__r.get()); 1192 _M_refcount = __shared_count<_Lp>(std::move(__r)); 1193 _M_enable_shared_from_this_with(__raw); 1194 } 1195 1196 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED 1197 protected: 1198 // If an exception is thrown this constructor has no effect. 1199 template
>, is_array<_Tp1>, 1202 is_convertible
::pointer, _Tp*> 1203 >::value, bool>::type = true> 1204 __shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete) 1205 : _M_ptr(__r.get()), _M_refcount() 1206 { 1207 auto __raw = __to_address(__r.get()); 1208 _M_refcount = __shared_count<_Lp>(std::move(__r)); 1209 _M_enable_shared_from_this_with(__raw); 1210 } 1211 public: 1212 #endif 1213 1214 #if _GLIBCXX_USE_DEPRECATED 1215 #pragma GCC diagnostic push 1216 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 1217 // Postcondition: use_count() == 1 and __r.get() == 0 1218 template
> 1219 __shared_ptr(auto_ptr<_Yp>&& __r); 1220 #pragma GCC diagnostic pop 1221 #endif 1222 1223 constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { } 1224 1225 template
1226 _Assignable<_Yp> 1227 operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept 1228 { 1229 _M_ptr = __r._M_ptr; 1230 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 1231 return *this; 1232 } 1233 1234 #if _GLIBCXX_USE_DEPRECATED 1235 #pragma GCC diagnostic push 1236 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 1237 template
1238 _Assignable<_Yp> 1239 operator=(auto_ptr<_Yp>&& __r) 1240 { 1241 __shared_ptr(std::move(__r)).swap(*this); 1242 return *this; 1243 } 1244 #pragma GCC diagnostic pop 1245 #endif 1246 1247 __shared_ptr& 1248 operator=(__shared_ptr&& __r) noexcept 1249 { 1250 __shared_ptr(std::move(__r)).swap(*this); 1251 return *this; 1252 } 1253 1254 template
1255 _Assignable<_Yp> 1256 operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept 1257 { 1258 __shared_ptr(std::move(__r)).swap(*this); 1259 return *this; 1260 } 1261 1262 template
1263 _UniqAssignable<_Yp, _Del> 1264 operator=(unique_ptr<_Yp, _Del>&& __r) 1265 { 1266 __shared_ptr(std::move(__r)).swap(*this); 1267 return *this; 1268 } 1269 1270 void 1271 reset() noexcept 1272 { __shared_ptr().swap(*this); } 1273 1274 template
1275 _SafeConv<_Yp> 1276 reset(_Yp* __p) // _Yp must be complete. 1277 { 1278 // Catch self-reset errors. 1279 __glibcxx_assert(__p == nullptr || __p != _M_ptr); 1280 __shared_ptr(__p).swap(*this); 1281 } 1282 1283 template
1284 _SafeConv<_Yp> 1285 reset(_Yp* __p, _Deleter __d) 1286 { __shared_ptr(__p, std::move(__d)).swap(*this); } 1287 1288 template
1289 _SafeConv<_Yp> 1290 reset(_Yp* __p, _Deleter __d, _Alloc __a) 1291 { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); } 1292 1293 /// Return the stored pointer. 1294 element_type* 1295 get() const noexcept 1296 { return _M_ptr; } 1297 1298 /// Return true if the stored pointer is not null. 1299 explicit operator bool() const noexcept 1300 { return _M_ptr != nullptr; } 1301 1302 /// Return true if use_count() == 1. 1303 bool 1304 unique() const noexcept 1305 { return _M_refcount._M_unique(); } 1306 1307 /// If *this owns a pointer, return the number of owners, otherwise zero. 1308 long 1309 use_count() const noexcept 1310 { return _M_refcount._M_get_use_count(); } 1311 1312 /// Exchange both the owned pointer and the stored pointer. 1313 void 1314 swap(__shared_ptr<_Tp, _Lp>& __other) noexcept 1315 { 1316 std::swap(_M_ptr, __other._M_ptr); 1317 _M_refcount._M_swap(__other._M_refcount); 1318 } 1319 1320 /** @brief Define an ordering based on ownership. 1321 * 1322 * This function defines a strict weak ordering between two shared_ptr 1323 * or weak_ptr objects, such that one object is less than the other 1324 * unless they share ownership of the same pointer, or are both empty. 1325 * @{ 1326 */ 1327 template
1328 bool 1329 owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept 1330 { return _M_refcount._M_less(__rhs._M_refcount); } 1331 1332 template
1333 bool 1334 owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept 1335 { return _M_refcount._M_less(__rhs._M_refcount); } 1336 /// @} 1337 1338 protected: 1339 // This constructor is non-standard, it is used by allocate_shared. 1340 template
1341 __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) 1342 : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...) 1343 { _M_enable_shared_from_this_with(_M_ptr); } 1344 1345 template
1347 friend __shared_ptr<_Tp1, _Lp1> 1348 __allocate_shared(const _Alloc& __a, _Args&&... __args); 1349 1350 // This constructor is used by __weak_ptr::lock() and 1351 // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t). 1352 __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) noexcept 1353 : _M_refcount(__r._M_refcount, std::nothrow) 1354 { 1355 _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr; 1356 } 1357 1358 friend class __weak_ptr<_Tp, _Lp>; 1359 1360 private: 1361 1362 template
1363 using __esft_base_t = decltype(__enable_shared_from_this_base( 1364 std::declval
&>(), 1365 std::declval<_Yp*>())); 1366 1367 // Detect an accessible and unambiguous enable_shared_from_this base. 1368 template
1369 struct __has_esft_base 1370 : false_type { }; 1371 1372 template
1373 struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>> 1374 : __not_
> { }; // No enable shared_from_this for arrays 1375 1376 template
::type> 1377 typename enable_if<__has_esft_base<_Yp2>::value>::type 1378 _M_enable_shared_from_this_with(_Yp* __p) noexcept 1379 { 1380 if (auto __base = __enable_shared_from_this_base(_M_refcount, __p)) 1381 __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount); 1382 } 1383 1384 template
::type> 1385 typename enable_if::value>::type 1386 _M_enable_shared_from_this_with(_Yp*) noexcept 1387 { } 1388 1389 void* 1390 _M_get_deleter(const std::type_info& __ti) const noexcept 1391 { return _M_refcount._M_get_deleter(__ti); } 1392 1393 template
friend class __shared_ptr; 1394 template
friend class __weak_ptr; 1395 1396 template
1397 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept; 1398 1399 template
1400 friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept; 1401 1402 element_type* _M_ptr; // Contained pointer. 1403 __shared_count<_Lp> _M_refcount; // Reference counter. 1404 }; 1405 1406 1407 // 20.7.2.2.7 shared_ptr comparisons 1408 template
1409 inline bool 1410 operator==(const __shared_ptr<_Tp1, _Lp>& __a, 1411 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1412 { return __a.get() == __b.get(); } 1413 1414 template
1415 inline bool 1416 operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1417 { return !__a; } 1418 1419 #ifdef __cpp_lib_three_way_comparison 1420 template
1421 inline strong_ordering 1422 operator<=>(const __shared_ptr<_Tp, _Lp>& __a, 1423 const __shared_ptr<_Up, _Lp>& __b) noexcept 1424 { return compare_three_way()(__a.get(), __b.get()); } 1425 1426 template
1427 inline strong_ordering 1428 operator<=>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1429 { 1430 using pointer = typename __shared_ptr<_Tp, _Lp>::element_type*; 1431 return compare_three_way()(__a.get(), static_cast
(nullptr)); 1432 } 1433 #else 1434 template
1435 inline bool 1436 operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1437 { return !__a; } 1438 1439 template
1440 inline bool 1441 operator!=(const __shared_ptr<_Tp1, _Lp>& __a, 1442 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1443 { return __a.get() != __b.get(); } 1444 1445 template
1446 inline bool 1447 operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1448 { return (bool)__a; } 1449 1450 template
1451 inline bool 1452 operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1453 { return (bool)__a; } 1454 1455 template
1456 inline bool 1457 operator<(const __shared_ptr<_Tp, _Lp>& __a, 1458 const __shared_ptr<_Up, _Lp>& __b) noexcept 1459 { 1460 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 1461 using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type; 1462 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; 1463 return less<_Vp>()(__a.get(), __b.get()); 1464 } 1465 1466 template
1467 inline bool 1468 operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1469 { 1470 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 1471 return less<_Tp_elt*>()(__a.get(), nullptr); 1472 } 1473 1474 template
1475 inline bool 1476 operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1477 { 1478 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 1479 return less<_Tp_elt*>()(nullptr, __a.get()); 1480 } 1481 1482 template
1483 inline bool 1484 operator<=(const __shared_ptr<_Tp1, _Lp>& __a, 1485 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1486 { return !(__b < __a); } 1487 1488 template
1489 inline bool 1490 operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1491 { return !(nullptr < __a); } 1492 1493 template
1494 inline bool 1495 operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1496 { return !(__a < nullptr); } 1497 1498 template
1499 inline bool 1500 operator>(const __shared_ptr<_Tp1, _Lp>& __a, 1501 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1502 { return (__b < __a); } 1503 1504 template
1505 inline bool 1506 operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1507 { return nullptr < __a; } 1508 1509 template
1510 inline bool 1511 operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1512 { return __a < nullptr; } 1513 1514 template
1515 inline bool 1516 operator>=(const __shared_ptr<_Tp1, _Lp>& __a, 1517 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1518 { return !(__a < __b); } 1519 1520 template
1521 inline bool 1522 operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1523 { return !(__a < nullptr); } 1524 1525 template
1526 inline bool 1527 operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1528 { return !(nullptr < __a); } 1529 #endif // three-way comparison 1530 1531 // 20.7.2.2.8 shared_ptr specialized algorithms. 1532 template
1533 inline void 1534 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept 1535 { __a.swap(__b); } 1536 1537 // 20.7.2.2.9 shared_ptr casts 1538 1539 // The seemingly equivalent code: 1540 // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) 1541 // will eventually result in undefined behaviour, attempting to 1542 // delete the same object twice. 1543 /// static_pointer_cast 1544 template
1545 inline __shared_ptr<_Tp, _Lp> 1546 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1547 { 1548 using _Sp = __shared_ptr<_Tp, _Lp>; 1549 return _Sp(__r, static_cast
(__r.get())); 1550 } 1551 1552 // The seemingly equivalent code: 1553 // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) 1554 // will eventually result in undefined behaviour, attempting to 1555 // delete the same object twice. 1556 /// const_pointer_cast 1557 template
1558 inline __shared_ptr<_Tp, _Lp> 1559 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1560 { 1561 using _Sp = __shared_ptr<_Tp, _Lp>; 1562 return _Sp(__r, const_cast
(__r.get())); 1563 } 1564 1565 // The seemingly equivalent code: 1566 // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) 1567 // will eventually result in undefined behaviour, attempting to 1568 // delete the same object twice. 1569 /// dynamic_pointer_cast 1570 template
1571 inline __shared_ptr<_Tp, _Lp> 1572 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1573 { 1574 using _Sp = __shared_ptr<_Tp, _Lp>; 1575 if (auto* __p = dynamic_cast
(__r.get())) 1576 return _Sp(__r, __p); 1577 return _Sp(); 1578 } 1579 1580 #if __cplusplus > 201402L 1581 template
1582 inline __shared_ptr<_Tp, _Lp> 1583 reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1584 { 1585 using _Sp = __shared_ptr<_Tp, _Lp>; 1586 return _Sp(__r, reinterpret_cast
(__r.get())); 1587 } 1588 #endif 1589 1590 template
1591 class __weak_ptr 1592 { 1593 template
1594 using _Compatible = typename 1595 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type; 1596 1597 // Constraint for assignment from shared_ptr and weak_ptr: 1598 template
1599 using _Assignable = _Compatible<_Yp, __weak_ptr&>; 1600 1601 public: 1602 using element_type = typename remove_extent<_Tp>::type; 1603 1604 constexpr __weak_ptr() noexcept 1605 : _M_ptr(nullptr), _M_refcount() 1606 { } 1607 1608 __weak_ptr(const __weak_ptr&) noexcept = default; 1609 1610 ~__weak_ptr() = default; 1611 1612 // The "obvious" converting constructor implementation: 1613 // 1614 // template
1615 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 1616 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 1617 // { } 1618 // 1619 // has a serious problem. 1620 // 1621 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 1622 // conversion may require access to *__r._M_ptr (virtual inheritance). 1623 // 1624 // It is not possible to avoid spurious access violations since 1625 // in multithreaded programs __r._M_ptr may be invalidated at any point. 1626 template
> 1627 __weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept 1628 : _M_refcount(__r._M_refcount) 1629 { _M_ptr = __r.lock().get(); } 1630 1631 template
> 1632 __weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept 1633 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 1634 { } 1635 1636 __weak_ptr(__weak_ptr&& __r) noexcept 1637 : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount)) 1638 { __r._M_ptr = nullptr; } 1639 1640 template
> 1641 __weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept 1642 : _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount)) 1643 { __r._M_ptr = nullptr; } 1644 1645 __weak_ptr& 1646 operator=(const __weak_ptr& __r) noexcept = default; 1647 1648 template
1649 _Assignable<_Yp> 1650 operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept 1651 { 1652 _M_ptr = __r.lock().get(); 1653 _M_refcount = __r._M_refcount; 1654 return *this; 1655 } 1656 1657 template
1658 _Assignable<_Yp> 1659 operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept 1660 { 1661 _M_ptr = __r._M_ptr; 1662 _M_refcount = __r._M_refcount; 1663 return *this; 1664 } 1665 1666 __weak_ptr& 1667 operator=(__weak_ptr&& __r) noexcept 1668 { 1669 __weak_ptr(std::move(__r)).swap(*this); 1670 return *this; 1671 } 1672 1673 template
1674 _Assignable<_Yp> 1675 operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept 1676 { 1677 _M_ptr = __r.lock().get(); 1678 _M_refcount = std::move(__r._M_refcount); 1679 __r._M_ptr = nullptr; 1680 return *this; 1681 } 1682 1683 __shared_ptr<_Tp, _Lp> 1684 lock() const noexcept 1685 { return __shared_ptr
(*this, std::nothrow); } 1686 1687 long 1688 use_count() const noexcept 1689 { return _M_refcount._M_get_use_count(); } 1690 1691 bool 1692 expired() const noexcept 1693 { return _M_refcount._M_get_use_count() == 0; } 1694 1695 template
1696 bool 1697 owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept 1698 { return _M_refcount._M_less(__rhs._M_refcount); } 1699 1700 template
1701 bool 1702 owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept 1703 { return _M_refcount._M_less(__rhs._M_refcount); } 1704 1705 void 1706 reset() noexcept 1707 { __weak_ptr().swap(*this); } 1708 1709 void 1710 swap(__weak_ptr& __s) noexcept 1711 { 1712 std::swap(_M_ptr, __s._M_ptr); 1713 _M_refcount._M_swap(__s._M_refcount); 1714 } 1715 1716 private: 1717 // Used by __enable_shared_from_this. 1718 void 1719 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept 1720 { 1721 if (use_count() == 0) 1722 { 1723 _M_ptr = __ptr; 1724 _M_refcount = __refcount; 1725 } 1726 } 1727 1728 template
friend class __shared_ptr; 1729 template
friend class __weak_ptr; 1730 friend class __enable_shared_from_this<_Tp, _Lp>; 1731 friend class enable_shared_from_this<_Tp>; 1732 1733 element_type* _M_ptr; // Contained pointer. 1734 __weak_count<_Lp> _M_refcount; // Reference counter. 1735 }; 1736 1737 // 20.7.2.3.6 weak_ptr specialized algorithms. 1738 template
1739 inline void 1740 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept 1741 { __a.swap(__b); } 1742 1743 template
1744 struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool> 1745 { 1746 bool 1747 operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept 1748 { return __lhs.owner_before(__rhs); } 1749 1750 bool 1751 operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept 1752 { return __lhs.owner_before(__rhs); } 1753 1754 bool 1755 operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept 1756 { return __lhs.owner_before(__rhs); } 1757 }; 1758 1759 template<> 1760 struct _Sp_owner_less
1761 { 1762 template
1763 auto 1764 operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept 1765 -> decltype(__lhs.owner_before(__rhs)) 1766 { return __lhs.owner_before(__rhs); } 1767 1768 using is_transparent = void; 1769 }; 1770 1771 template
1772 struct owner_less<__shared_ptr<_Tp, _Lp>> 1773 : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>> 1774 { }; 1775 1776 template
1777 struct owner_less<__weak_ptr<_Tp, _Lp>> 1778 : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>> 1779 { }; 1780 1781 1782 template
1783 class __enable_shared_from_this 1784 { 1785 protected: 1786 constexpr __enable_shared_from_this() noexcept { } 1787 1788 __enable_shared_from_this(const __enable_shared_from_this&) noexcept { } 1789 1790 __enable_shared_from_this& 1791 operator=(const __enable_shared_from_this&) noexcept 1792 { return *this; } 1793 1794 ~__enable_shared_from_this() { } 1795 1796 public: 1797 __shared_ptr<_Tp, _Lp> 1798 shared_from_this() 1799 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 1800 1801 __shared_ptr
1802 shared_from_this() const 1803 { return __shared_ptr
(this->_M_weak_this); } 1804 1805 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 1806 __weak_ptr<_Tp, _Lp> 1807 weak_from_this() noexcept 1808 { return this->_M_weak_this; } 1809 1810 __weak_ptr
1811 weak_from_this() const noexcept 1812 { return this->_M_weak_this; } 1813 #endif 1814 1815 private: 1816 template
1817 void 1818 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept 1819 { _M_weak_this._M_assign(__p, __n); } 1820 1821 friend const __enable_shared_from_this* 1822 __enable_shared_from_this_base(const __shared_count<_Lp>&, 1823 const __enable_shared_from_this* __p) 1824 { return __p; } 1825 1826 template
1827 friend class __shared_ptr; 1828 1829 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 1830 }; 1831 1832 template
1834 inline __shared_ptr<_Tp, _Lp> 1835 __allocate_shared(const _Alloc& __a, _Args&&... __args) 1836 { 1837 static_assert(!is_array<_Tp>::value, "make_shared
not supported"); 1838 1839 return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a}, 1840 std::forward<_Args>(__args)...); 1841 } 1842 1843 template
1845 inline __shared_ptr<_Tp, _Lp> 1846 __make_shared(_Args&&... __args) 1847 { 1848 typedef typename std::remove_const<_Tp>::type _Tp_nc; 1849 return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(), 1850 std::forward<_Args>(__args)...); 1851 } 1852 1853 /// std::hash specialization for __shared_ptr. 1854 template
1855 struct hash<__shared_ptr<_Tp, _Lp>> 1856 : public __hash_base
> 1857 { 1858 size_t 1859 operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept 1860 { 1861 return hash
::element_type*>()( 1862 __s.get()); 1863 } 1864 }; 1865 1866 _GLIBCXX_END_NAMESPACE_VERSION 1867 } // namespace 1868 1869 #endif // _SHARED_PTR_BASE_H
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™