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 // _GLIBCXX_RESOLVE_LIB_DEFECTS 720 // 3548. shared_ptr construction from unique_ptr should move 721 // (not copy) the deleter 722 _Alloc_traits::construct(__a, __mem, __r.release(), 723 std::forward<_Del>(__r.get_deleter())); 724 _M_pi = __mem; 725 } 726 727 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 728 explicit __shared_count(const __weak_count<_Lp>& __r); 729 730 // Does not throw if __r._M_get_use_count() == 0, caller must check. 731 explicit __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t); 732 733 ~__shared_count() noexcept 734 { 735 if (_M_pi != nullptr) 736 _M_pi->_M_release(); 737 } 738 739 __shared_count(const __shared_count& __r) noexcept 740 : _M_pi(__r._M_pi) 741 { 742 if (_M_pi != 0) 743 _M_pi->_M_add_ref_copy(); 744 } 745 746 __shared_count& 747 operator=(const __shared_count& __r) noexcept 748 { 749 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 750 if (__tmp != _M_pi) 751 { 752 if (__tmp != 0) 753 __tmp->_M_add_ref_copy(); 754 if (_M_pi != 0) 755 _M_pi->_M_release(); 756 _M_pi = __tmp; 757 } 758 return *this; 759 } 760 761 void 762 _M_swap(__shared_count& __r) noexcept 763 { 764 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 765 __r._M_pi = _M_pi; 766 _M_pi = __tmp; 767 } 768 769 long 770 _M_get_use_count() const noexcept 771 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 772 773 bool 774 _M_unique() const noexcept 775 { return this->_M_get_use_count() == 1; } 776 777 void* 778 _M_get_deleter(const std::type_info& __ti) const noexcept 779 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; } 780 781 bool 782 _M_less(const __shared_count& __rhs) const noexcept 783 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 784 785 bool 786 _M_less(const __weak_count<_Lp>& __rhs) const noexcept 787 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 788 789 // Friend function injected into enclosing namespace and found by ADL 790 friend inline bool 791 operator==(const __shared_count& __a, const __shared_count& __b) noexcept 792 { return __a._M_pi == __b._M_pi; } 793 794 private: 795 friend class __weak_count<_Lp>; 796 797 _Sp_counted_base<_Lp>* _M_pi; 798 }; 799 800 801 template<_Lock_policy _Lp> 802 class __weak_count 803 { 804 public: 805 constexpr __weak_count() noexcept : _M_pi(nullptr) 806 { } 807 808 __weak_count(const __shared_count<_Lp>& __r) noexcept 809 : _M_pi(__r._M_pi) 810 { 811 if (_M_pi != nullptr) 812 _M_pi->_M_weak_add_ref(); 813 } 814 815 __weak_count(const __weak_count& __r) noexcept 816 : _M_pi(__r._M_pi) 817 { 818 if (_M_pi != nullptr) 819 _M_pi->_M_weak_add_ref(); 820 } 821 822 __weak_count(__weak_count&& __r) noexcept 823 : _M_pi(__r._M_pi) 824 { __r._M_pi = nullptr; } 825 826 ~__weak_count() noexcept 827 { 828 if (_M_pi != nullptr) 829 _M_pi->_M_weak_release(); 830 } 831 832 __weak_count& 833 operator=(const __shared_count<_Lp>& __r) noexcept 834 { 835 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 836 if (__tmp != nullptr) 837 __tmp->_M_weak_add_ref(); 838 if (_M_pi != nullptr) 839 _M_pi->_M_weak_release(); 840 _M_pi = __tmp; 841 return *this; 842 } 843 844 __weak_count& 845 operator=(const __weak_count& __r) noexcept 846 { 847 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 848 if (__tmp != nullptr) 849 __tmp->_M_weak_add_ref(); 850 if (_M_pi != nullptr) 851 _M_pi->_M_weak_release(); 852 _M_pi = __tmp; 853 return *this; 854 } 855 856 __weak_count& 857 operator=(__weak_count&& __r) noexcept 858 { 859 if (_M_pi != nullptr) 860 _M_pi->_M_weak_release(); 861 _M_pi = __r._M_pi; 862 __r._M_pi = nullptr; 863 return *this; 864 } 865 866 void 867 _M_swap(__weak_count& __r) noexcept 868 { 869 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 870 __r._M_pi = _M_pi; 871 _M_pi = __tmp; 872 } 873 874 long 875 _M_get_use_count() const noexcept 876 { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; } 877 878 bool 879 _M_less(const __weak_count& __rhs) const noexcept 880 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 881 882 bool 883 _M_less(const __shared_count<_Lp>& __rhs) const noexcept 884 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 885 886 // Friend function injected into enclosing namespace and found by ADL 887 friend inline bool 888 operator==(const __weak_count& __a, const __weak_count& __b) noexcept 889 { return __a._M_pi == __b._M_pi; } 890 891 private: 892 friend class __shared_count<_Lp>; 893 894 _Sp_counted_base<_Lp>* _M_pi; 895 }; 896 897 // Now that __weak_count is defined we can define this constructor: 898 template<_Lock_policy _Lp> 899 inline 900 __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r) 901 : _M_pi(__r._M_pi) 902 { 903 if (_M_pi != nullptr) 904 _M_pi->_M_add_ref_lock(); 905 else 906 __throw_bad_weak_ptr(); 907 } 908 909 // Now that __weak_count is defined we can define this constructor: 910 template<_Lock_policy _Lp> 911 inline 912 __shared_count<_Lp>:: 913 __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) 914 : _M_pi(__r._M_pi) 915 { 916 if (_M_pi != nullptr) 917 if (!_M_pi->_M_add_ref_lock_nothrow()) 918 _M_pi = nullptr; 919 } 920 921 #define __cpp_lib_shared_ptr_arrays 201611L 922 923 // Helper traits for shared_ptr of array: 924 925 // A pointer type Y* is said to be compatible with a pointer type T* when 926 // either Y* is convertible to T* or Y is U[N] and T is U cv []. 927 template<typename _Yp_ptr, typename _Tp_ptr> 928 struct __sp_compatible_with 929 : false_type 930 { }; 931 932 template<typename _Yp, typename _Tp> 933 struct __sp_compatible_with<_Yp*, _Tp*> 934 : is_convertible<_Yp*, _Tp*>::type 935 { }; 936 937 template<typename _Up, size_t _Nm> 938 struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]> 939 : true_type 940 { }; 941 942 template<typename _Up, size_t _Nm> 943 struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]> 944 : true_type 945 { }; 946 947 template<typename _Up, size_t _Nm> 948 struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]> 949 : true_type 950 { }; 951 952 template<typename _Up, size_t _Nm> 953 struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]> 954 : true_type 955 { }; 956 957 // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N]. 958 template<typename _Up, size_t _Nm, typename _Yp, typename = void> 959 struct __sp_is_constructible_arrN 960 : false_type 961 { }; 962 963 template<typename _Up, size_t _Nm, typename _Yp> 964 struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>> 965 : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type 966 { }; 967 968 // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[]. 969 template<typename _Up, typename _Yp, typename = void> 970 struct __sp_is_constructible_arr 971 : false_type 972 { }; 973 974 template<typename _Up, typename _Yp> 975 struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>> 976 : is_convertible<_Yp(*)[], _Up(*)[]>::type 977 { }; 978 979 // Trait to check if shared_ptr<T> can be constructed from Y*. 980 template<typename _Tp, typename _Yp> 981 struct __sp_is_constructible; 982 983 // When T is U[N], Y(*)[N] shall be convertible to T*; 984 template<typename _Up, size_t _Nm, typename _Yp> 985 struct __sp_is_constructible<_Up[_Nm], _Yp> 986 : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type 987 { }; 988 989 // when T is U[], Y(*)[] shall be convertible to T*; 990 template<typename _Up, typename _Yp> 991 struct __sp_is_constructible<_Up[], _Yp> 992 : __sp_is_constructible_arr<_Up, _Yp>::type 993 { }; 994 995 // otherwise, Y* shall be convertible to T*. 996 template<typename _Tp, typename _Yp> 997 struct __sp_is_constructible 998 : is_convertible<_Yp*, _Tp*>::type 999 { }; 1000 1001 1002 // Define operator* and operator-> for shared_ptr<T>. 1003 template<typename _Tp, _Lock_policy _Lp, 1004 bool = is_array<_Tp>::value, bool = is_void<_Tp>::value> 1005 class __shared_ptr_access 1006 { 1007 public: 1008 using element_type = _Tp; 1009 1010 element_type& 1011 operator*() const noexcept 1012 { 1013 __glibcxx_assert(_M_get() != nullptr); 1014 return *_M_get(); 1015 } 1016 1017 element_type* 1018 operator->() const noexcept 1019 { 1020 _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr); 1021 return _M_get(); 1022 } 1023 1024 private: 1025 element_type* 1026 _M_get() const noexcept 1027 { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); } 1028 }; 1029 1030 // Define operator-> for shared_ptr<cv void>. 1031 template<typename _Tp, _Lock_policy _Lp> 1032 class __shared_ptr_access<_Tp, _Lp, false, true> 1033 { 1034 public: 1035 using element_type = _Tp; 1036 1037 element_type* 1038 operator->() const noexcept 1039 { 1040 auto __ptr = static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); 1041 _GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr); 1042 return __ptr; 1043 } 1044 }; 1045 1046 // Define operator[] for shared_ptr<T[]> and shared_ptr<T[N]>. 1047 template<typename _Tp, _Lock_policy _Lp> 1048 class __shared_ptr_access<_Tp, _Lp, true, false> 1049 { 1050 public: 1051 using element_type = typename remove_extent<_Tp>::type; 1052 1053 #if __cplusplus <= 201402L 1054 [[__deprecated__("shared_ptr<T[]>::operator* is absent from C++17")]] 1055 element_type& 1056 operator*() const noexcept 1057 { 1058 __glibcxx_assert(_M_get() != nullptr); 1059 return *_M_get(); 1060 } 1061 1062 [[__deprecated__("shared_ptr<T[]>::operator-> is absent from C++17")]] 1063 element_type* 1064 operator->() const noexcept 1065 { 1066 _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr); 1067 return _M_get(); 1068 } 1069 #endif 1070 1071 element_type& 1072 operator[](ptrdiff_t __i) const 1073 { 1074 __glibcxx_assert(_M_get() != nullptr); 1075 __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value); 1076 return _M_get()[__i]; 1077 } 1078 1079 private: 1080 element_type* 1081 _M_get() const noexcept 1082 { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); } 1083 }; 1084 1085 template<typename _Tp, _Lock_policy _Lp> 1086 class __shared_ptr 1087 : public __shared_ptr_access<_Tp, _Lp> 1088 { 1089 public: 1090 using element_type = typename remove_extent<_Tp>::type; 1091 1092 private: 1093 // Constraint for taking ownership of a pointer of type _Yp*: 1094 template<typename _Yp> 1095 using _SafeConv 1096 = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type; 1097 1098 // Constraint for construction from shared_ptr and weak_ptr: 1099 template<typename _Yp, typename _Res = void> 1100 using _Compatible = typename 1101 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type; 1102 1103 // Constraint for assignment from shared_ptr and weak_ptr: 1104 template<typename _Yp> 1105 using _Assignable = _Compatible<_Yp, __shared_ptr&>; 1106 1107 // Constraint for construction from unique_ptr: 1108 template<typename _Yp, typename _Del, typename _Res = void, 1109 typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer> 1110 using _UniqCompatible = __enable_if_t<__and_< 1111 __sp_compatible_with<_Yp*, _Tp*>, 1112 is_convertible<_Ptr, element_type*>, 1113 is_move_constructible<_Del> 1114 >::value, _Res>; 1115 1116 // Constraint for assignment from unique_ptr: 1117 template<typename _Yp, typename _Del> 1118 using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>; 1119 1120 public: 1121 1122 #if __cplusplus > 201402L 1123 using weak_type = __weak_ptr<_Tp, _Lp>; 1124 #endif 1125 1126 constexpr __shared_ptr() noexcept 1127 : _M_ptr(0), _M_refcount() 1128 { } 1129 1130 template<typename _Yp, typename = _SafeConv<_Yp>> 1131 explicit 1132 __shared_ptr(_Yp* __p) 1133 : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type()) 1134 { 1135 static_assert( !is_void<_Yp>::value, "incomplete type" ); 1136 static_assert( sizeof(_Yp) > 0, "incomplete type" ); 1137 _M_enable_shared_from_this_with(__p); 1138 } 1139 1140 template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>> 1141 __shared_ptr(_Yp* __p, _Deleter __d) 1142 : _M_ptr(__p), _M_refcount(__p, std::move(__d)) 1143 { 1144 static_assert(__is_invocable<_Deleter&, _Yp*&>::value, 1145 "deleter expression d(p) is well-formed"); 1146 _M_enable_shared_from_this_with(__p); 1147 } 1148 1149 template<typename _Yp, typename _Deleter, typename _Alloc, 1150 typename = _SafeConv<_Yp>> 1151 __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a) 1152 : _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a)) 1153 { 1154 static_assert(__is_invocable<_Deleter&, _Yp*&>::value, 1155 "deleter expression d(p) is well-formed"); 1156 _M_enable_shared_from_this_with(__p); 1157 } 1158 1159 template<typename _Deleter> 1160 __shared_ptr(nullptr_t __p, _Deleter __d) 1161 : _M_ptr(0), _M_refcount(__p, std::move(__d)) 1162 { } 1163 1164 template<typename _Deleter, typename _Alloc> 1165 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 1166 : _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a)) 1167 { } 1168 1169 // Aliasing constructor 1170 template<typename _Yp> 1171 __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r, 1172 element_type* __p) noexcept 1173 : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws 1174 { } 1175 1176 // Aliasing constructor 1177 template<typename _Yp> 1178 __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r, 1179 element_type* __p) noexcept 1180 : _M_ptr(__p), _M_refcount() 1181 { 1182 _M_refcount._M_swap(__r._M_refcount); 1183 __r._M_ptr = 0; 1184 } 1185 1186 __shared_ptr(const __shared_ptr&) noexcept = default; 1187 __shared_ptr& operator=(const __shared_ptr&) noexcept = default; 1188 ~__shared_ptr() = default; 1189 1190 template<typename _Yp, typename = _Compatible<_Yp>> 1191 __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept 1192 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 1193 { } 1194 1195 __shared_ptr(__shared_ptr&& __r) noexcept 1196 : _M_ptr(__r._M_ptr), _M_refcount() 1197 { 1198 _M_refcount._M_swap(__r._M_refcount); 1199 __r._M_ptr = 0; 1200 } 1201 1202 template<typename _Yp, typename = _Compatible<_Yp>> 1203 __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept 1204 : _M_ptr(__r._M_ptr), _M_refcount() 1205 { 1206 _M_refcount._M_swap(__r._M_refcount); 1207 __r._M_ptr = 0; 1208 } 1209 1210 template<typename _Yp, typename = _Compatible<_Yp>> 1211 explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r) 1212 : _M_refcount(__r._M_refcount) // may throw 1213 { 1214 // It is now safe to copy __r._M_ptr, as 1215 // _M_refcount(__r._M_refcount) did not throw. 1216 _M_ptr = __r._M_ptr; 1217 } 1218 1219 // If an exception is thrown this constructor has no effect. 1220 template<typename _Yp, typename _Del, 1221 typename = _UniqCompatible<_Yp, _Del>> 1222 __shared_ptr(unique_ptr<_Yp, _Del>&& __r) 1223 : _M_ptr(__r.get()), _M_refcount() 1224 { 1225 auto __raw = __to_address(__r.get()); 1226 _M_refcount = __shared_count<_Lp>(std::move(__r)); 1227 _M_enable_shared_from_this_with(__raw); 1228 } 1229 1230 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED 1231 protected: 1232 // If an exception is thrown this constructor has no effect. 1233 template<typename _Tp1, typename _Del, 1234 typename enable_if<__and_< 1235 __not_<is_array<_Tp>>, is_array<_Tp1>, 1236 is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*> 1237 >::value, bool>::type = true> 1238 __shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete) 1239 : _M_ptr(__r.get()), _M_refcount() 1240 { 1241 auto __raw = __to_address(__r.get()); 1242 _M_refcount = __shared_count<_Lp>(std::move(__r)); 1243 _M_enable_shared_from_this_with(__raw); 1244 } 1245 public: 1246 #endif 1247 1248 #if _GLIBCXX_USE_DEPRECATED 1249 #pragma GCC diagnostic push 1250 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 1251 // Postcondition: use_count() == 1 and __r.get() == 0 1252 template<typename _Yp, typename = _Compatible<_Yp>> 1253 __shared_ptr(auto_ptr<_Yp>&& __r); 1254 #pragma GCC diagnostic pop 1255 #endif 1256 1257 constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { } 1258 1259 template<typename _Yp> 1260 _Assignable<_Yp> 1261 operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept 1262 { 1263 _M_ptr = __r._M_ptr; 1264 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 1265 return *this; 1266 } 1267 1268 #if _GLIBCXX_USE_DEPRECATED 1269 #pragma GCC diagnostic push 1270 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 1271 template<typename _Yp> 1272 _Assignable<_Yp> 1273 operator=(auto_ptr<_Yp>&& __r) 1274 { 1275 __shared_ptr(std::move(__r)).swap(*this); 1276 return *this; 1277 } 1278 #pragma GCC diagnostic pop 1279 #endif 1280 1281 __shared_ptr& 1282 operator=(__shared_ptr&& __r) noexcept 1283 { 1284 __shared_ptr(std::move(__r)).swap(*this); 1285 return *this; 1286 } 1287 1288 template<class _Yp> 1289 _Assignable<_Yp> 1290 operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept 1291 { 1292 __shared_ptr(std::move(__r)).swap(*this); 1293 return *this; 1294 } 1295 1296 template<typename _Yp, typename _Del> 1297 _UniqAssignable<_Yp, _Del> 1298 operator=(unique_ptr<_Yp, _Del>&& __r) 1299 { 1300 __shared_ptr(std::move(__r)).swap(*this); 1301 return *this; 1302 } 1303 1304 void 1305 reset() noexcept 1306 { __shared_ptr().swap(*this); } 1307 1308 template<typename _Yp> 1309 _SafeConv<_Yp> 1310 reset(_Yp* __p) // _Yp must be complete. 1311 { 1312 // Catch self-reset errors. 1313 __glibcxx_assert(__p == 0 || __p != _M_ptr); 1314 __shared_ptr(__p).swap(*this); 1315 } 1316 1317 template<typename _Yp, typename _Deleter> 1318 _SafeConv<_Yp> 1319 reset(_Yp* __p, _Deleter __d) 1320 { __shared_ptr(__p, std::move(__d)).swap(*this); } 1321 1322 template<typename _Yp, typename _Deleter, typename _Alloc> 1323 _SafeConv<_Yp> 1324 reset(_Yp* __p, _Deleter __d, _Alloc __a) 1325 { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); } 1326 1327 /// Return the stored pointer. 1328 element_type* 1329 get() const noexcept 1330 { return _M_ptr; } 1331 1332 /// Return true if the stored pointer is not null. 1333 explicit operator bool() const // never throws 1334 { return _M_ptr == 0 ? false : true; } 1335 1336 /// Return true if use_count() == 1. 1337 bool 1338 unique() const noexcept 1339 { return _M_refcount._M_unique(); } 1340 1341 /// If *this owns a pointer, return the number of owners, otherwise zero. 1342 long 1343 use_count() const noexcept 1344 { return _M_refcount._M_get_use_count(); } 1345 1346 /// Exchange both the owned pointer and the stored pointer. 1347 void 1348 swap(__shared_ptr<_Tp, _Lp>& __other) noexcept 1349 { 1350 std::swap(_M_ptr, __other._M_ptr); 1351 _M_refcount._M_swap(__other._M_refcount); 1352 } 1353 1354 /** @brief Define an ordering based on ownership. 1355 * 1356 * This function defines a strict weak ordering between two shared_ptr 1357 * or weak_ptr objects, such that one object is less than the other 1358 * unless they share ownership of the same pointer, or are both empty. 1359 * @{ 1360 */ 1361 template<typename _Tp1> 1362 bool 1363 owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept 1364 { return _M_refcount._M_less(__rhs._M_refcount); } 1365 1366 template<typename _Tp1> 1367 bool 1368 owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept 1369 { return _M_refcount._M_less(__rhs._M_refcount); } 1370 /// @} 1371 1372 protected: 1373 // This constructor is non-standard, it is used by allocate_shared. 1374 template<typename _Alloc, typename... _Args> 1375 __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) 1376 : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...) 1377 { _M_enable_shared_from_this_with(_M_ptr); } 1378 1379 template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc, 1380 typename... _Args> 1381 friend __shared_ptr<_Tp1, _Lp1> 1382 __allocate_shared(const _Alloc& __a, _Args&&... __args); 1383 1384 // This constructor is used by __weak_ptr::lock() and 1385 // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t). 1386 __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) 1387 : _M_refcount(__r._M_refcount, std::nothrow) 1388 { 1389 _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr; 1390 } 1391 1392 friend class __weak_ptr<_Tp, _Lp>; 1393 1394 private: 1395 1396 template<typename _Yp> 1397 using __esft_base_t = decltype(__enable_shared_from_this_base( 1398 std::declval<const __shared_count<_Lp>&>(), 1399 std::declval<_Yp*>())); 1400 1401 // Detect an accessible and unambiguous enable_shared_from_this base. 1402 template<typename _Yp, typename = void> 1403 struct __has_esft_base 1404 : false_type { }; 1405 1406 template<typename _Yp> 1407 struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>> 1408 : __not_<is_array<_Tp>> { }; // No enable shared_from_this for arrays 1409 1410 template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type> 1411 typename enable_if<__has_esft_base<_Yp2>::value>::type 1412 _M_enable_shared_from_this_with(_Yp* __p) noexcept 1413 { 1414 if (auto __base = __enable_shared_from_this_base(_M_refcount, __p)) 1415 __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount); 1416 } 1417 1418 template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type> 1419 typename enable_if<!__has_esft_base<_Yp2>::value>::type 1420 _M_enable_shared_from_this_with(_Yp*) noexcept 1421 { } 1422 1423 void* 1424 _M_get_deleter(const std::type_info& __ti) const noexcept 1425 { return _M_refcount._M_get_deleter(__ti); } 1426 1427 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 1428 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 1429 1430 template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 1431 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept; 1432 1433 template<typename _Del, typename _Tp1> 1434 friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept; 1435 1436 element_type* _M_ptr; // Contained pointer. 1437 __shared_count<_Lp> _M_refcount; // Reference counter. 1438 }; 1439 1440 1441 // 20.7.2.2.7 shared_ptr comparisons 1442 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 1443 inline bool 1444 operator==(const __shared_ptr<_Tp1, _Lp>& __a, 1445 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1446 { return __a.get() == __b.get(); } 1447 1448 template<typename _Tp, _Lock_policy _Lp> 1449 inline bool 1450 operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1451 { return !__a; } 1452 1453 #ifdef __cpp_lib_three_way_comparison 1454 template<typename _Tp, typename _Up, _Lock_policy _Lp> 1455 inline strong_ordering 1456 operator<=>(const __shared_ptr<_Tp, _Lp>& __a, 1457 const __shared_ptr<_Up, _Lp>& __b) noexcept 1458 { return compare_three_way()(__a.get(), __b.get()); } 1459 1460 template<typename _Tp, _Lock_policy _Lp> 1461 inline strong_ordering 1462 operator<=>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1463 { 1464 using pointer = typename __shared_ptr<_Tp, _Lp>::element_type*; 1465 return compare_three_way()(__a.get(), static_cast<pointer>(nullptr)); 1466 } 1467 #else 1468 template<typename _Tp, _Lock_policy _Lp> 1469 inline bool 1470 operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1471 { return !__a; } 1472 1473 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 1474 inline bool 1475 operator!=(const __shared_ptr<_Tp1, _Lp>& __a, 1476 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1477 { return __a.get() != __b.get(); } 1478 1479 template<typename _Tp, _Lock_policy _Lp> 1480 inline bool 1481 operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1482 { return (bool)__a; } 1483 1484 template<typename _Tp, _Lock_policy _Lp> 1485 inline bool 1486 operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1487 { return (bool)__a; } 1488 1489 template<typename _Tp, typename _Up, _Lock_policy _Lp> 1490 inline bool 1491 operator<(const __shared_ptr<_Tp, _Lp>& __a, 1492 const __shared_ptr<_Up, _Lp>& __b) noexcept 1493 { 1494 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 1495 using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type; 1496 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; 1497 return less<_Vp>()(__a.get(), __b.get()); 1498 } 1499 1500 template<typename _Tp, _Lock_policy _Lp> 1501 inline bool 1502 operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1503 { 1504 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 1505 return less<_Tp_elt*>()(__a.get(), nullptr); 1506 } 1507 1508 template<typename _Tp, _Lock_policy _Lp> 1509 inline bool 1510 operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1511 { 1512 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 1513 return less<_Tp_elt*>()(nullptr, __a.get()); 1514 } 1515 1516 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 1517 inline bool 1518 operator<=(const __shared_ptr<_Tp1, _Lp>& __a, 1519 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1520 { return !(__b < __a); } 1521 1522 template<typename _Tp, _Lock_policy _Lp> 1523 inline bool 1524 operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1525 { return !(nullptr < __a); } 1526 1527 template<typename _Tp, _Lock_policy _Lp> 1528 inline bool 1529 operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1530 { return !(__a < nullptr); } 1531 1532 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 1533 inline bool 1534 operator>(const __shared_ptr<_Tp1, _Lp>& __a, 1535 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1536 { return (__b < __a); } 1537 1538 template<typename _Tp, _Lock_policy _Lp> 1539 inline bool 1540 operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1541 { return nullptr < __a; } 1542 1543 template<typename _Tp, _Lock_policy _Lp> 1544 inline bool 1545 operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1546 { return __a < nullptr; } 1547 1548 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 1549 inline bool 1550 operator>=(const __shared_ptr<_Tp1, _Lp>& __a, 1551 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1552 { return !(__a < __b); } 1553 1554 template<typename _Tp, _Lock_policy _Lp> 1555 inline bool 1556 operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1557 { return !(__a < nullptr); } 1558 1559 template<typename _Tp, _Lock_policy _Lp> 1560 inline bool 1561 operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1562 { return !(nullptr < __a); } 1563 #endif // three-way comparison 1564 1565 // 20.7.2.2.8 shared_ptr specialized algorithms. 1566 template<typename _Tp, _Lock_policy _Lp> 1567 inline void 1568 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept 1569 { __a.swap(__b); } 1570 1571 // 20.7.2.2.9 shared_ptr casts 1572 1573 // The seemingly equivalent code: 1574 // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) 1575 // will eventually result in undefined behaviour, attempting to 1576 // delete the same object twice. 1577 /// static_pointer_cast 1578 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 1579 inline __shared_ptr<_Tp, _Lp> 1580 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1581 { 1582 using _Sp = __shared_ptr<_Tp, _Lp>; 1583 return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get())); 1584 } 1585 1586 // The seemingly equivalent code: 1587 // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) 1588 // will eventually result in undefined behaviour, attempting to 1589 // delete the same object twice. 1590 /// const_pointer_cast 1591 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 1592 inline __shared_ptr<_Tp, _Lp> 1593 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1594 { 1595 using _Sp = __shared_ptr<_Tp, _Lp>; 1596 return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get())); 1597 } 1598 1599 // The seemingly equivalent code: 1600 // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) 1601 // will eventually result in undefined behaviour, attempting to 1602 // delete the same object twice. 1603 /// dynamic_pointer_cast 1604 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 1605 inline __shared_ptr<_Tp, _Lp> 1606 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1607 { 1608 using _Sp = __shared_ptr<_Tp, _Lp>; 1609 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get())) 1610 return _Sp(__r, __p); 1611 return _Sp(); 1612 } 1613 1614 #if __cplusplus > 201402L 1615 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 1616 inline __shared_ptr<_Tp, _Lp> 1617 reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1618 { 1619 using _Sp = __shared_ptr<_Tp, _Lp>; 1620 return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get())); 1621 } 1622 #endif 1623 1624 template<typename _Tp, _Lock_policy _Lp> 1625 class __weak_ptr 1626 { 1627 template<typename _Yp, typename _Res = void> 1628 using _Compatible = typename 1629 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type; 1630 1631 // Constraint for assignment from shared_ptr and weak_ptr: 1632 template<typename _Yp> 1633 using _Assignable = _Compatible<_Yp, __weak_ptr&>; 1634 1635 public: 1636 using element_type = typename remove_extent<_Tp>::type; 1637 1638 constexpr __weak_ptr() noexcept 1639 : _M_ptr(nullptr), _M_refcount() 1640 { } 1641 1642 __weak_ptr(const __weak_ptr&) noexcept = default; 1643 1644 ~__weak_ptr() = default; 1645 1646 // The "obvious" converting constructor implementation: 1647 // 1648 // template<typename _Tp1> 1649 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 1650 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 1651 // { } 1652 // 1653 // has a serious problem. 1654 // 1655 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 1656 // conversion may require access to *__r._M_ptr (virtual inheritance). 1657 // 1658 // It is not possible to avoid spurious access violations since 1659 // in multithreaded programs __r._M_ptr may be invalidated at any point. 1660 template<typename _Yp, typename = _Compatible<_Yp>> 1661 __weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept 1662 : _M_refcount(__r._M_refcount) 1663 { _M_ptr = __r.lock().get(); } 1664 1665 template<typename _Yp, typename = _Compatible<_Yp>> 1666 __weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept 1667 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 1668 { } 1669 1670 __weak_ptr(__weak_ptr&& __r) noexcept 1671 : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount)) 1672 { __r._M_ptr = nullptr; } 1673 1674 template<typename _Yp, typename = _Compatible<_Yp>> 1675 __weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept 1676 : _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount)) 1677 { __r._M_ptr = nullptr; } 1678 1679 __weak_ptr& 1680 operator=(const __weak_ptr& __r) noexcept = default; 1681 1682 template<typename _Yp> 1683 _Assignable<_Yp> 1684 operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept 1685 { 1686 _M_ptr = __r.lock().get(); 1687 _M_refcount = __r._M_refcount; 1688 return *this; 1689 } 1690 1691 template<typename _Yp> 1692 _Assignable<_Yp> 1693 operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept 1694 { 1695 _M_ptr = __r._M_ptr; 1696 _M_refcount = __r._M_refcount; 1697 return *this; 1698 } 1699 1700 __weak_ptr& 1701 operator=(__weak_ptr&& __r) noexcept 1702 { 1703 __weak_ptr(std::move(__r)).swap(*this); 1704 return *this; 1705 } 1706 1707 template<typename _Yp> 1708 _Assignable<_Yp> 1709 operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept 1710 { 1711 _M_ptr = __r.lock().get(); 1712 _M_refcount = std::move(__r._M_refcount); 1713 __r._M_ptr = nullptr; 1714 return *this; 1715 } 1716 1717 __shared_ptr<_Tp, _Lp> 1718 lock() const noexcept 1719 { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); } 1720 1721 long 1722 use_count() const noexcept 1723 { return _M_refcount._M_get_use_count(); } 1724 1725 bool 1726 expired() const noexcept 1727 { return _M_refcount._M_get_use_count() == 0; } 1728 1729 template<typename _Tp1> 1730 bool 1731 owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept 1732 { return _M_refcount._M_less(__rhs._M_refcount); } 1733 1734 template<typename _Tp1> 1735 bool 1736 owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept 1737 { return _M_refcount._M_less(__rhs._M_refcount); } 1738 1739 void 1740 reset() noexcept 1741 { __weak_ptr().swap(*this); } 1742 1743 void 1744 swap(__weak_ptr& __s) noexcept 1745 { 1746 std::swap(_M_ptr, __s._M_ptr); 1747 _M_refcount._M_swap(__s._M_refcount); 1748 } 1749 1750 private: 1751 // Used by __enable_shared_from_this. 1752 void 1753 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept 1754 { 1755 if (use_count() == 0) 1756 { 1757 _M_ptr = __ptr; 1758 _M_refcount = __refcount; 1759 } 1760 } 1761 1762 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 1763 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 1764 friend class __enable_shared_from_this<_Tp, _Lp>; 1765 friend class enable_shared_from_this<_Tp>; 1766 1767 element_type* _M_ptr; // Contained pointer. 1768 __weak_count<_Lp> _M_refcount; // Reference counter. 1769 }; 1770 1771 // 20.7.2.3.6 weak_ptr specialized algorithms. 1772 template<typename _Tp, _Lock_policy _Lp> 1773 inline void 1774 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept 1775 { __a.swap(__b); } 1776 1777 template<typename _Tp, typename _Tp1> 1778 struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool> 1779 { 1780 bool 1781 operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept 1782 { return __lhs.owner_before(__rhs); } 1783 1784 bool 1785 operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept 1786 { return __lhs.owner_before(__rhs); } 1787 1788 bool 1789 operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept 1790 { return __lhs.owner_before(__rhs); } 1791 }; 1792 1793 template<> 1794 struct _Sp_owner_less<void, void> 1795 { 1796 template<typename _Tp, typename _Up> 1797 auto 1798 operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept 1799 -> decltype(__lhs.owner_before(__rhs)) 1800 { return __lhs.owner_before(__rhs); } 1801 1802 using is_transparent = void; 1803 }; 1804 1805 template<typename _Tp, _Lock_policy _Lp> 1806 struct owner_less<__shared_ptr<_Tp, _Lp>> 1807 : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>> 1808 { }; 1809 1810 template<typename _Tp, _Lock_policy _Lp> 1811 struct owner_less<__weak_ptr<_Tp, _Lp>> 1812 : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>> 1813 { }; 1814 1815 1816 template<typename _Tp, _Lock_policy _Lp> 1817 class __enable_shared_from_this 1818 { 1819 protected: 1820 constexpr __enable_shared_from_this() noexcept { } 1821 1822 __enable_shared_from_this(const __enable_shared_from_this&) noexcept { } 1823 1824 __enable_shared_from_this& 1825 operator=(const __enable_shared_from_this&) noexcept 1826 { return *this; } 1827 1828 ~__enable_shared_from_this() { } 1829 1830 public: 1831 __shared_ptr<_Tp, _Lp> 1832 shared_from_this() 1833 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 1834 1835 __shared_ptr<const _Tp, _Lp> 1836 shared_from_this() const 1837 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } 1838 1839 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 1840 __weak_ptr<_Tp, _Lp> 1841 weak_from_this() noexcept 1842 { return this->_M_weak_this; } 1843 1844 __weak_ptr<const _Tp, _Lp> 1845 weak_from_this() const noexcept 1846 { return this->_M_weak_this; } 1847 #endif 1848 1849 private: 1850 template<typename _Tp1> 1851 void 1852 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept 1853 { _M_weak_this._M_assign(__p, __n); } 1854 1855 friend const __enable_shared_from_this* 1856 __enable_shared_from_this_base(const __shared_count<_Lp>&, 1857 const __enable_shared_from_this* __p) 1858 { return __p; } 1859 1860 template<typename, _Lock_policy> 1861 friend class __shared_ptr; 1862 1863 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 1864 }; 1865 1866 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy, 1867 typename _Alloc, typename... _Args> 1868 inline __shared_ptr<_Tp, _Lp> 1869 __allocate_shared(const _Alloc& __a, _Args&&... __args) 1870 { 1871 static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported"); 1872 1873 return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a}, 1874 std::forward<_Args>(__args)...); 1875 } 1876 1877 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy, 1878 typename... _Args> 1879 inline __shared_ptr<_Tp, _Lp> 1880 __make_shared(_Args&&... __args) 1881 { 1882 typedef typename std::remove_const<_Tp>::type _Tp_nc; 1883 return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(), 1884 std::forward<_Args>(__args)...); 1885 } 1886 1887 /// std::hash specialization for __shared_ptr. 1888 template<typename _Tp, _Lock_policy _Lp> 1889 struct hash<__shared_ptr<_Tp, _Lp>> 1890 : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>> 1891 { 1892 size_t 1893 operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept 1894 { 1895 return hash<typename __shared_ptr<_Tp, _Lp>::element_type*>()( 1896 __s.get()); 1897 } 1898 }; 1899 1900 _GLIBCXX_END_NAMESPACE_VERSION 1901 } // namespace 1902 1903 #endif // _SHARED_PTR_BASE_H 1904