1 // <tr1/shared_ptr.h> -*- C++ -*- 2 3 // Copyright (C) 2007-2018 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 // shared_count.hpp 26 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 27 28 // shared_ptr.hpp 29 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. 30 // Copyright (C) 2001, 2002, 2003 Peter Dimov 31 32 // weak_ptr.hpp 33 // Copyright (C) 2001, 2002, 2003 Peter Dimov 34 35 // enable_shared_from_this.hpp 36 // Copyright (C) 2002 Peter Dimov 37 38 // Distributed under the Boost Software License, Version 1.0. (See 39 // accompanying file LICENSE_1_0.txt or copy at 40 // http://www.boost.org/LICENSE_1_0.txt) 41 42 // GCC Note: based on version 1.32.0 of the Boost library. 43 44 /** @file tr1/shared_ptr.h 45 * This is an internal header file, included by other library headers. 46 * Do not attempt to use it directly. @headername{tr1/memory} 47 */ 48 49 #ifndef _TR1_SHARED_PTR_H 50 #define _TR1_SHARED_PTR_H 1 51 52 namespace std _GLIBCXX_VISIBILITY(default) 53 { 54 _GLIBCXX_BEGIN_NAMESPACE_VERSION 55 56 namespace tr1 57 { 58 /** 59 * @brief Exception possibly thrown by @c shared_ptr. 60 * @ingroup exceptions 61 */ 62 class bad_weak_ptr : public std::exception 63 { 64 public: 65 virtual char const* 66 what() const throw() 67 { return "tr1::bad_weak_ptr"; } 68 }; 69 70 // Substitute for bad_weak_ptr object in the case of -fno-exceptions. 71 inline void 72 __throw_bad_weak_ptr() 73 { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); } 74 75 using __gnu_cxx::_Lock_policy; 76 using __gnu_cxx::__default_lock_policy; 77 using __gnu_cxx::_S_single; 78 using __gnu_cxx::_S_mutex; 79 using __gnu_cxx::_S_atomic; 80 81 // Empty helper class except when the template argument is _S_mutex. 82 template<_Lock_policy _Lp> 83 class _Mutex_base 84 { 85 protected: 86 // The atomic policy uses fully-fenced builtins, single doesn't care. 87 enum { _S_need_barriers = 0 }; 88 }; 89 90 template<> 91 class _Mutex_base<_S_mutex> 92 : public __gnu_cxx::__mutex 93 { 94 protected: 95 // This policy is used when atomic builtins are not available. 96 // The replacement atomic operations might not have the necessary 97 // memory barriers. 98 enum { _S_need_barriers = 1 }; 99 }; 100 101 template<_Lock_policy _Lp = __default_lock_policy> 102 class _Sp_counted_base 103 : public _Mutex_base<_Lp> 104 { 105 public: 106 _Sp_counted_base() 107 : _M_use_count(1), _M_weak_count(1) { } 108 109 virtual 110 ~_Sp_counted_base() // nothrow 111 { } 112 113 // Called when _M_use_count drops to zero, to release the resources 114 // managed by *this. 115 virtual void 116 _M_dispose() = 0; // nothrow 117 118 // Called when _M_weak_count drops to zero. 119 virtual void 120 _M_destroy() // nothrow 121 { delete this; } 122 123 virtual void* 124 _M_get_deleter(const std::type_info&) = 0; 125 126 void 127 _M_add_ref_copy() 128 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } 129 130 void 131 _M_add_ref_lock(); 132 133 void 134 _M_release() // nothrow 135 { 136 // Be race-detector-friendly. For more info see bits/c++config. 137 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); 138 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) 139 { 140 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); 141 _M_dispose(); 142 // There must be a memory barrier between dispose() and destroy() 143 // to ensure that the effects of dispose() are observed in the 144 // thread that runs destroy(). 145 // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html 146 if (_Mutex_base<_Lp>::_S_need_barriers) 147 { 148 __atomic_thread_fence (__ATOMIC_ACQ_REL); 149 } 150 151 // Be race-detector-friendly. For more info see bits/c++config. 152 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 153 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, 154 -1) == 1) 155 { 156 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 157 _M_destroy(); 158 } 159 } 160 } 161 162 void 163 _M_weak_add_ref() // nothrow 164 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } 165 166 void 167 _M_weak_release() // nothrow 168 { 169 // Be race-detector-friendly. For more info see bits/c++config. 170 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 171 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) 172 { 173 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 174 if (_Mutex_base<_Lp>::_S_need_barriers) 175 { 176 // See _M_release(), 177 // destroy() must observe results of dispose() 178 __atomic_thread_fence (__ATOMIC_ACQ_REL); 179 } 180 _M_destroy(); 181 } 182 } 183 184 long 185 _M_get_use_count() const // nothrow 186 { 187 // No memory barrier is used here so there is no synchronization 188 // with other threads. 189 return const_cast<const volatile _Atomic_word&>(_M_use_count); 190 } 191 192 private: 193 _Sp_counted_base(_Sp_counted_base const&); 194 _Sp_counted_base& operator=(_Sp_counted_base const&); 195 196 _Atomic_word _M_use_count; // #shared 197 _Atomic_word _M_weak_count; // #weak + (#shared != 0) 198 }; 199 200 template<> 201 inline void 202 _Sp_counted_base<_S_single>:: 203 _M_add_ref_lock() 204 { 205 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 206 { 207 _M_use_count = 0; 208 __throw_bad_weak_ptr(); 209 } 210 } 211 212 template<> 213 inline void 214 _Sp_counted_base<_S_mutex>:: 215 _M_add_ref_lock() 216 { 217 __gnu_cxx::__scoped_lock sentry(*this); 218 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 219 { 220 _M_use_count = 0; 221 __throw_bad_weak_ptr(); 222 } 223 } 224 225 template<> 226 inline void 227 _Sp_counted_base<_S_atomic>:: 228 _M_add_ref_lock() 229 { 230 // Perform lock-free add-if-not-zero operation. 231 _Atomic_word __count = _M_use_count; 232 do 233 { 234 if (__count == 0) 235 __throw_bad_weak_ptr(); 236 // Replace the current counter value with the old value + 1, as 237 // long as it's not changed meanwhile. 238 } 239 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, 240 true, __ATOMIC_ACQ_REL, 241 __ATOMIC_RELAXED)); 242 } 243 244 template<typename _Ptr, typename _Deleter, _Lock_policy _Lp> 245 class _Sp_counted_base_impl 246 : public _Sp_counted_base<_Lp> 247 { 248 public: 249 // Precondition: __d(__p) must not throw. 250 _Sp_counted_base_impl(_Ptr __p, _Deleter __d) 251 : _M_ptr(__p), _M_del(__d) { } 252 253 virtual void 254 _M_dispose() // nothrow 255 { _M_del(_M_ptr); } 256 257 virtual void* 258 _M_get_deleter(const std::type_info& __ti) 259 { 260 #if __cpp_rtti 261 return __ti == typeid(_Deleter) ? &_M_del : 0; 262 #else 263 return 0; 264 #endif 265 } 266 267 private: 268 _Sp_counted_base_impl(const _Sp_counted_base_impl&); 269 _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&); 270 271 _Ptr _M_ptr; // copy constructor must not throw 272 _Deleter _M_del; // copy constructor must not throw 273 }; 274 275 template<_Lock_policy _Lp = __default_lock_policy> 276 class __weak_count; 277 278 template<typename _Tp> 279 struct _Sp_deleter 280 { 281 typedef void result_type; 282 typedef _Tp* argument_type; 283 void operator()(_Tp* __p) const { delete __p; } 284 }; 285 286 template<_Lock_policy _Lp = __default_lock_policy> 287 class __shared_count 288 { 289 public: 290 __shared_count() 291 : _M_pi(0) // nothrow 292 { } 293 294 template<typename _Ptr> 295 __shared_count(_Ptr __p) : _M_pi(0) 296 { 297 __try 298 { 299 typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp; 300 _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>( 301 __p, _Sp_deleter<_Tp>()); 302 } 303 __catch(...) 304 { 305 delete __p; 306 __throw_exception_again; 307 } 308 } 309 310 template<typename _Ptr, typename _Deleter> 311 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) 312 { 313 __try 314 { 315 _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d); 316 } 317 __catch(...) 318 { 319 __d(__p); // Call _Deleter on __p. 320 __throw_exception_again; 321 } 322 } 323 324 // Special case for auto_ptr<_Tp> to provide the strong guarantee. 325 template<typename _Tp> 326 explicit 327 __shared_count(std::auto_ptr<_Tp>& __r) 328 : _M_pi(new _Sp_counted_base_impl<_Tp*, 329 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>())) 330 { __r.release(); } 331 332 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 333 explicit 334 __shared_count(const __weak_count<_Lp>& __r); 335 336 ~__shared_count() // nothrow 337 { 338 if (_M_pi != 0) 339 _M_pi->_M_release(); 340 } 341 342 __shared_count(const __shared_count& __r) 343 : _M_pi(__r._M_pi) // nothrow 344 { 345 if (_M_pi != 0) 346 _M_pi->_M_add_ref_copy(); 347 } 348 349 __shared_count& 350 operator=(const __shared_count& __r) // nothrow 351 { 352 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 353 if (__tmp != _M_pi) 354 { 355 if (__tmp != 0) 356 __tmp->_M_add_ref_copy(); 357 if (_M_pi != 0) 358 _M_pi->_M_release(); 359 _M_pi = __tmp; 360 } 361 return *this; 362 } 363 364 void 365 _M_swap(__shared_count& __r) // nothrow 366 { 367 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 368 __r._M_pi = _M_pi; 369 _M_pi = __tmp; 370 } 371 372 long 373 _M_get_use_count() const // nothrow 374 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 375 376 bool 377 _M_unique() const // nothrow 378 { return this->_M_get_use_count() == 1; } 379 380 friend inline bool 381 operator==(const __shared_count& __a, const __shared_count& __b) 382 { return __a._M_pi == __b._M_pi; } 383 384 friend inline bool 385 operator<(const __shared_count& __a, const __shared_count& __b) 386 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } 387 388 void* 389 _M_get_deleter(const std::type_info& __ti) const 390 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; } 391 392 private: 393 friend class __weak_count<_Lp>; 394 395 _Sp_counted_base<_Lp>* _M_pi; 396 }; 397 398 399 template<_Lock_policy _Lp> 400 class __weak_count 401 { 402 public: 403 __weak_count() 404 : _M_pi(0) // nothrow 405 { } 406 407 __weak_count(const __shared_count<_Lp>& __r) 408 : _M_pi(__r._M_pi) // nothrow 409 { 410 if (_M_pi != 0) 411 _M_pi->_M_weak_add_ref(); 412 } 413 414 __weak_count(const __weak_count<_Lp>& __r) 415 : _M_pi(__r._M_pi) // nothrow 416 { 417 if (_M_pi != 0) 418 _M_pi->_M_weak_add_ref(); 419 } 420 421 ~__weak_count() // nothrow 422 { 423 if (_M_pi != 0) 424 _M_pi->_M_weak_release(); 425 } 426 427 __weak_count<_Lp>& 428 operator=(const __shared_count<_Lp>& __r) // nothrow 429 { 430 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 431 if (__tmp != 0) 432 __tmp->_M_weak_add_ref(); 433 if (_M_pi != 0) 434 _M_pi->_M_weak_release(); 435 _M_pi = __tmp; 436 return *this; 437 } 438 439 __weak_count<_Lp>& 440 operator=(const __weak_count<_Lp>& __r) // nothrow 441 { 442 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 443 if (__tmp != 0) 444 __tmp->_M_weak_add_ref(); 445 if (_M_pi != 0) 446 _M_pi->_M_weak_release(); 447 _M_pi = __tmp; 448 return *this; 449 } 450 451 void 452 _M_swap(__weak_count<_Lp>& __r) // nothrow 453 { 454 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 455 __r._M_pi = _M_pi; 456 _M_pi = __tmp; 457 } 458 459 long 460 _M_get_use_count() const // nothrow 461 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 462 463 friend inline bool 464 operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) 465 { return __a._M_pi == __b._M_pi; } 466 467 friend inline bool 468 operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) 469 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } 470 471 private: 472 friend class __shared_count<_Lp>; 473 474 _Sp_counted_base<_Lp>* _M_pi; 475 }; 476 477 // now that __weak_count is defined we can define this constructor: 478 template<_Lock_policy _Lp> 479 inline 480 __shared_count<_Lp>:: 481 __shared_count(const __weak_count<_Lp>& __r) 482 : _M_pi(__r._M_pi) 483 { 484 if (_M_pi != 0) 485 _M_pi->_M_add_ref_lock(); 486 else 487 __throw_bad_weak_ptr(); 488 } 489 490 // Forward declarations. 491 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 492 class __shared_ptr; 493 494 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 495 class __weak_ptr; 496 497 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 498 class __enable_shared_from_this; 499 500 template<typename _Tp> 501 class shared_ptr; 502 503 template<typename _Tp> 504 class weak_ptr; 505 506 template<typename _Tp> 507 class enable_shared_from_this; 508 509 // Support for enable_shared_from_this. 510 511 // Friend of __enable_shared_from_this. 512 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> 513 void 514 __enable_shared_from_this_helper(const __shared_count<_Lp>&, 515 const __enable_shared_from_this<_Tp1, 516 _Lp>*, const _Tp2*); 517 518 // Friend of enable_shared_from_this. 519 template<typename _Tp1, typename _Tp2> 520 void 521 __enable_shared_from_this_helper(const __shared_count<>&, 522 const enable_shared_from_this<_Tp1>*, 523 const _Tp2*); 524 525 template<_Lock_policy _Lp> 526 inline void 527 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) 528 { } 529 530 531 struct __static_cast_tag { }; 532 struct __const_cast_tag { }; 533 struct __dynamic_cast_tag { }; 534 535 // A smart pointer with reference-counted copy semantics. The 536 // object pointed to is deleted when the last shared_ptr pointing to 537 // it is destroyed or reset. 538 template<typename _Tp, _Lock_policy _Lp> 539 class __shared_ptr 540 { 541 public: 542 typedef _Tp element_type; 543 544 __shared_ptr() 545 : _M_ptr(0), _M_refcount() // never throws 546 { } 547 548 template<typename _Tp1> 549 explicit 550 __shared_ptr(_Tp1* __p) 551 : _M_ptr(__p), _M_refcount(__p) 552 { 553 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 554 typedef int _IsComplete[sizeof(_Tp1)]; 555 __enable_shared_from_this_helper(_M_refcount, __p, __p); 556 } 557 558 template<typename _Tp1, typename _Deleter> 559 __shared_ptr(_Tp1* __p, _Deleter __d) 560 : _M_ptr(__p), _M_refcount(__p, __d) 561 { 562 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 563 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 564 __enable_shared_from_this_helper(_M_refcount, __p, __p); 565 } 566 567 // generated copy constructor, assignment, destructor are fine. 568 569 template<typename _Tp1> 570 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 571 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 572 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 573 574 template<typename _Tp1> 575 explicit 576 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 577 : _M_refcount(__r._M_refcount) // may throw 578 { 579 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 580 // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount) 581 // did not throw. 582 _M_ptr = __r._M_ptr; 583 } 584 585 #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED 586 // Postcondition: use_count() == 1 and __r.get() == 0 587 template<typename _Tp1> 588 explicit 589 __shared_ptr(std::auto_ptr<_Tp1>& __r) 590 : _M_ptr(__r.get()), _M_refcount() 591 { // TODO requries delete __r.release() well-formed 592 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 593 typedef int _IsComplete[sizeof(_Tp1)]; 594 _Tp1* __tmp = __r.get(); 595 _M_refcount = __shared_count<_Lp>(__r); 596 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); 597 } 598 599 #endif 600 601 template<typename _Tp1> 602 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag) 603 : _M_ptr(static_cast<element_type*>(__r._M_ptr)), 604 _M_refcount(__r._M_refcount) 605 { } 606 607 template<typename _Tp1> 608 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag) 609 : _M_ptr(const_cast<element_type*>(__r._M_ptr)), 610 _M_refcount(__r._M_refcount) 611 { } 612 613 template<typename _Tp1> 614 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag) 615 : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)), 616 _M_refcount(__r._M_refcount) 617 { 618 if (_M_ptr == 0) // need to allocate new counter -- the cast failed 619 _M_refcount = __shared_count<_Lp>(); 620 } 621 622 template<typename _Tp1> 623 __shared_ptr& 624 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 625 { 626 _M_ptr = __r._M_ptr; 627 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 628 return *this; 629 } 630 631 #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED 632 template<typename _Tp1> 633 __shared_ptr& 634 operator=(std::auto_ptr<_Tp1>& __r) 635 { 636 __shared_ptr(__r).swap(*this); 637 return *this; 638 } 639 #endif 640 641 void 642 reset() // never throws 643 { __shared_ptr().swap(*this); } 644 645 template<typename _Tp1> 646 void 647 reset(_Tp1* __p) // _Tp1 must be complete. 648 { 649 // Catch self-reset errors. 650 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 651 __shared_ptr(__p).swap(*this); 652 } 653 654 template<typename _Tp1, typename _Deleter> 655 void 656 reset(_Tp1* __p, _Deleter __d) 657 { __shared_ptr(__p, __d).swap(*this); } 658 659 // Allow class instantiation when _Tp is [cv-qual] void. 660 typename std::tr1::add_reference<_Tp>::type 661 operator*() const // never throws 662 { 663 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 664 return *_M_ptr; 665 } 666 667 _Tp* 668 operator->() const // never throws 669 { 670 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 671 return _M_ptr; 672 } 673 674 _Tp* 675 get() const // never throws 676 { return _M_ptr; } 677 678 // Implicit conversion to "bool" 679 private: 680 typedef _Tp* __shared_ptr::*__unspecified_bool_type; 681 682 public: 683 operator __unspecified_bool_type() const // never throws 684 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; } 685 686 bool 687 unique() const // never throws 688 { return _M_refcount._M_unique(); } 689 690 long 691 use_count() const // never throws 692 { return _M_refcount._M_get_use_count(); } 693 694 void 695 swap(__shared_ptr<_Tp, _Lp>& __other) // never throws 696 { 697 std::swap(_M_ptr, __other._M_ptr); 698 _M_refcount._M_swap(__other._M_refcount); 699 } 700 701 private: 702 void* 703 _M_get_deleter(const std::type_info& __ti) const 704 { return _M_refcount._M_get_deleter(__ti); } 705 706 template<typename _Tp1, _Lock_policy _Lp1> 707 bool 708 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const 709 { return _M_refcount < __rhs._M_refcount; } 710 711 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 712 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 713 714 template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 715 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&); 716 717 // Friends injected into enclosing namespace and found by ADL: 718 template<typename _Tp1> 719 friend inline bool 720 operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 721 { return __a.get() == __b.get(); } 722 723 template<typename _Tp1> 724 friend inline bool 725 operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 726 { return __a.get() != __b.get(); } 727 728 template<typename _Tp1> 729 friend inline bool 730 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 731 { return __a._M_less(__b); } 732 733 _Tp* _M_ptr; // Contained pointer. 734 __shared_count<_Lp> _M_refcount; // Reference counter. 735 }; 736 737 // 2.2.3.8 shared_ptr specialized algorithms. 738 template<typename _Tp, _Lock_policy _Lp> 739 inline void 740 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) 741 { __a.swap(__b); } 742 743 // 2.2.3.9 shared_ptr casts 744 /* The seemingly equivalent 745 * shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) 746 * will eventually result in undefined behaviour, 747 * attempting to delete the same object twice. 748 */ 749 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 750 inline __shared_ptr<_Tp, _Lp> 751 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 752 { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); } 753 754 /* The seemingly equivalent 755 * shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) 756 * will eventually result in undefined behaviour, 757 * attempting to delete the same object twice. 758 */ 759 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 760 inline __shared_ptr<_Tp, _Lp> 761 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 762 { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); } 763 764 /* The seemingly equivalent 765 * shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) 766 * will eventually result in undefined behaviour, 767 * attempting to delete the same object twice. 768 */ 769 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 770 inline __shared_ptr<_Tp, _Lp> 771 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 772 { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); } 773 774 // 2.2.3.7 shared_ptr I/O 775 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> 776 std::basic_ostream<_Ch, _Tr>& 777 operator<<(std::basic_ostream<_Ch, _Tr>& __os, 778 const __shared_ptr<_Tp, _Lp>& __p) 779 { 780 __os << __p.get(); 781 return __os; 782 } 783 784 // 2.2.3.10 shared_ptr get_deleter (experimental) 785 template<typename _Del, typename _Tp, _Lock_policy _Lp> 786 inline _Del* 787 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) 788 { 789 #if __cpp_rtti 790 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 791 #else 792 return 0; 793 #endif 794 } 795 796 797 template<typename _Tp, _Lock_policy _Lp> 798 class __weak_ptr 799 { 800 public: 801 typedef _Tp element_type; 802 803 __weak_ptr() 804 : _M_ptr(0), _M_refcount() // never throws 805 { } 806 807 // Generated copy constructor, assignment, destructor are fine. 808 809 // The "obvious" converting constructor implementation: 810 // 811 // template<typename _Tp1> 812 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 813 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 814 // { } 815 // 816 // has a serious problem. 817 // 818 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 819 // conversion may require access to *__r._M_ptr (virtual inheritance). 820 // 821 // It is not possible to avoid spurious access violations since 822 // in multithreaded programs __r._M_ptr may be invalidated at any point. 823 template<typename _Tp1> 824 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 825 : _M_refcount(__r._M_refcount) // never throws 826 { 827 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 828 _M_ptr = __r.lock().get(); 829 } 830 831 template<typename _Tp1> 832 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 833 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 834 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 835 836 template<typename _Tp1> 837 __weak_ptr& 838 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws 839 { 840 _M_ptr = __r.lock().get(); 841 _M_refcount = __r._M_refcount; 842 return *this; 843 } 844 845 template<typename _Tp1> 846 __weak_ptr& 847 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 848 { 849 _M_ptr = __r._M_ptr; 850 _M_refcount = __r._M_refcount; 851 return *this; 852 } 853 854 __shared_ptr<_Tp, _Lp> 855 lock() const // never throws 856 { 857 #ifdef __GTHREADS 858 // Optimization: avoid throw overhead. 859 if (expired()) 860 return __shared_ptr<element_type, _Lp>(); 861 862 __try 863 { 864 return __shared_ptr<element_type, _Lp>(*this); 865 } 866 __catch(const bad_weak_ptr&) 867 { 868 // Q: How can we get here? 869 // A: Another thread may have invalidated r after the 870 // use_count test above. 871 return __shared_ptr<element_type, _Lp>(); 872 } 873 874 #else 875 // Optimization: avoid try/catch overhead when single threaded. 876 return expired() ? __shared_ptr<element_type, _Lp>() 877 : __shared_ptr<element_type, _Lp>(*this); 878 879 #endif 880 } // XXX MT 881 882 long 883 use_count() const // never throws 884 { return _M_refcount._M_get_use_count(); } 885 886 bool 887 expired() const // never throws 888 { return _M_refcount._M_get_use_count() == 0; } 889 890 void 891 reset() // never throws 892 { __weak_ptr().swap(*this); } 893 894 void 895 swap(__weak_ptr& __s) // never throws 896 { 897 std::swap(_M_ptr, __s._M_ptr); 898 _M_refcount._M_swap(__s._M_refcount); 899 } 900 901 private: 902 // Used by __enable_shared_from_this. 903 void 904 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) 905 { 906 _M_ptr = __ptr; 907 _M_refcount = __refcount; 908 } 909 910 template<typename _Tp1> 911 bool 912 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const 913 { return _M_refcount < __rhs._M_refcount; } 914 915 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 916 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 917 friend class __enable_shared_from_this<_Tp, _Lp>; 918 friend class enable_shared_from_this<_Tp>; 919 920 // Friend injected into namespace and found by ADL. 921 template<typename _Tp1> 922 friend inline bool 923 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs) 924 { return __lhs._M_less(__rhs); } 925 926 _Tp* _M_ptr; // Contained pointer. 927 __weak_count<_Lp> _M_refcount; // Reference counter. 928 }; 929 930 // 2.2.4.7 weak_ptr specialized algorithms. 931 template<typename _Tp, _Lock_policy _Lp> 932 inline void 933 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) 934 { __a.swap(__b); } 935 936 937 template<typename _Tp, _Lock_policy _Lp> 938 class __enable_shared_from_this 939 { 940 protected: 941 __enable_shared_from_this() { } 942 943 __enable_shared_from_this(const __enable_shared_from_this&) { } 944 945 __enable_shared_from_this& 946 operator=(const __enable_shared_from_this&) 947 { return *this; } 948 949 ~__enable_shared_from_this() { } 950 951 public: 952 __shared_ptr<_Tp, _Lp> 953 shared_from_this() 954 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 955 956 __shared_ptr<const _Tp, _Lp> 957 shared_from_this() const 958 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } 959 960 private: 961 template<typename _Tp1> 962 void 963 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const 964 { _M_weak_this._M_assign(__p, __n); } 965 966 template<typename _Tp1> 967 friend void 968 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, 969 const __enable_shared_from_this* __pe, 970 const _Tp1* __px) 971 { 972 if (__pe != 0) 973 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 974 } 975 976 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 977 }; 978 979 980 // The actual shared_ptr, with forwarding constructors and 981 // assignment operators. 982 template<typename _Tp> 983 class shared_ptr 984 : public __shared_ptr<_Tp> 985 { 986 public: 987 shared_ptr() 988 : __shared_ptr<_Tp>() { } 989 990 template<typename _Tp1> 991 explicit 992 shared_ptr(_Tp1* __p) 993 : __shared_ptr<_Tp>(__p) { } 994 995 template<typename _Tp1, typename _Deleter> 996 shared_ptr(_Tp1* __p, _Deleter __d) 997 : __shared_ptr<_Tp>(__p, __d) { } 998 999 template<typename _Tp1> 1000 shared_ptr(const shared_ptr<_Tp1>& __r) 1001 : __shared_ptr<_Tp>(__r) { } 1002 1003 template<typename _Tp1> 1004 explicit 1005 shared_ptr(const weak_ptr<_Tp1>& __r) 1006 : __shared_ptr<_Tp>(__r) { } 1007 1008 #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED 1009 template<typename _Tp1> 1010 explicit 1011 shared_ptr(std::auto_ptr<_Tp1>& __r) 1012 : __shared_ptr<_Tp>(__r) { } 1013 #endif 1014 1015 template<typename _Tp1> 1016 shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag) 1017 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { } 1018 1019 template<typename _Tp1> 1020 shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag) 1021 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { } 1022 1023 template<typename _Tp1> 1024 shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag) 1025 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { } 1026 1027 template<typename _Tp1> 1028 shared_ptr& 1029 operator=(const shared_ptr<_Tp1>& __r) // never throws 1030 { 1031 this->__shared_ptr<_Tp>::operator=(__r); 1032 return *this; 1033 } 1034 1035 #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED 1036 template<typename _Tp1> 1037 shared_ptr& 1038 operator=(std::auto_ptr<_Tp1>& __r) 1039 { 1040 this->__shared_ptr<_Tp>::operator=(__r); 1041 return *this; 1042 } 1043 #endif 1044 }; 1045 1046 // 2.2.3.8 shared_ptr specialized algorithms. 1047 template<typename _Tp> 1048 inline void 1049 swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b) 1050 { __a.swap(__b); } 1051 1052 template<typename _Tp, typename _Tp1> 1053 inline shared_ptr<_Tp> 1054 static_pointer_cast(const shared_ptr<_Tp1>& __r) 1055 { return shared_ptr<_Tp>(__r, __static_cast_tag()); } 1056 1057 template<typename _Tp, typename _Tp1> 1058 inline shared_ptr<_Tp> 1059 const_pointer_cast(const shared_ptr<_Tp1>& __r) 1060 { return shared_ptr<_Tp>(__r, __const_cast_tag()); } 1061 1062 template<typename _Tp, typename _Tp1> 1063 inline shared_ptr<_Tp> 1064 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) 1065 { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); } 1066 1067 1068 // The actual weak_ptr, with forwarding constructors and 1069 // assignment operators. 1070 template<typename _Tp> 1071 class weak_ptr 1072 : public __weak_ptr<_Tp> 1073 { 1074 public: 1075 weak_ptr() 1076 : __weak_ptr<_Tp>() { } 1077 1078 template<typename _Tp1> 1079 weak_ptr(const weak_ptr<_Tp1>& __r) 1080 : __weak_ptr<_Tp>(__r) { } 1081 1082 template<typename _Tp1> 1083 weak_ptr(const shared_ptr<_Tp1>& __r) 1084 : __weak_ptr<_Tp>(__r) { } 1085 1086 template<typename _Tp1> 1087 weak_ptr& 1088 operator=(const weak_ptr<_Tp1>& __r) // never throws 1089 { 1090 this->__weak_ptr<_Tp>::operator=(__r); 1091 return *this; 1092 } 1093 1094 template<typename _Tp1> 1095 weak_ptr& 1096 operator=(const shared_ptr<_Tp1>& __r) // never throws 1097 { 1098 this->__weak_ptr<_Tp>::operator=(__r); 1099 return *this; 1100 } 1101 1102 shared_ptr<_Tp> 1103 lock() const // never throws 1104 { 1105 #ifdef __GTHREADS 1106 if (this->expired()) 1107 return shared_ptr<_Tp>(); 1108 1109 __try 1110 { 1111 return shared_ptr<_Tp>(*this); 1112 } 1113 __catch(const bad_weak_ptr&) 1114 { 1115 return shared_ptr<_Tp>(); 1116 } 1117 #else 1118 return this->expired() ? shared_ptr<_Tp>() 1119 : shared_ptr<_Tp>(*this); 1120 #endif 1121 } 1122 }; 1123 1124 template<typename _Tp> 1125 class enable_shared_from_this 1126 { 1127 protected: 1128 enable_shared_from_this() { } 1129 1130 enable_shared_from_this(const enable_shared_from_this&) { } 1131 1132 enable_shared_from_this& 1133 operator=(const enable_shared_from_this&) 1134 { return *this; } 1135 1136 ~enable_shared_from_this() { } 1137 1138 public: 1139 shared_ptr<_Tp> 1140 shared_from_this() 1141 { return shared_ptr<_Tp>(this->_M_weak_this); } 1142 1143 shared_ptr<const _Tp> 1144 shared_from_this() const 1145 { return shared_ptr<const _Tp>(this->_M_weak_this); } 1146 1147 private: 1148 template<typename _Tp1> 1149 void 1150 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const 1151 { _M_weak_this._M_assign(__p, __n); } 1152 1153 template<typename _Tp1> 1154 friend void 1155 __enable_shared_from_this_helper(const __shared_count<>& __pn, 1156 const enable_shared_from_this* __pe, 1157 const _Tp1* __px) 1158 { 1159 if (__pe != 0) 1160 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 1161 } 1162 1163 mutable weak_ptr<_Tp> _M_weak_this; 1164 }; 1165 } 1166 1167 _GLIBCXX_END_NAMESPACE_VERSION 1168 } 1169 1170 #endif // _TR1_SHARED_PTR_H 1171