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