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