1 // shared_ptr and weak_ptr implementation details -*- C++ -*- 2 3 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 4 // Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 3, or (at your option) 10 // any later version. 11 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 // GCC Note: Based on files from version 1.32.0 of the Boost library. 27 28 // shared_count.hpp 29 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 30 31 // shared_ptr.hpp 32 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. 33 // Copyright (C) 2001, 2002, 2003 Peter Dimov 34 35 // weak_ptr.hpp 36 // Copyright (C) 2001, 2002, 2003 Peter Dimov 37 38 // enable_shared_from_this.hpp 39 // Copyright (C) 2002 Peter Dimov 40 41 // Distributed under the Boost Software License, Version 1.0. (See 42 // accompanying file LICENSE_1_0.txt or copy at 43 // http://www.boost.org/LICENSE_1_0.txt) 44 45 /** @file bits/shared_ptr_base.h 46 * This is an internal header file, included by other library headers. 47 * Do not attempt to use it directly. @headername{memory} 48 */ 49 50 #ifndef _SHARED_PTR_BASE_H 51 #define _SHARED_PTR_BASE_H 1 52 53 namespace std _GLIBCXX_VISIBILITY(default) 54 { 55 _GLIBCXX_BEGIN_NAMESPACE_VERSION 56 57 /** 58 * @brief Exception possibly thrown by @c shared_ptr. 59 * @ingroup exceptions 60 */ 61 class bad_weak_ptr : public std::exception 62 { 63 public: 64 virtual char const* 65 what() const noexcept; 66 67 virtual ~bad_weak_ptr() noexcept; 68 }; 69 70 // Substitute for bad_weak_ptr object in the case of -fno-exceptions. 71 inline void 72 __throw_bad_weak_ptr() 73 { 74 #if __EXCEPTIONS 75 throw bad_weak_ptr(); 76 #else 77 __builtin_abort(); 78 #endif 79 } 80 81 using __gnu_cxx::_Lock_policy; 82 using __gnu_cxx::__default_lock_policy; 83 using __gnu_cxx::_S_single; 84 using __gnu_cxx::_S_mutex; 85 using __gnu_cxx::_S_atomic; 86 87 // Empty helper class except when the template argument is _S_mutex. 88 template<_Lock_policy _Lp> 89 class _Mutex_base 90 { 91 protected: 92 // The atomic policy uses fully-fenced builtins, single doesn't care. 93 enum { _S_need_barriers = 0 }; 94 }; 95 96 template<> 97 class _Mutex_base<_S_mutex> 98 : public __gnu_cxx::__mutex 99 { 100 protected: 101 // This policy is used when atomic builtins are not available. 102 // The replacement atomic operations might not have the necessary 103 // memory barriers. 104 enum { _S_need_barriers = 1 }; 105 }; 106 107 template<_Lock_policy _Lp = __default_lock_policy> 108 class _Sp_counted_base 109 : public _Mutex_base<_Lp> 110 { 111 public: 112 _Sp_counted_base() noexcept 113 : _M_use_count(1), _M_weak_count(1) { } 114 115 virtual 116 ~_Sp_counted_base() noexcept 117 { } 118 119 // Called when _M_use_count drops to zero, to release the resources 120 // managed by *this. 121 virtual void 122 _M_dispose() noexcept = 0; 123 124 // Called when _M_weak_count drops to zero. 125 virtual void 126 _M_destroy() noexcept 127 { delete this; } 128 129 virtual void* 130 _M_get_deleter(const std::type_info&) = 0; 131 132 void 133 _M_add_ref_copy() 134 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } 135 136 void 137 _M_add_ref_lock(); 138 139 void 140 _M_release() noexcept 141 { 142 // Be race-detector-friendly. For more info see bits/c++config. 143 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); 144 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) 145 { 146 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); 147 _M_dispose(); 148 // There must be a memory barrier between dispose() and destroy() 149 // to ensure that the effects of dispose() are observed in the 150 // thread that runs destroy(). 151 // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html 152 if (_Mutex_base<_Lp>::_S_need_barriers) 153 { 154 _GLIBCXX_READ_MEM_BARRIER; 155 _GLIBCXX_WRITE_MEM_BARRIER; 156 } 157 158 // Be race-detector-friendly. For more info see bits/c++config. 159 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 160 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, 161 -1) == 1) 162 { 163 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 164 _M_destroy(); 165 } 166 } 167 } 168 169 void 170 _M_weak_add_ref() noexcept 171 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } 172 173 void 174 _M_weak_release() noexcept 175 { 176 // Be race-detector-friendly. For more info see bits/c++config. 177 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 178 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) 179 { 180 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 181 if (_Mutex_base<_Lp>::_S_need_barriers) 182 { 183 // See _M_release(), 184 // destroy() must observe results of dispose() 185 _GLIBCXX_READ_MEM_BARRIER; 186 _GLIBCXX_WRITE_MEM_BARRIER; 187 } 188 _M_destroy(); 189 } 190 } 191 192 long 193 _M_get_use_count() const noexcept 194 { 195 // No memory barrier is used here so there is no synchronization 196 // with other threads. 197 return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED); 198 } 199 200 private: 201 _Sp_counted_base(_Sp_counted_base const&) = delete; 202 _Sp_counted_base& operator=(_Sp_counted_base const&) = delete; 203 204 _Atomic_word _M_use_count; // #shared 205 _Atomic_word _M_weak_count; // #weak + (#shared != 0) 206 }; 207 208 template<> 209 inline void 210 _Sp_counted_base<_S_single>:: 211 _M_add_ref_lock() 212 { 213 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 214 { 215 _M_use_count = 0; 216 __throw_bad_weak_ptr(); 217 } 218 } 219 220 template<> 221 inline void 222 _Sp_counted_base<_S_mutex>:: 223 _M_add_ref_lock() 224 { 225 __gnu_cxx::__scoped_lock sentry(*this); 226 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 227 { 228 _M_use_count = 0; 229 __throw_bad_weak_ptr(); 230 } 231 } 232 233 template<> 234 inline void 235 _Sp_counted_base<_S_atomic>:: 236 _M_add_ref_lock() 237 { 238 // Perform lock-free add-if-not-zero operation. 239 _Atomic_word __count = _M_use_count; 240 do 241 { 242 if (__count == 0) 243 __throw_bad_weak_ptr(); 244 // Replace the current counter value with the old value + 1, as 245 // long as it's not changed meanwhile. 246 } 247 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, 248 true, __ATOMIC_ACQ_REL, 249 __ATOMIC_RELAXED)); 250 } 251 252 253 // Forward declarations. 254 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 255 class __shared_ptr; 256 257 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 258 class __weak_ptr; 259 260 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 261 class __enable_shared_from_this; 262 263 template<typename _Tp> 264 class shared_ptr; 265 266 template<typename _Tp> 267 class weak_ptr; 268 269 template<typename _Tp> 270 struct owner_less; 271 272 template<typename _Tp> 273 class enable_shared_from_this; 274 275 template<_Lock_policy _Lp = __default_lock_policy> 276 class __weak_count; 277 278 template<_Lock_policy _Lp = __default_lock_policy> 279 class __shared_count; 280 281 282 // Counted ptr with no deleter or allocator support 283 template<typename _Ptr, _Lock_policy _Lp> 284 class _Sp_counted_ptr final : public _Sp_counted_base<_Lp> 285 { 286 public: 287 explicit 288 _Sp_counted_ptr(_Ptr __p) 289 : _M_ptr(__p) { } 290 291 virtual void 292 _M_dispose() noexcept 293 { delete _M_ptr; } 294 295 virtual void 296 _M_destroy() noexcept 297 { delete this; } 298 299 virtual void* 300 _M_get_deleter(const std::type_info&) 301 { return 0; } 302 303 _Sp_counted_ptr(const _Sp_counted_ptr&) = delete; 304 _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete; 305 306 protected: 307 _Ptr _M_ptr; // copy constructor must not throw 308 }; 309 310 template<> 311 inline void 312 _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { } 313 314 template<> 315 inline void 316 _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { } 317 318 template<> 319 inline void 320 _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { } 321 322 // Support for custom deleter and/or allocator 323 template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp> 324 class _Sp_counted_deleter final : public _Sp_counted_base<_Lp> 325 { 326 // Helper class that stores the Deleter and also acts as an allocator. 327 // Used to dispose of the owned pointer and the internal refcount 328 // Requires that copies of _Alloc can free each other's memory. 329 struct _My_Deleter 330 : public _Alloc // copy constructor must not throw 331 { 332 _Deleter _M_del; // copy constructor must not throw 333 _My_Deleter(_Deleter __d, const _Alloc& __a) 334 : _Alloc(__a), _M_del(__d) { } 335 }; 336 337 public: 338 // __d(__p) must not throw. 339 _Sp_counted_deleter(_Ptr __p, _Deleter __d) 340 : _M_ptr(__p), _M_del(__d, _Alloc()) { } 341 342 // __d(__p) must not throw. 343 _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) 344 : _M_ptr(__p), _M_del(__d, __a) { } 345 346 ~_Sp_counted_deleter() noexcept { } 347 348 virtual void 349 _M_dispose() noexcept 350 { _M_del._M_del(_M_ptr); } 351 352 virtual void 353 _M_destroy() noexcept 354 { 355 typedef typename allocator_traits<_Alloc>::template 356 rebind_traits<_Sp_counted_deleter> _Alloc_traits; 357 typename _Alloc_traits::allocator_type __a(_M_del); 358 _Alloc_traits::destroy(__a, this); 359 _Alloc_traits::deallocate(__a, this, 1); 360 } 361 362 virtual void* 363 _M_get_deleter(const std::type_info& __ti) 364 { 365 #ifdef __GXX_RTTI 366 return __ti == typeid(_Deleter) ? &_M_del._M_del : 0; 367 #else 368 return 0; 369 #endif 370 } 371 372 protected: 373 _Ptr _M_ptr; // copy constructor must not throw 374 _My_Deleter _M_del; // copy constructor must not throw 375 }; 376 377 // helpers for make_shared / allocate_shared 378 379 struct _Sp_make_shared_tag { }; 380 381 template<typename _Tp, typename _Alloc, _Lock_policy _Lp> 382 class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> 383 { 384 // Helper class that stores the pointer and also acts as an allocator. 385 // Used to dispose of the owned pointer and the internal refcount 386 // Requires that copies of _Alloc can free each other's memory. 387 struct _Impl 388 : public _Alloc // copy constructor must not throw 389 { 390 _Impl(_Alloc __a) : _Alloc(__a), _M_ptr() { } 391 _Tp* _M_ptr; 392 }; 393 394 public: 395 template<typename... _Args> 396 _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args) 397 : _M_impl(__a), _M_storage() 398 { 399 _M_impl._M_ptr = static_cast<_Tp*>(static_cast<void*>(&_M_storage)); 400 // _GLIBCXX_RESOLVE_LIB_DEFECTS 401 // 2070. allocate_shared should use allocator_traits<A>::construct 402 allocator_traits<_Alloc>::construct(__a, _M_impl._M_ptr, 403 std::forward<_Args>(__args)...); // might throw 404 } 405 406 ~_Sp_counted_ptr_inplace() noexcept { } 407 408 virtual void 409 _M_dispose() noexcept 410 { allocator_traits<_Alloc>::destroy(_M_impl, _M_impl._M_ptr); } 411 412 // Override because the allocator needs to know the dynamic type 413 virtual void 414 _M_destroy() noexcept 415 { 416 typedef typename allocator_traits<_Alloc>::template 417 rebind_traits<_Sp_counted_ptr_inplace> _Alloc_traits; 418 typename _Alloc_traits::allocator_type __a(_M_impl); 419 _Alloc_traits::destroy(__a, this); 420 _Alloc_traits::deallocate(__a, this, 1); 421 } 422 423 // Sneaky trick so __shared_ptr can get the managed pointer 424 virtual void* 425 _M_get_deleter(const std::type_info& __ti) noexcept 426 { 427 #ifdef __GXX_RTTI 428 return __ti == typeid(_Sp_make_shared_tag) 429 ? static_cast<void*>(&_M_storage) 430 : 0; 431 #else 432 return 0; 433 #endif 434 } 435 436 private: 437 _Impl _M_impl; 438 typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type 439 _M_storage; 440 }; 441 442 template<_Lock_policy _Lp> 443 class __shared_count 444 { 445 public: 446 constexpr __shared_count() noexcept : _M_pi(0) 447 { } 448 449 template<typename _Ptr> 450 explicit 451 __shared_count(_Ptr __p) : _M_pi(0) 452 { 453 __try 454 { 455 _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); 456 } 457 __catch(...) 458 { 459 delete __p; 460 __throw_exception_again; 461 } 462 } 463 464 template<typename _Ptr, typename _Deleter> 465 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) 466 { 467 // The allocator's value_type doesn't matter, will rebind it anyway. 468 typedef std::allocator<int> _Alloc; 469 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; 470 typedef typename allocator_traits<_Alloc>::template 471 rebind_traits<_Sp_cd_type> _Alloc_traits; 472 typename _Alloc_traits::allocator_type __a; 473 _Sp_cd_type* __mem = 0; 474 __try 475 { 476 __mem = _Alloc_traits::allocate(__a, 1); 477 _Alloc_traits::construct(__a, __mem, __p, std::move(__d)); 478 _M_pi = __mem; 479 } 480 __catch(...) 481 { 482 __d(__p); // Call _Deleter on __p. 483 if (__mem) 484 _Alloc_traits::deallocate(__a, __mem, 1); 485 __throw_exception_again; 486 } 487 } 488 489 template<typename _Ptr, typename _Deleter, typename _Alloc> 490 __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) 491 { 492 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; 493 typedef typename allocator_traits<_Alloc>::template 494 rebind_traits<_Sp_cd_type> _Alloc_traits; 495 typename _Alloc_traits::allocator_type __a2(__a); 496 _Sp_cd_type* __mem = 0; 497 __try 498 { 499 __mem = _Alloc_traits::allocate(__a2, 1); 500 _Alloc_traits::construct(__a2, __mem, 501 __p, std::move(__d), std::move(__a)); 502 _M_pi = __mem; 503 } 504 __catch(...) 505 { 506 __d(__p); // Call _Deleter on __p. 507 if (__mem) 508 _Alloc_traits::deallocate(__a2, __mem, 1); 509 __throw_exception_again; 510 } 511 } 512 513 template<typename _Tp, typename _Alloc, typename... _Args> 514 __shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a, 515 _Args&&... __args) 516 : _M_pi(0) 517 { 518 typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type; 519 typedef typename allocator_traits<_Alloc>::template 520 rebind_traits<_Sp_cp_type> _Alloc_traits; 521 typename _Alloc_traits::allocator_type __a2(__a); 522 _Sp_cp_type* __mem = _Alloc_traits::allocate(__a2, 1); 523 __try 524 { 525 _Alloc_traits::construct(__a2, __mem, std::move(__a), 526 std::forward<_Args>(__args)...); 527 _M_pi = __mem; 528 } 529 __catch(...) 530 { 531 _Alloc_traits::deallocate(__a2, __mem, 1); 532 __throw_exception_again; 533 } 534 } 535 536 #if _GLIBCXX_USE_DEPRECATED 537 // Special case for auto_ptr<_Tp> to provide the strong guarantee. 538 template<typename _Tp> 539 explicit 540 __shared_count(std::auto_ptr<_Tp>&& __r) 541 : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get())) 542 { __r.release(); } 543 #endif 544 545 // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee. 546 template<typename _Tp, typename _Del> 547 explicit 548 __shared_count(std::unique_ptr<_Tp, _Del>&& __r) 549 : _M_pi(_S_create_from_up(std::move(__r))) 550 { __r.release(); } 551 552 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 553 explicit __shared_count(const __weak_count<_Lp>& __r); 554 555 ~__shared_count() noexcept 556 { 557 if (_M_pi != 0) 558 _M_pi->_M_release(); 559 } 560 561 __shared_count(const __shared_count& __r) noexcept 562 : _M_pi(__r._M_pi) 563 { 564 if (_M_pi != 0) 565 _M_pi->_M_add_ref_copy(); 566 } 567 568 __shared_count& 569 operator=(const __shared_count& __r) noexcept 570 { 571 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 572 if (__tmp != _M_pi) 573 { 574 if (__tmp != 0) 575 __tmp->_M_add_ref_copy(); 576 if (_M_pi != 0) 577 _M_pi->_M_release(); 578 _M_pi = __tmp; 579 } 580 return *this; 581 } 582 583 void 584 _M_swap(__shared_count& __r) noexcept 585 { 586 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 587 __r._M_pi = _M_pi; 588 _M_pi = __tmp; 589 } 590 591 long 592 _M_get_use_count() const noexcept 593 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 594 595 bool 596 _M_unique() const noexcept 597 { return this->_M_get_use_count() == 1; } 598 599 void* 600 _M_get_deleter(const std::type_info& __ti) const noexcept 601 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; } 602 603 bool 604 _M_less(const __shared_count& __rhs) const noexcept 605 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 606 607 bool 608 _M_less(const __weak_count<_Lp>& __rhs) const noexcept 609 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 610 611 // Friend function injected into enclosing namespace and found by ADL 612 friend inline bool 613 operator==(const __shared_count& __a, const __shared_count& __b) noexcept 614 { return __a._M_pi == __b._M_pi; } 615 616 private: 617 friend class __weak_count<_Lp>; 618 619 template<typename _Tp, typename _Del> 620 static _Sp_counted_base<_Lp>* 621 _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r, 622 typename std::enable_if<!std::is_reference<_Del>::value>::type* = 0) 623 { 624 return new _Sp_counted_deleter<_Tp*, _Del, std::allocator<_Tp>, 625 _Lp>(__r.get(), __r.get_deleter()); 626 } 627 628 template<typename _Tp, typename _Del> 629 static _Sp_counted_base<_Lp>* 630 _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r, 631 typename std::enable_if<std::is_reference<_Del>::value>::type* = 0) 632 { 633 typedef typename std::remove_reference<_Del>::type _Del1; 634 typedef std::reference_wrapper<_Del1> _Del2; 635 return new _Sp_counted_deleter<_Tp*, _Del2, std::allocator<_Tp>, 636 _Lp>(__r.get(), std::ref(__r.get_deleter())); 637 } 638 639 _Sp_counted_base<_Lp>* _M_pi; 640 }; 641 642 643 template<_Lock_policy _Lp> 644 class __weak_count 645 { 646 public: 647 constexpr __weak_count() noexcept : _M_pi(0) 648 { } 649 650 __weak_count(const __shared_count<_Lp>& __r) noexcept 651 : _M_pi(__r._M_pi) 652 { 653 if (_M_pi != 0) 654 _M_pi->_M_weak_add_ref(); 655 } 656 657 __weak_count(const __weak_count<_Lp>& __r) noexcept 658 : _M_pi(__r._M_pi) 659 { 660 if (_M_pi != 0) 661 _M_pi->_M_weak_add_ref(); 662 } 663 664 ~__weak_count() noexcept 665 { 666 if (_M_pi != 0) 667 _M_pi->_M_weak_release(); 668 } 669 670 __weak_count<_Lp>& 671 operator=(const __shared_count<_Lp>& __r) noexcept 672 { 673 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 674 if (__tmp != 0) 675 __tmp->_M_weak_add_ref(); 676 if (_M_pi != 0) 677 _M_pi->_M_weak_release(); 678 _M_pi = __tmp; 679 return *this; 680 } 681 682 __weak_count<_Lp>& 683 operator=(const __weak_count<_Lp>& __r) noexcept 684 { 685 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 686 if (__tmp != 0) 687 __tmp->_M_weak_add_ref(); 688 if (_M_pi != 0) 689 _M_pi->_M_weak_release(); 690 _M_pi = __tmp; 691 return *this; 692 } 693 694 void 695 _M_swap(__weak_count<_Lp>& __r) noexcept 696 { 697 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 698 __r._M_pi = _M_pi; 699 _M_pi = __tmp; 700 } 701 702 long 703 _M_get_use_count() const noexcept 704 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 705 706 bool 707 _M_less(const __weak_count& __rhs) const noexcept 708 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 709 710 bool 711 _M_less(const __shared_count<_Lp>& __rhs) const noexcept 712 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 713 714 // Friend function injected into enclosing namespace and found by ADL 715 friend inline bool 716 operator==(const __weak_count& __a, const __weak_count& __b) noexcept 717 { return __a._M_pi == __b._M_pi; } 718 719 private: 720 friend class __shared_count<_Lp>; 721 722 _Sp_counted_base<_Lp>* _M_pi; 723 }; 724 725 // Now that __weak_count is defined we can define this constructor: 726 template<_Lock_policy _Lp> 727 inline __shared_count<_Lp>:: __shared_count(const __weak_count<_Lp>& __r) 728 : _M_pi(__r._M_pi) 729 { 730 if (_M_pi != 0) 731 _M_pi->_M_add_ref_lock(); 732 else 733 __throw_bad_weak_ptr(); 734 } 735 736 737 // Support for enable_shared_from_this. 738 739 // Friend of __enable_shared_from_this. 740 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> 741 void 742 __enable_shared_from_this_helper(const __shared_count<_Lp>&, 743 const __enable_shared_from_this<_Tp1, 744 _Lp>*, const _Tp2*) noexcept; 745 746 // Friend of enable_shared_from_this. 747 template<typename _Tp1, typename _Tp2> 748 void 749 __enable_shared_from_this_helper(const __shared_count<>&, 750 const enable_shared_from_this<_Tp1>*, 751 const _Tp2*) noexcept; 752 753 template<_Lock_policy _Lp> 754 inline void 755 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) noexcept 756 { } 757 758 759 template<typename _Tp, _Lock_policy _Lp> 760 class __shared_ptr 761 { 762 public: 763 typedef _Tp element_type; 764 765 constexpr __shared_ptr() noexcept 766 : _M_ptr(0), _M_refcount() 767 { } 768 769 template<typename _Tp1> 770 explicit __shared_ptr(_Tp1* __p) 771 : _M_ptr(__p), _M_refcount(__p) 772 { 773 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 774 static_assert( sizeof(_Tp1) > 0, "incomplete type" ); 775 __enable_shared_from_this_helper(_M_refcount, __p, __p); 776 } 777 778 template<typename _Tp1, typename _Deleter> 779 __shared_ptr(_Tp1* __p, _Deleter __d) 780 : _M_ptr(__p), _M_refcount(__p, __d) 781 { 782 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 783 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 784 __enable_shared_from_this_helper(_M_refcount, __p, __p); 785 } 786 787 template<typename _Tp1, typename _Deleter, typename _Alloc> 788 __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) 789 : _M_ptr(__p), _M_refcount(__p, __d, std::move(__a)) 790 { 791 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 792 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 793 __enable_shared_from_this_helper(_M_refcount, __p, __p); 794 } 795 796 template<typename _Deleter> 797 __shared_ptr(nullptr_t __p, _Deleter __d) 798 : _M_ptr(0), _M_refcount(__p, __d) 799 { } 800 801 template<typename _Deleter, typename _Alloc> 802 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 803 : _M_ptr(0), _M_refcount(__p, __d, std::move(__a)) 804 { } 805 806 template<typename _Tp1> 807 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept 808 : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws 809 { } 810 811 __shared_ptr(const __shared_ptr&) noexcept = default; 812 __shared_ptr& operator=(const __shared_ptr&) noexcept = default; 813 ~__shared_ptr() = default; 814 815 template<typename _Tp1, typename = typename 816 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 817 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 818 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 819 { } 820 821 __shared_ptr(__shared_ptr&& __r) noexcept 822 : _M_ptr(__r._M_ptr), _M_refcount() 823 { 824 _M_refcount._M_swap(__r._M_refcount); 825 __r._M_ptr = 0; 826 } 827 828 template<typename _Tp1, typename = typename 829 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 830 __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept 831 : _M_ptr(__r._M_ptr), _M_refcount() 832 { 833 _M_refcount._M_swap(__r._M_refcount); 834 __r._M_ptr = 0; 835 } 836 837 template<typename _Tp1> 838 explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 839 : _M_refcount(__r._M_refcount) // may throw 840 { 841 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 842 843 // It is now safe to copy __r._M_ptr, as 844 // _M_refcount(__r._M_refcount) did not throw. 845 _M_ptr = __r._M_ptr; 846 } 847 848 // If an exception is thrown this constructor has no effect. 849 template<typename _Tp1, typename _Del> 850 __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r) 851 : _M_ptr(__r.get()), _M_refcount() 852 { 853 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 854 _Tp1* __tmp = __r.get(); 855 _M_refcount = __shared_count<_Lp>(std::move(__r)); 856 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); 857 } 858 859 #if _GLIBCXX_USE_DEPRECATED 860 // Postcondition: use_count() == 1 and __r.get() == 0 861 template<typename _Tp1> 862 __shared_ptr(std::auto_ptr<_Tp1>&& __r) 863 : _M_ptr(__r.get()), _M_refcount() 864 { 865 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 866 static_assert( sizeof(_Tp1) > 0, "incomplete type" ); 867 _Tp1* __tmp = __r.get(); 868 _M_refcount = __shared_count<_Lp>(std::move(__r)); 869 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); 870 } 871 #endif 872 873 /* TODO: use delegating constructor */ 874 constexpr __shared_ptr(nullptr_t) noexcept 875 : _M_ptr(0), _M_refcount() 876 { } 877 878 template<typename _Tp1> 879 __shared_ptr& 880 operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 881 { 882 _M_ptr = __r._M_ptr; 883 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 884 return *this; 885 } 886 887 #if _GLIBCXX_USE_DEPRECATED 888 template<typename _Tp1> 889 __shared_ptr& 890 operator=(std::auto_ptr<_Tp1>&& __r) 891 { 892 __shared_ptr(std::move(__r)).swap(*this); 893 return *this; 894 } 895 #endif 896 897 __shared_ptr& 898 operator=(__shared_ptr&& __r) noexcept 899 { 900 __shared_ptr(std::move(__r)).swap(*this); 901 return *this; 902 } 903 904 template<class _Tp1> 905 __shared_ptr& 906 operator=(__shared_ptr<_Tp1, _Lp>&& __r) noexcept 907 { 908 __shared_ptr(std::move(__r)).swap(*this); 909 return *this; 910 } 911 912 template<typename _Tp1, typename _Del> 913 __shared_ptr& 914 operator=(std::unique_ptr<_Tp1, _Del>&& __r) 915 { 916 __shared_ptr(std::move(__r)).swap(*this); 917 return *this; 918 } 919 920 void 921 reset() noexcept 922 { __shared_ptr().swap(*this); } 923 924 template<typename _Tp1> 925 void 926 reset(_Tp1* __p) // _Tp1 must be complete. 927 { 928 // Catch self-reset errors. 929 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 930 __shared_ptr(__p).swap(*this); 931 } 932 933 template<typename _Tp1, typename _Deleter> 934 void 935 reset(_Tp1* __p, _Deleter __d) 936 { __shared_ptr(__p, __d).swap(*this); } 937 938 template<typename _Tp1, typename _Deleter, typename _Alloc> 939 void 940 reset(_Tp1* __p, _Deleter __d, _Alloc __a) 941 { __shared_ptr(__p, __d, std::move(__a)).swap(*this); } 942 943 // Allow class instantiation when _Tp is [cv-qual] void. 944 typename std::add_lvalue_reference<_Tp>::type 945 operator*() const noexcept 946 { 947 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 948 return *_M_ptr; 949 } 950 951 _Tp* 952 operator->() const noexcept 953 { 954 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 955 return _M_ptr; 956 } 957 958 _Tp* 959 get() const noexcept 960 { return _M_ptr; } 961 962 explicit operator bool() const // never throws 963 { return _M_ptr == 0 ? false : true; } 964 965 bool 966 unique() const noexcept 967 { return _M_refcount._M_unique(); } 968 969 long 970 use_count() const noexcept 971 { return _M_refcount._M_get_use_count(); } 972 973 void 974 swap(__shared_ptr<_Tp, _Lp>& __other) noexcept 975 { 976 std::swap(_M_ptr, __other._M_ptr); 977 _M_refcount._M_swap(__other._M_refcount); 978 } 979 980 template<typename _Tp1> 981 bool 982 owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const 983 { return _M_refcount._M_less(__rhs._M_refcount); } 984 985 template<typename _Tp1> 986 bool 987 owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const 988 { return _M_refcount._M_less(__rhs._M_refcount); } 989 990 #ifdef __GXX_RTTI 991 protected: 992 // This constructor is non-standard, it is used by allocate_shared. 993 template<typename _Alloc, typename... _Args> 994 __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 995 _Args&&... __args) 996 : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a, 997 std::forward<_Args>(__args)...) 998 { 999 // _M_ptr needs to point to the newly constructed object. 1000 // This relies on _Sp_counted_ptr_inplace::_M_get_deleter. 1001 void* __p = _M_refcount._M_get_deleter(typeid(__tag)); 1002 _M_ptr = static_cast<_Tp*>(__p); 1003 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr); 1004 } 1005 #else 1006 template<typename _Alloc> 1007 struct _Deleter 1008 { 1009 void operator()(_Tp* __ptr) 1010 { 1011 typedef allocator_traits<_Alloc> _Alloc_traits; 1012 _Alloc_traits::destroy(_M_alloc, __ptr); 1013 _Alloc_traits::deallocate(_M_alloc, __ptr, 1); 1014 } 1015 _Alloc _M_alloc; 1016 }; 1017 1018 template<typename _Alloc, typename... _Args> 1019 __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 1020 _Args&&... __args) 1021 : _M_ptr(), _M_refcount() 1022 { 1023 typedef typename _Alloc::template rebind<_Tp>::other _Alloc2; 1024 _Deleter<_Alloc2> __del = { _Alloc2(__a) }; 1025 typedef allocator_traits<_Alloc2> __traits; 1026 _M_ptr = __traits::allocate(__del._M_alloc, 1); 1027 __try 1028 { 1029 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1030 // 2070. allocate_shared should use allocator_traits<A>::construct 1031 __traits::construct(__del._M_alloc, _M_ptr, 1032 std::forward<_Args>(__args)...); 1033 } 1034 __catch(...) 1035 { 1036 __traits::deallocate(__del._M_alloc, _M_ptr, 1); 1037 __throw_exception_again; 1038 } 1039 __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc); 1040 _M_refcount._M_swap(__count); 1041 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr); 1042 } 1043 #endif 1044 1045 template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc, 1046 typename... _Args> 1047 friend __shared_ptr<_Tp1, _Lp1> 1048 __allocate_shared(const _Alloc& __a, _Args&&... __args); 1049 1050 private: 1051 void* 1052 _M_get_deleter(const std::type_info& __ti) const noexcept 1053 { return _M_refcount._M_get_deleter(__ti); } 1054 1055 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 1056 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 1057 1058 template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 1059 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept; 1060 1061 _Tp* _M_ptr; // Contained pointer. 1062 __shared_count<_Lp> _M_refcount; // Reference counter. 1063 }; 1064 1065 1066 // 20.8.13.2.7 shared_ptr comparisons 1067 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 1068 inline bool 1069 operator==(const __shared_ptr<_Tp1, _Lp>& __a, 1070 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1071 { return __a.get() == __b.get(); } 1072 1073 template<typename _Tp, _Lock_policy _Lp> 1074 inline bool 1075 operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1076 { return !__a; } 1077 1078 template<typename _Tp, _Lock_policy _Lp> 1079 inline bool 1080 operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1081 { return !__a; } 1082 1083 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 1084 inline bool 1085 operator!=(const __shared_ptr<_Tp1, _Lp>& __a, 1086 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1087 { return __a.get() != __b.get(); } 1088 1089 template<typename _Tp, _Lock_policy _Lp> 1090 inline bool 1091 operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1092 { return (bool)__a; } 1093 1094 template<typename _Tp, _Lock_policy _Lp> 1095 inline bool 1096 operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1097 { return (bool)__a; } 1098 1099 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 1100 inline bool 1101 operator<(const __shared_ptr<_Tp1, _Lp>& __a, 1102 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1103 { 1104 typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT; 1105 return std::less<_CT>()(__a.get(), __b.get()); 1106 } 1107 1108 template<typename _Tp, _Lock_policy _Lp> 1109 inline bool 1110 operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1111 { return std::less<_Tp*>()(__a.get(), nullptr); } 1112 1113 template<typename _Tp, _Lock_policy _Lp> 1114 inline bool 1115 operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1116 { return std::less<_Tp*>()(nullptr, __a.get()); } 1117 1118 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 1119 inline bool 1120 operator<=(const __shared_ptr<_Tp1, _Lp>& __a, 1121 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1122 { return !(__b < __a); } 1123 1124 template<typename _Tp, _Lock_policy _Lp> 1125 inline bool 1126 operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1127 { return !(nullptr < __a); } 1128 1129 template<typename _Tp, _Lock_policy _Lp> 1130 inline bool 1131 operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1132 { return !(__a < nullptr); } 1133 1134 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 1135 inline bool 1136 operator>(const __shared_ptr<_Tp1, _Lp>& __a, 1137 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1138 { return (__b < __a); } 1139 1140 template<typename _Tp, _Lock_policy _Lp> 1141 inline bool 1142 operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1143 { return std::less<_Tp*>()(nullptr, __a.get()); } 1144 1145 template<typename _Tp, _Lock_policy _Lp> 1146 inline bool 1147 operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1148 { return std::less<_Tp*>()(__a.get(), nullptr); } 1149 1150 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 1151 inline bool 1152 operator>=(const __shared_ptr<_Tp1, _Lp>& __a, 1153 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 1154 { return !(__a < __b); } 1155 1156 template<typename _Tp, _Lock_policy _Lp> 1157 inline bool 1158 operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 1159 { return !(__a < nullptr); } 1160 1161 template<typename _Tp, _Lock_policy _Lp> 1162 inline bool 1163 operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 1164 { return !(nullptr < __a); } 1165 1166 template<typename _Sp> 1167 struct _Sp_less : public binary_function<_Sp, _Sp, bool> 1168 { 1169 bool 1170 operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept 1171 { 1172 typedef typename _Sp::element_type element_type; 1173 return std::less<element_type*>()(__lhs.get(), __rhs.get()); 1174 } 1175 }; 1176 1177 template<typename _Tp, _Lock_policy _Lp> 1178 struct less<__shared_ptr<_Tp, _Lp>> 1179 : public _Sp_less<__shared_ptr<_Tp, _Lp>> 1180 { }; 1181 1182 // 2.2.3.8 shared_ptr specialized algorithms. 1183 template<typename _Tp, _Lock_policy _Lp> 1184 inline void 1185 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept 1186 { __a.swap(__b); } 1187 1188 // 2.2.3.9 shared_ptr casts 1189 1190 // The seemingly equivalent code: 1191 // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) 1192 // will eventually result in undefined behaviour, attempting to 1193 // delete the same object twice. 1194 /// static_pointer_cast 1195 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 1196 inline __shared_ptr<_Tp, _Lp> 1197 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1198 { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); } 1199 1200 // The seemingly equivalent code: 1201 // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) 1202 // will eventually result in undefined behaviour, attempting to 1203 // delete the same object twice. 1204 /// const_pointer_cast 1205 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 1206 inline __shared_ptr<_Tp, _Lp> 1207 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1208 { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); } 1209 1210 // The seemingly equivalent code: 1211 // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) 1212 // will eventually result in undefined behaviour, attempting to 1213 // delete the same object twice. 1214 /// dynamic_pointer_cast 1215 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 1216 inline __shared_ptr<_Tp, _Lp> 1217 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1218 { 1219 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get())) 1220 return __shared_ptr<_Tp, _Lp>(__r, __p); 1221 return __shared_ptr<_Tp, _Lp>(); 1222 } 1223 1224 1225 template<typename _Tp, _Lock_policy _Lp> 1226 class __weak_ptr 1227 { 1228 public: 1229 typedef _Tp element_type; 1230 1231 constexpr __weak_ptr() noexcept 1232 : _M_ptr(0), _M_refcount() 1233 { } 1234 1235 __weak_ptr(const __weak_ptr&) noexcept = default; 1236 __weak_ptr& operator=(const __weak_ptr&) noexcept = default; 1237 ~__weak_ptr() = default; 1238 1239 // The "obvious" converting constructor implementation: 1240 // 1241 // template<typename _Tp1> 1242 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 1243 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 1244 // { } 1245 // 1246 // has a serious problem. 1247 // 1248 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 1249 // conversion may require access to *__r._M_ptr (virtual inheritance). 1250 // 1251 // It is not possible to avoid spurious access violations since 1252 // in multithreaded programs __r._M_ptr may be invalidated at any point. 1253 template<typename _Tp1, typename = typename 1254 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 1255 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) noexcept 1256 : _M_refcount(__r._M_refcount) 1257 { _M_ptr = __r.lock().get(); } 1258 1259 template<typename _Tp1, typename = typename 1260 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 1261 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1262 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 1263 { } 1264 1265 template<typename _Tp1> 1266 __weak_ptr& 1267 operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept 1268 { 1269 _M_ptr = __r.lock().get(); 1270 _M_refcount = __r._M_refcount; 1271 return *this; 1272 } 1273 1274 template<typename _Tp1> 1275 __weak_ptr& 1276 operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 1277 { 1278 _M_ptr = __r._M_ptr; 1279 _M_refcount = __r._M_refcount; 1280 return *this; 1281 } 1282 1283 __shared_ptr<_Tp, _Lp> 1284 lock() const noexcept 1285 { 1286 #ifdef __GTHREADS 1287 // Optimization: avoid throw overhead. 1288 if (expired()) 1289 return __shared_ptr<element_type, _Lp>(); 1290 1291 __try 1292 { 1293 return __shared_ptr<element_type, _Lp>(*this); 1294 } 1295 __catch(const bad_weak_ptr&) 1296 { 1297 // Q: How can we get here? 1298 // A: Another thread may have invalidated r after the 1299 // use_count test above. 1300 return __shared_ptr<element_type, _Lp>(); 1301 } 1302 1303 #else 1304 // Optimization: avoid try/catch overhead when single threaded. 1305 return expired() ? __shared_ptr<element_type, _Lp>() 1306 : __shared_ptr<element_type, _Lp>(*this); 1307 1308 #endif 1309 } // XXX MT 1310 1311 long 1312 use_count() const noexcept 1313 { return _M_refcount._M_get_use_count(); } 1314 1315 bool 1316 expired() const noexcept 1317 { return _M_refcount._M_get_use_count() == 0; } 1318 1319 template<typename _Tp1> 1320 bool 1321 owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const 1322 { return _M_refcount._M_less(__rhs._M_refcount); } 1323 1324 template<typename _Tp1> 1325 bool 1326 owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const 1327 { return _M_refcount._M_less(__rhs._M_refcount); } 1328 1329 void 1330 reset() noexcept 1331 { __weak_ptr().swap(*this); } 1332 1333 void 1334 swap(__weak_ptr& __s) noexcept 1335 { 1336 std::swap(_M_ptr, __s._M_ptr); 1337 _M_refcount._M_swap(__s._M_refcount); 1338 } 1339 1340 private: 1341 // Used by __enable_shared_from_this. 1342 void 1343 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept 1344 { 1345 _M_ptr = __ptr; 1346 _M_refcount = __refcount; 1347 } 1348 1349 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 1350 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 1351 friend class __enable_shared_from_this<_Tp, _Lp>; 1352 friend class enable_shared_from_this<_Tp>; 1353 1354 _Tp* _M_ptr; // Contained pointer. 1355 __weak_count<_Lp> _M_refcount; // Reference counter. 1356 }; 1357 1358 // 20.8.13.3.7 weak_ptr specialized algorithms. 1359 template<typename _Tp, _Lock_policy _Lp> 1360 inline void 1361 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept 1362 { __a.swap(__b); } 1363 1364 template<typename _Tp, typename _Tp1> 1365 struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool> 1366 { 1367 bool 1368 operator()(const _Tp& __lhs, const _Tp& __rhs) const 1369 { return __lhs.owner_before(__rhs); } 1370 1371 bool 1372 operator()(const _Tp& __lhs, const _Tp1& __rhs) const 1373 { return __lhs.owner_before(__rhs); } 1374 1375 bool 1376 operator()(const _Tp1& __lhs, const _Tp& __rhs) const 1377 { return __lhs.owner_before(__rhs); } 1378 }; 1379 1380 template<typename _Tp, _Lock_policy _Lp> 1381 struct owner_less<__shared_ptr<_Tp, _Lp>> 1382 : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>> 1383 { }; 1384 1385 template<typename _Tp, _Lock_policy _Lp> 1386 struct owner_less<__weak_ptr<_Tp, _Lp>> 1387 : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>> 1388 { }; 1389 1390 1391 template<typename _Tp, _Lock_policy _Lp> 1392 class __enable_shared_from_this 1393 { 1394 protected: 1395 constexpr __enable_shared_from_this() noexcept { } 1396 1397 __enable_shared_from_this(const __enable_shared_from_this&) noexcept { } 1398 1399 __enable_shared_from_this& 1400 operator=(const __enable_shared_from_this&) noexcept 1401 { return *this; } 1402 1403 ~__enable_shared_from_this() { } 1404 1405 public: 1406 __shared_ptr<_Tp, _Lp> 1407 shared_from_this() 1408 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 1409 1410 __shared_ptr<const _Tp, _Lp> 1411 shared_from_this() const 1412 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } 1413 1414 private: 1415 template<typename _Tp1> 1416 void 1417 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept 1418 { _M_weak_this._M_assign(__p, __n); } 1419 1420 template<typename _Tp1> 1421 friend void 1422 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, 1423 const __enable_shared_from_this* __pe, 1424 const _Tp1* __px) noexcept 1425 { 1426 if (__pe != 0) 1427 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 1428 } 1429 1430 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 1431 }; 1432 1433 1434 template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args> 1435 inline __shared_ptr<_Tp, _Lp> 1436 __allocate_shared(const _Alloc& __a, _Args&&... __args) 1437 { 1438 return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a, 1439 std::forward<_Args>(__args)...); 1440 } 1441 1442 template<typename _Tp, _Lock_policy _Lp, typename... _Args> 1443 inline __shared_ptr<_Tp, _Lp> 1444 __make_shared(_Args&&... __args) 1445 { 1446 typedef typename std::remove_const<_Tp>::type _Tp_nc; 1447 return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(), 1448 std::forward<_Args>(__args)...); 1449 } 1450 1451 /// std::hash specialization for __shared_ptr. 1452 template<typename _Tp, _Lock_policy _Lp> 1453 struct hash<__shared_ptr<_Tp, _Lp>> 1454 : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>> 1455 { 1456 size_t 1457 operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept 1458 { return std::hash<_Tp*>()(__s.get()); } 1459 }; 1460 1461 _GLIBCXX_END_NAMESPACE_VERSION 1462 } // namespace 1463 1464 #endif // _SHARED_PTR_BASE_H 1465