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