1// <tr1/shared_ptr.h> -*- C++ -*- 2 3// Copyright (C) 2007, 2008, 2009 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 * You should not attempt to use it directly. 47 */ 48 49#ifndef _TR1_SHARED_PTR_H 50#define _TR1_SHARED_PTR_H 1 51 52#if defined(_GLIBCXX_INCLUDE_AS_CXX0X) 53# error TR1 header cannot be included from C++0x header 54#endif 55 56namespace std 57{ 58namespace tr1 59{ 60 61 template<typename _Ptr, typename _Deleter, _Lock_policy _Lp> 62 class _Sp_counted_base_impl 63 : public _Sp_counted_base<_Lp> 64 { 65 public: 66 /** 67 * @brief 68 * @pre __d(__p) must not throw. 69 */ 70 _Sp_counted_base_impl(_Ptr __p, _Deleter __d) 71 : _M_ptr(__p), _M_del(__d) { } 72 73 virtual void 74 _M_dispose() // nothrow 75 { _M_del(_M_ptr); } 76 77 virtual void* 78 _M_get_deleter(const std::type_info& __ti) 79 { return __ti == typeid(_Deleter) ? &_M_del : 0; } 80 81 private: 82 _Sp_counted_base_impl(const _Sp_counted_base_impl&); 83 _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&); 84 85 _Ptr _M_ptr; // copy constructor must not throw 86 _Deleter _M_del; // copy constructor must not throw 87 }; 88 89 template<_Lock_policy _Lp = __default_lock_policy> 90 class __weak_count; 91 92 template<typename _Tp> 93 struct _Sp_deleter 94 { 95 typedef void result_type; 96 typedef _Tp* argument_type; 97 void operator()(_Tp* __p) const { delete __p; } 98 }; 99 100 template<_Lock_policy _Lp = __default_lock_policy> 101 class __shared_count 102 { 103 public: 104 __shared_count() 105 : _M_pi(0) // nothrow 106 { } 107 108 template<typename _Ptr> 109 __shared_count(_Ptr __p) : _M_pi(0) 110 { 111 __try 112 { 113 typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp; 114 _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>( 115 __p, _Sp_deleter<_Tp>()); 116 } 117 __catch(...) 118 { 119 delete __p; 120 __throw_exception_again; 121 } 122 } 123 124 template<typename _Ptr, typename _Deleter> 125 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) 126 { 127 __try 128 { 129 _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d); 130 } 131 __catch(...) 132 { 133 __d(__p); // Call _Deleter on __p. 134 __throw_exception_again; 135 } 136 } 137 138 // Special case for auto_ptr<_Tp> to provide the strong guarantee. 139 template<typename _Tp> 140 explicit 141 __shared_count(std::auto_ptr<_Tp>& __r) 142 : _M_pi(new _Sp_counted_base_impl<_Tp*, 143 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>())) 144 { __r.release(); } 145 146 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 147 explicit 148 __shared_count(const __weak_count<_Lp>& __r); 149 150 ~__shared_count() // nothrow 151 { 152 if (_M_pi != 0) 153 _M_pi->_M_release(); 154 } 155 156 __shared_count(const __shared_count& __r) 157 : _M_pi(__r._M_pi) // nothrow 158 { 159 if (_M_pi != 0) 160 _M_pi->_M_add_ref_copy(); 161 } 162 163 __shared_count& 164 operator=(const __shared_count& __r) // nothrow 165 { 166 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 167 if (__tmp != _M_pi) 168 { 169 if (__tmp != 0) 170 __tmp->_M_add_ref_copy(); 171 if (_M_pi != 0) 172 _M_pi->_M_release(); 173 _M_pi = __tmp; 174 } 175 return *this; 176 } 177 178 void 179 _M_swap(__shared_count& __r) // nothrow 180 { 181 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 182 __r._M_pi = _M_pi; 183 _M_pi = __tmp; 184 } 185 186 long 187 _M_get_use_count() const // nothrow 188 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 189 190 bool 191 _M_unique() const // nothrow 192 { return this->_M_get_use_count() == 1; } 193 194 friend inline bool 195 operator==(const __shared_count& __a, const __shared_count& __b) 196 { return __a._M_pi == __b._M_pi; } 197 198 friend inline bool 199 operator<(const __shared_count& __a, const __shared_count& __b) 200 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } 201 202 void* 203 _M_get_deleter(const std::type_info& __ti) const 204 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; } 205 206 private: 207 friend class __weak_count<_Lp>; 208 209 _Sp_counted_base<_Lp>* _M_pi; 210 }; 211 212 213 template<_Lock_policy _Lp> 214 class __weak_count 215 { 216 public: 217 __weak_count() 218 : _M_pi(0) // nothrow 219 { } 220 221 __weak_count(const __shared_count<_Lp>& __r) 222 : _M_pi(__r._M_pi) // nothrow 223 { 224 if (_M_pi != 0) 225 _M_pi->_M_weak_add_ref(); 226 } 227 228 __weak_count(const __weak_count<_Lp>& __r) 229 : _M_pi(__r._M_pi) // nothrow 230 { 231 if (_M_pi != 0) 232 _M_pi->_M_weak_add_ref(); 233 } 234 235 ~__weak_count() // nothrow 236 { 237 if (_M_pi != 0) 238 _M_pi->_M_weak_release(); 239 } 240 241 __weak_count<_Lp>& 242 operator=(const __shared_count<_Lp>& __r) // nothrow 243 { 244 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 245 if (__tmp != 0) 246 __tmp->_M_weak_add_ref(); 247 if (_M_pi != 0) 248 _M_pi->_M_weak_release(); 249 _M_pi = __tmp; 250 return *this; 251 } 252 253 __weak_count<_Lp>& 254 operator=(const __weak_count<_Lp>& __r) // nothrow 255 { 256 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 257 if (__tmp != 0) 258 __tmp->_M_weak_add_ref(); 259 if (_M_pi != 0) 260 _M_pi->_M_weak_release(); 261 _M_pi = __tmp; 262 return *this; 263 } 264 265 void 266 _M_swap(__weak_count<_Lp>& __r) // nothrow 267 { 268 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 269 __r._M_pi = _M_pi; 270 _M_pi = __tmp; 271 } 272 273 long 274 _M_get_use_count() const // nothrow 275 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 276 277 friend inline bool 278 operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) 279 { return __a._M_pi == __b._M_pi; } 280 281 friend inline bool 282 operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) 283 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } 284 285 private: 286 friend class __shared_count<_Lp>; 287 288 _Sp_counted_base<_Lp>* _M_pi; 289 }; 290 291 // now that __weak_count is defined we can define this constructor: 292 template<_Lock_policy _Lp> 293 inline 294 __shared_count<_Lp>:: 295 __shared_count(const __weak_count<_Lp>& __r) 296 : _M_pi(__r._M_pi) 297 { 298 if (_M_pi != 0) 299 _M_pi->_M_add_ref_lock(); 300 else 301 __throw_bad_weak_ptr(); 302 } 303 304 // Forward declarations. 305 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 306 class __shared_ptr; 307 308 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 309 class __weak_ptr; 310 311 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 312 class __enable_shared_from_this; 313 314 template<typename _Tp> 315 class shared_ptr; 316 317 template<typename _Tp> 318 class weak_ptr; 319 320 template<typename _Tp> 321 class enable_shared_from_this; 322 323 // Support for enable_shared_from_this. 324 325 // Friend of __enable_shared_from_this. 326 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> 327 void 328 __enable_shared_from_this_helper(const __shared_count<_Lp>&, 329 const __enable_shared_from_this<_Tp1, 330 _Lp>*, const _Tp2*); 331 332 // Friend of enable_shared_from_this. 333 template<typename _Tp1, typename _Tp2> 334 void 335 __enable_shared_from_this_helper(const __shared_count<>&, 336 const enable_shared_from_this<_Tp1>*, 337 const _Tp2*); 338 339 template<_Lock_policy _Lp> 340 inline void 341 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) 342 { } 343 344 345 struct __static_cast_tag { }; 346 struct __const_cast_tag { }; 347 struct __dynamic_cast_tag { }; 348 349 /** 350 * @class __shared_ptr 351 * 352 * A smart pointer with reference-counted copy semantics. 353 * The object pointed to is deleted when the last shared_ptr pointing to 354 * it is destroyed or reset. 355 */ 356 template<typename _Tp, _Lock_policy _Lp> 357 class __shared_ptr 358 { 359 public: 360 typedef _Tp element_type; 361 362 /** @brief Construct an empty %__shared_ptr. 363 * @post use_count()==0 && get()==0 364 */ 365 __shared_ptr() 366 : _M_ptr(0), _M_refcount() // never throws 367 { } 368 369 /** @brief Construct a %__shared_ptr that owns the pointer @a __p. 370 * @param __p A pointer that is convertible to element_type*. 371 * @post use_count() == 1 && get() == __p 372 * @throw std::bad_alloc, in which case @c delete @a __p is called. 373 */ 374 template<typename _Tp1> 375 explicit 376 __shared_ptr(_Tp1* __p) 377 : _M_ptr(__p), _M_refcount(__p) 378 { 379 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 380 // __glibcxx_function_requires(_CompleteConcept<_Tp1*>) 381 __enable_shared_from_this_helper(_M_refcount, __p, __p); 382 } 383 384 // 385 // Requirements: _Deleter's copy constructor and destructor must 386 // not throw 387 // 388 // __shared_ptr will release __p by calling __d(__p) 389 // 390 /** @brief Construct a %__shared_ptr that owns the pointer @a __p 391 * and the deleter @a __d. 392 * @param __p A pointer. 393 * @param __d A deleter. 394 * @post use_count() == 1 && get() == __p 395 * @throw std::bad_alloc, in which case @a __d(__p) is called. 396 */ 397 template<typename _Tp1, typename _Deleter> 398 __shared_ptr(_Tp1* __p, _Deleter __d) 399 : _M_ptr(__p), _M_refcount(__p, __d) 400 { 401 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 402 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 403 __enable_shared_from_this_helper(_M_refcount, __p, __p); 404 } 405 406 // generated copy constructor, assignment, destructor are fine. 407 408 /** @brief If @a __r is empty, constructs an empty %__shared_ptr; 409 * otherwise construct a %__shared_ptr that shares ownership 410 * with @a __r. 411 * @param __r A %__shared_ptr. 412 * @post get() == __r.get() && use_count() == __r.use_count() 413 */ 414 template<typename _Tp1> 415 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 416 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 417 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 418 419 /** @brief Constructs a %__shared_ptr that shares ownership with @a __r 420 * and stores a copy of the pointer stored in @a __r. 421 * @param __r A weak_ptr. 422 * @post use_count() == __r.use_count() 423 * @throw bad_weak_ptr when __r.expired(), 424 * in which case the constructor has no effect. 425 */ 426 template<typename _Tp1> 427 explicit 428 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 429 : _M_refcount(__r._M_refcount) // may throw 430 { 431 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 432 // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount) 433 // did not throw. 434 _M_ptr = __r._M_ptr; 435 } 436 437#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED 438 /** 439 * @post use_count() == 1 and __r.get() == 0 440 */ 441 template<typename _Tp1> 442 explicit 443 __shared_ptr(std::auto_ptr<_Tp1>& __r) 444 : _M_ptr(__r.get()), _M_refcount() 445 { 446 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 447 // TODO requires _Tp1 is complete, delete __r.release() well-formed 448 _Tp1* __tmp = __r.get(); 449 _M_refcount = __shared_count<_Lp>(__r); 450 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); 451 } 452 453#endif 454 455 template<typename _Tp1> 456 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag) 457 : _M_ptr(static_cast<element_type*>(__r._M_ptr)), 458 _M_refcount(__r._M_refcount) 459 { } 460 461 template<typename _Tp1> 462 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag) 463 : _M_ptr(const_cast<element_type*>(__r._M_ptr)), 464 _M_refcount(__r._M_refcount) 465 { } 466 467 template<typename _Tp1> 468 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag) 469 : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)), 470 _M_refcount(__r._M_refcount) 471 { 472 if (_M_ptr == 0) // need to allocate new counter -- the cast failed 473 _M_refcount = __shared_count<_Lp>(); 474 } 475 476 template<typename _Tp1> 477 __shared_ptr& 478 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 479 { 480 _M_ptr = __r._M_ptr; 481 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 482 return *this; 483 } 484 485#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED 486 template<typename _Tp1> 487 __shared_ptr& 488 operator=(std::auto_ptr<_Tp1>& __r) 489 { 490 __shared_ptr(__r).swap(*this); 491 return *this; 492 } 493#endif 494 495 void 496 reset() // never throws 497 { __shared_ptr().swap(*this); } 498 499 template<typename _Tp1> 500 void 501 reset(_Tp1* __p) // _Tp1 must be complete. 502 { 503 // Catch self-reset errors. 504 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 505 __shared_ptr(__p).swap(*this); 506 } 507 508 template<typename _Tp1, typename _Deleter> 509 void 510 reset(_Tp1* __p, _Deleter __d) 511 { __shared_ptr(__p, __d).swap(*this); } 512 513 // Allow class instantiation when _Tp is [cv-qual] void. 514 typename std::tr1::add_reference<_Tp>::type 515 operator*() const // never throws 516 { 517 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 518 return *_M_ptr; 519 } 520 521 _Tp* 522 operator->() const // never throws 523 { 524 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 525 return _M_ptr; 526 } 527 528 _Tp* 529 get() const // never throws 530 { return _M_ptr; } 531 532 // Implicit conversion to "bool" 533 private: 534 typedef _Tp* __shared_ptr::*__unspecified_bool_type; 535 536 public: 537 operator __unspecified_bool_type() const // never throws 538 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; } 539 540 bool 541 unique() const // never throws 542 { return _M_refcount._M_unique(); } 543 544 long 545 use_count() const // never throws 546 { return _M_refcount._M_get_use_count(); } 547 548 void 549 swap(__shared_ptr<_Tp, _Lp>& __other) // never throws 550 { 551 std::swap(_M_ptr, __other._M_ptr); 552 _M_refcount._M_swap(__other._M_refcount); 553 } 554 555 private: 556 void* 557 _M_get_deleter(const std::type_info& __ti) const 558 { return _M_refcount._M_get_deleter(__ti); } 559 560 template<typename _Tp1, _Lock_policy _Lp1> 561 bool 562 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const 563 { return _M_refcount < __rhs._M_refcount; } 564 565 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 566 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 567 568 template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 569 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&); 570 571 // Friends injected into enclosing namespace and found by ADL: 572 template<typename _Tp1> 573 friend inline bool 574 operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 575 { return __a.get() == __b.get(); } 576 577 template<typename _Tp1> 578 friend inline bool 579 operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 580 { return __a.get() != __b.get(); } 581 582 template<typename _Tp1> 583 friend inline bool 584 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 585 { return __a._M_less(__b); } 586 587 _Tp* _M_ptr; // Contained pointer. 588 __shared_count<_Lp> _M_refcount; // Reference counter. 589 }; 590 591 // 2.2.3.8 shared_ptr specialized algorithms. 592 template<typename _Tp, _Lock_policy _Lp> 593 inline void 594 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) 595 { __a.swap(__b); } 596 597 // 2.2.3.9 shared_ptr casts 598 /** @warning The seemingly equivalent 599 * <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code> 600 * will eventually result in undefined behaviour, 601 * attempting to delete the same object twice. 602 */ 603 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 604 inline __shared_ptr<_Tp, _Lp> 605 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 606 { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); } 607 608 /** @warning The seemingly equivalent 609 * <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code> 610 * will eventually result in undefined behaviour, 611 * attempting to delete the same object twice. 612 */ 613 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 614 inline __shared_ptr<_Tp, _Lp> 615 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 616 { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); } 617 618 /** @warning The seemingly equivalent 619 * <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code> 620 * will eventually result in undefined behaviour, 621 * attempting to delete the same object twice. 622 */ 623 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 624 inline __shared_ptr<_Tp, _Lp> 625 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 626 { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); } 627 628 // 2.2.3.7 shared_ptr I/O 629 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> 630 std::basic_ostream<_Ch, _Tr>& 631 operator<<(std::basic_ostream<_Ch, _Tr>& __os, 632 const __shared_ptr<_Tp, _Lp>& __p) 633 { 634 __os << __p.get(); 635 return __os; 636 } 637 638 // 2.2.3.10 shared_ptr get_deleter (experimental) 639 template<typename _Del, typename _Tp, _Lock_policy _Lp> 640 inline _Del* 641 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) 642 { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); } 643 644 645 template<typename _Tp, _Lock_policy _Lp> 646 class __weak_ptr 647 { 648 public: 649 typedef _Tp element_type; 650 651 __weak_ptr() 652 : _M_ptr(0), _M_refcount() // never throws 653 { } 654 655 // Generated copy constructor, assignment, destructor are fine. 656 657 // The "obvious" converting constructor implementation: 658 // 659 // template<typename _Tp1> 660 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 661 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 662 // { } 663 // 664 // has a serious problem. 665 // 666 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 667 // conversion may require access to *__r._M_ptr (virtual inheritance). 668 // 669 // It is not possible to avoid spurious access violations since 670 // in multithreaded programs __r._M_ptr may be invalidated at any point. 671 template<typename _Tp1> 672 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 673 : _M_refcount(__r._M_refcount) // never throws 674 { 675 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 676 _M_ptr = __r.lock().get(); 677 } 678 679 template<typename _Tp1> 680 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 681 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 682 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 683 684 template<typename _Tp1> 685 __weak_ptr& 686 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws 687 { 688 _M_ptr = __r.lock().get(); 689 _M_refcount = __r._M_refcount; 690 return *this; 691 } 692 693 template<typename _Tp1> 694 __weak_ptr& 695 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 696 { 697 _M_ptr = __r._M_ptr; 698 _M_refcount = __r._M_refcount; 699 return *this; 700 } 701 702 __shared_ptr<_Tp, _Lp> 703 lock() const // never throws 704 { 705#ifdef __GTHREADS 706 // Optimization: avoid throw overhead. 707 if (expired()) 708 return __shared_ptr<element_type, _Lp>(); 709 710 __try 711 { 712 return __shared_ptr<element_type, _Lp>(*this); 713 } 714 __catch(const bad_weak_ptr&) 715 { 716 // Q: How can we get here? 717 // A: Another thread may have invalidated r after the 718 // use_count test above. 719 return __shared_ptr<element_type, _Lp>(); 720 } 721 722#else 723 // Optimization: avoid try/catch overhead when single threaded. 724 return expired() ? __shared_ptr<element_type, _Lp>() 725 : __shared_ptr<element_type, _Lp>(*this); 726 727#endif 728 } // XXX MT 729 730 long 731 use_count() const // never throws 732 { return _M_refcount._M_get_use_count(); } 733 734 bool 735 expired() const // never throws 736 { return _M_refcount._M_get_use_count() == 0; } 737 738 void 739 reset() // never throws 740 { __weak_ptr().swap(*this); } 741 742 void 743 swap(__weak_ptr& __s) // never throws 744 { 745 std::swap(_M_ptr, __s._M_ptr); 746 _M_refcount._M_swap(__s._M_refcount); 747 } 748 749 private: 750 // Used by __enable_shared_from_this. 751 void 752 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) 753 { 754 _M_ptr = __ptr; 755 _M_refcount = __refcount; 756 } 757 758 template<typename _Tp1> 759 bool 760 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const 761 { return _M_refcount < __rhs._M_refcount; } 762 763 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 764 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 765 friend class __enable_shared_from_this<_Tp, _Lp>; 766 friend class enable_shared_from_this<_Tp>; 767 768 // Friend injected into namespace and found by ADL. 769 template<typename _Tp1> 770 friend inline bool 771 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs) 772 { return __lhs._M_less(__rhs); } 773 774 _Tp* _M_ptr; // Contained pointer. 775 __weak_count<_Lp> _M_refcount; // Reference counter. 776 }; 777 778 // 2.2.4.7 weak_ptr specialized algorithms. 779 template<typename _Tp, _Lock_policy _Lp> 780 inline void 781 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) 782 { __a.swap(__b); } 783 784 785 template<typename _Tp, _Lock_policy _Lp> 786 class __enable_shared_from_this 787 { 788 protected: 789 __enable_shared_from_this() { } 790 791 __enable_shared_from_this(const __enable_shared_from_this&) { } 792 793 __enable_shared_from_this& 794 operator=(const __enable_shared_from_this&) 795 { return *this; } 796 797 ~__enable_shared_from_this() { } 798 799 public: 800 __shared_ptr<_Tp, _Lp> 801 shared_from_this() 802 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 803 804 __shared_ptr<const _Tp, _Lp> 805 shared_from_this() const 806 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } 807 808 private: 809 template<typename _Tp1> 810 void 811 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const 812 { _M_weak_this._M_assign(__p, __n); } 813 814 template<typename _Tp1> 815 friend void 816 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, 817 const __enable_shared_from_this* __pe, 818 const _Tp1* __px) 819 { 820 if (__pe != 0) 821 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 822 } 823 824 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 825 }; 826 827 828 /// shared_ptr 829 // The actual shared_ptr, with forwarding constructors and 830 // assignment operators. 831 template<typename _Tp> 832 class shared_ptr 833 : public __shared_ptr<_Tp> 834 { 835 public: 836 shared_ptr() 837 : __shared_ptr<_Tp>() { } 838 839 template<typename _Tp1> 840 explicit 841 shared_ptr(_Tp1* __p) 842 : __shared_ptr<_Tp>(__p) { } 843 844 template<typename _Tp1, typename _Deleter> 845 shared_ptr(_Tp1* __p, _Deleter __d) 846 : __shared_ptr<_Tp>(__p, __d) { } 847 848 template<typename _Tp1> 849 shared_ptr(const shared_ptr<_Tp1>& __r) 850 : __shared_ptr<_Tp>(__r) { } 851 852 template<typename _Tp1> 853 explicit 854 shared_ptr(const weak_ptr<_Tp1>& __r) 855 : __shared_ptr<_Tp>(__r) { } 856 857#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED 858 template<typename _Tp1> 859 explicit 860 shared_ptr(std::auto_ptr<_Tp1>& __r) 861 : __shared_ptr<_Tp>(__r) { } 862#endif 863 864 template<typename _Tp1> 865 shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag) 866 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { } 867 868 template<typename _Tp1> 869 shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag) 870 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { } 871 872 template<typename _Tp1> 873 shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag) 874 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { } 875 876 template<typename _Tp1> 877 shared_ptr& 878 operator=(const shared_ptr<_Tp1>& __r) // never throws 879 { 880 this->__shared_ptr<_Tp>::operator=(__r); 881 return *this; 882 } 883 884#if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED 885 template<typename _Tp1> 886 shared_ptr& 887 operator=(std::auto_ptr<_Tp1>& __r) 888 { 889 this->__shared_ptr<_Tp>::operator=(__r); 890 return *this; 891 } 892#endif 893 }; 894 895 // 2.2.3.8 shared_ptr specialized algorithms. 896 template<typename _Tp> 897 inline void 898 swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b) 899 { __a.swap(__b); } 900 901 template<typename _Tp, typename _Tp1> 902 inline shared_ptr<_Tp> 903 static_pointer_cast(const shared_ptr<_Tp1>& __r) 904 { return shared_ptr<_Tp>(__r, __static_cast_tag()); } 905 906 template<typename _Tp, typename _Tp1> 907 inline shared_ptr<_Tp> 908 const_pointer_cast(const shared_ptr<_Tp1>& __r) 909 { return shared_ptr<_Tp>(__r, __const_cast_tag()); } 910 911 template<typename _Tp, typename _Tp1> 912 inline shared_ptr<_Tp> 913 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) 914 { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); } 915 916 917 /// weak_ptr 918 // The actual weak_ptr, with forwarding constructors and 919 // assignment operators. 920 template<typename _Tp> 921 class weak_ptr 922 : public __weak_ptr<_Tp> 923 { 924 public: 925 weak_ptr() 926 : __weak_ptr<_Tp>() { } 927 928 template<typename _Tp1> 929 weak_ptr(const weak_ptr<_Tp1>& __r) 930 : __weak_ptr<_Tp>(__r) { } 931 932 template<typename _Tp1> 933 weak_ptr(const shared_ptr<_Tp1>& __r) 934 : __weak_ptr<_Tp>(__r) { } 935 936 template<typename _Tp1> 937 weak_ptr& 938 operator=(const weak_ptr<_Tp1>& __r) // never throws 939 { 940 this->__weak_ptr<_Tp>::operator=(__r); 941 return *this; 942 } 943 944 template<typename _Tp1> 945 weak_ptr& 946 operator=(const shared_ptr<_Tp1>& __r) // never throws 947 { 948 this->__weak_ptr<_Tp>::operator=(__r); 949 return *this; 950 } 951 952 shared_ptr<_Tp> 953 lock() const // never throws 954 { 955#ifdef __GTHREADS 956 if (this->expired()) 957 return shared_ptr<_Tp>(); 958 959 __try 960 { 961 return shared_ptr<_Tp>(*this); 962 } 963 __catch(const bad_weak_ptr&) 964 { 965 return shared_ptr<_Tp>(); 966 } 967#else 968 return this->expired() ? shared_ptr<_Tp>() 969 : shared_ptr<_Tp>(*this); 970#endif 971 } 972 }; 973 974 /// enable_shared_from_this 975 template<typename _Tp> 976 class enable_shared_from_this 977 { 978 protected: 979 enable_shared_from_this() { } 980 981 enable_shared_from_this(const enable_shared_from_this&) { } 982 983 enable_shared_from_this& 984 operator=(const enable_shared_from_this&) 985 { return *this; } 986 987 ~enable_shared_from_this() { } 988 989 public: 990 shared_ptr<_Tp> 991 shared_from_this() 992 { return shared_ptr<_Tp>(this->_M_weak_this); } 993 994 shared_ptr<const _Tp> 995 shared_from_this() const 996 { return shared_ptr<const _Tp>(this->_M_weak_this); } 997 998 private: 999 template<typename _Tp1> 1000 void 1001 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const 1002 { _M_weak_this._M_assign(__p, __n); } 1003 1004 template<typename _Tp1> 1005 friend void 1006 __enable_shared_from_this_helper(const __shared_count<>& __pn, 1007 const enable_shared_from_this* __pe, 1008 const _Tp1* __px) 1009 { 1010 if (__pe != 0) 1011 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 1012 } 1013 1014 mutable weak_ptr<_Tp> _M_weak_this; 1015 }; 1016 1017} 1018} 1019 1020#endif // _TR1_SHARED_PTR_H 1021