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