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