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