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