1// shared_ptr and weak_ptr implementation -*- 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 bits/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 _SHARED_PTR_H 50#define _SHARED_PTR_H 1 51 52#ifndef __GXX_EXPERIMENTAL_CXX0X__ 53# include <c++0x_warning.h> 54#endif 55 56#if defined(_GLIBCXX_INCLUDE_AS_TR1) 57# error C++0x header cannot be included from TR1 header 58#endif 59 60_GLIBCXX_BEGIN_NAMESPACE(std) 61 62 /** 63 * @addtogroup pointer_abstractions 64 * @{ 65 */ 66 67 // counted ptr with no deleter or allocator support 68 template<typename _Ptr, _Lock_policy _Lp> 69 class _Sp_counted_ptr 70 : public _Sp_counted_base<_Lp> 71 { 72 public: 73 _Sp_counted_ptr(_Ptr __p) 74 : _M_ptr(__p) { } 75 76 virtual void 77 _M_dispose() // nothrow 78 { delete _M_ptr; } 79 80 virtual void 81 _M_destroy() // nothrow 82 { delete this; } 83 84 virtual void* 85 _M_get_deleter(const std::type_info& __ti) 86 { return 0; } 87 88 _Sp_counted_ptr(const _Sp_counted_ptr&) = delete; 89 _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete; 90 91 protected: 92 _Ptr _M_ptr; // copy constructor must not throw 93 }; 94 95 // support for custom deleter and/or allocator 96 template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp> 97 class _Sp_counted_deleter 98 : public _Sp_counted_ptr<_Ptr, _Lp> 99 { 100 typedef typename _Alloc::template 101 rebind<_Sp_counted_deleter>::other _My_alloc_type; 102 103 // Helper class that stores the Deleter and also acts as an allocator. 104 // Used to dispose of the owned pointer and the internal refcount 105 // Requires that copies of _Alloc can free each other's memory. 106 struct _My_Deleter 107 : public _My_alloc_type // copy constructor must not throw 108 { 109 _Deleter _M_del; // copy constructor must not throw 110 _My_Deleter(_Deleter __d, const _Alloc& __a) 111 : _My_alloc_type(__a), _M_del(__d) { } 112 }; 113 114 protected: 115 typedef _Sp_counted_ptr<_Ptr, _Lp> _Base_type; 116 117 public: 118 /** 119 * @brief 120 * @pre __d(__p) must not throw. 121 */ 122 _Sp_counted_deleter(_Ptr __p, _Deleter __d) 123 : _Base_type(__p), _M_del(__d, _Alloc()) { } 124 125 /** 126 * @brief 127 * @pre __d(__p) must not throw. 128 */ 129 _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) 130 : _Base_type(__p), _M_del(__d, __a) { } 131 132 virtual void 133 _M_dispose() // nothrow 134 { _M_del._M_del(_Base_type::_M_ptr); } 135 136 virtual void 137 _M_destroy() // nothrow 138 { 139 _My_alloc_type __a(_M_del); 140 this->~_Sp_counted_deleter(); 141 __a.deallocate(this, 1); 142 } 143 144 virtual void* 145 _M_get_deleter(const std::type_info& __ti) 146 { return __ti == typeid(_Deleter) ? &_M_del._M_del : 0; } 147 148 protected: 149 _My_Deleter _M_del; // copy constructor must not throw 150 }; 151 152 // helpers for make_shared / allocate_shared 153 154 template<typename _Tp> 155 struct _Sp_destroy_inplace 156 { 157 void operator()(_Tp* __p) const { if (__p) __p->~_Tp(); } 158 }; 159 160 struct _Sp_make_shared_tag { }; 161 162 template<typename _Tp, typename _Alloc, _Lock_policy _Lp> 163 class _Sp_counted_ptr_inplace 164 : public _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp> 165 { 166 typedef _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp> 167 _Base_type; 168 169 public: 170 _Sp_counted_ptr_inplace(_Alloc __a) 171 : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a) 172 , _M_storage() 173 { 174 void* __p = &_M_storage; 175 ::new (__p) _Tp(); // might throw 176 _Base_type::_Base_type::_M_ptr = static_cast<_Tp*>(__p); 177 } 178 179 template<typename... _Args> 180 _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args) 181 : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a) 182 , _M_storage() 183 { 184 void* __p = &_M_storage; 185 ::new (__p) _Tp(std::forward<_Args>(__args)...); // might throw 186 _Base_type::_Base_type::_M_ptr = static_cast<_Tp*>(__p); 187 } 188 189 // override because the allocator needs to know the dynamic type 190 virtual void 191 _M_destroy() // nothrow 192 { 193 typedef typename _Alloc::template 194 rebind<_Sp_counted_ptr_inplace>::other _My_alloc_type; 195 _My_alloc_type __a(_Base_type::_M_del); 196 this->~_Sp_counted_ptr_inplace(); 197 __a.deallocate(this, 1); 198 } 199 200 // sneaky trick so __shared_ptr can get the managed pointer 201 virtual void* 202 _M_get_deleter(const std::type_info& __ti) 203 { 204 return __ti == typeid(_Sp_make_shared_tag) 205 ? static_cast<void*>(&_M_storage) 206 : _Base_type::_M_get_deleter(__ti); 207 } 208 209 private: 210 typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type 211 _M_storage; 212 }; 213 214 template<_Lock_policy _Lp = __default_lock_policy> 215 class __weak_count; 216 217 template<_Lock_policy _Lp = __default_lock_policy> 218 class __shared_count 219 { 220 public: 221 __shared_count() 222 : _M_pi(0) // nothrow 223 { } 224 225 template<typename _Ptr> 226 __shared_count(_Ptr __p) : _M_pi(0) 227 { 228 __try 229 { 230 _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); 231 } 232 __catch(...) 233 { 234 delete __p; 235 __throw_exception_again; 236 } 237 } 238 239 template<typename _Ptr, typename _Deleter> 240 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) 241 { 242 // allocator's value_type doesn't matter, will rebind it anyway 243 typedef std::allocator<int> _Alloc; 244 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; 245 typedef std::allocator<_Sp_cd_type> _Alloc2; 246 _Alloc2 __a2; 247 __try 248 { 249 _M_pi = __a2.allocate(1); 250 ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d); 251 } 252 __catch(...) 253 { 254 __d(__p); // Call _Deleter on __p. 255 if (_M_pi) 256 __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1); 257 __throw_exception_again; 258 } 259 } 260 261 template<typename _Ptr, typename _Deleter, typename _Alloc> 262 __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) 263 { 264 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; 265 typedef typename _Alloc::template rebind<_Sp_cd_type>::other _Alloc2; 266 _Alloc2 __a2(__a); 267 __try 268 { 269 _M_pi = __a2.allocate(1); 270 ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d, __a); 271 } 272 __catch(...) 273 { 274 __d(__p); // Call _Deleter on __p. 275 if (_M_pi) 276 __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1); 277 __throw_exception_again; 278 } 279 } 280 281 template<typename _Tp, typename _Alloc, typename... _Args> 282 __shared_count(_Sp_make_shared_tag, _Tp*, _Alloc __a, _Args&&... __args) 283 : _M_pi(0) 284 { 285 typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type; 286 typedef typename _Alloc::template rebind<_Sp_cp_type>::other _Alloc2; 287 _Alloc2 __a2(__a); 288 __try 289 { 290 _M_pi = __a2.allocate(1); 291 ::new(static_cast<void*>(_M_pi)) _Sp_cp_type(__a, 292 std::forward<_Args>(__args)...); 293 } 294 __catch(...) 295 { 296 if (_M_pi) 297 __a2.deallocate(static_cast<_Sp_cp_type*>(_M_pi), 1); 298 __throw_exception_again; 299 } 300 } 301 302#if _GLIBCXX_DEPRECATED 303 // Special case for auto_ptr<_Tp> to provide the strong guarantee. 304 template<typename _Tp> 305 explicit 306 __shared_count(std::auto_ptr<_Tp>&& __r) 307 : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get())) 308 { __r.release(); } 309#endif 310 311 // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee. 312 template<typename _Tp, typename _Del> 313 explicit 314 __shared_count(std::unique_ptr<_Tp, _Del>&& __r) 315 : _M_pi(_S_create_from_up(std::move(__r))) 316 { __r.release(); } 317 318 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 319 explicit 320 __shared_count(const __weak_count<_Lp>& __r); 321 322 ~__shared_count() // nothrow 323 { 324 if (_M_pi != 0) 325 _M_pi->_M_release(); 326 } 327 328 __shared_count(const __shared_count& __r) 329 : _M_pi(__r._M_pi) // nothrow 330 { 331 if (_M_pi != 0) 332 _M_pi->_M_add_ref_copy(); 333 } 334 335 __shared_count& 336 operator=(const __shared_count& __r) // nothrow 337 { 338 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 339 if (__tmp != _M_pi) 340 { 341 if (__tmp != 0) 342 __tmp->_M_add_ref_copy(); 343 if (_M_pi != 0) 344 _M_pi->_M_release(); 345 _M_pi = __tmp; 346 } 347 return *this; 348 } 349 350 void 351 _M_swap(__shared_count& __r) // nothrow 352 { 353 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 354 __r._M_pi = _M_pi; 355 _M_pi = __tmp; 356 } 357 358 long 359 _M_get_use_count() const // nothrow 360 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 361 362 bool 363 _M_unique() const // nothrow 364 { return this->_M_get_use_count() == 1; } 365 366 void* 367 _M_get_deleter(const std::type_info& __ti) const 368 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; } 369 370 bool 371 _M_less(const __shared_count& __rhs) const 372 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 373 374 bool 375 _M_less(const __weak_count<_Lp>& __rhs) const 376 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 377 378 // friend function injected into enclosing namespace and found by ADL 379 friend inline bool 380 operator==(const __shared_count& __a, const __shared_count& __b) 381 { return __a._M_pi == __b._M_pi; } 382 383 private: 384 friend class __weak_count<_Lp>; 385 386 template<typename _Tp, typename _Del> 387 static _Sp_counted_base<_Lp>* 388 _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r, 389 typename std::enable_if<!std::is_reference<_Del>::value>::type* = 0) 390 { 391 return new _Sp_counted_deleter<_Tp*, _Del, std::allocator<_Tp>, 392 _Lp>(__r.get(), __r.get_deleter()); 393 } 394 395 template<typename _Tp, typename _Del> 396 static _Sp_counted_base<_Lp>* 397 _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r, 398 typename std::enable_if<std::is_reference<_Del>::value>::type* = 0) 399 { 400 typedef typename std::remove_reference<_Del>::type _Del1; 401 typedef std::reference_wrapper<_Del1> _Del2; 402 return new _Sp_counted_deleter<_Tp*, _Del2, std::allocator<_Tp>, 403 _Lp>(__r.get(), std::ref(__r.get_deleter())); 404 } 405 406 _Sp_counted_base<_Lp>* _M_pi; 407 }; 408 409 410 template<_Lock_policy _Lp> 411 class __weak_count 412 { 413 public: 414 __weak_count() 415 : _M_pi(0) // nothrow 416 { } 417 418 __weak_count(const __shared_count<_Lp>& __r) 419 : _M_pi(__r._M_pi) // nothrow 420 { 421 if (_M_pi != 0) 422 _M_pi->_M_weak_add_ref(); 423 } 424 425 __weak_count(const __weak_count<_Lp>& __r) 426 : _M_pi(__r._M_pi) // nothrow 427 { 428 if (_M_pi != 0) 429 _M_pi->_M_weak_add_ref(); 430 } 431 432 ~__weak_count() // nothrow 433 { 434 if (_M_pi != 0) 435 _M_pi->_M_weak_release(); 436 } 437 438 __weak_count<_Lp>& 439 operator=(const __shared_count<_Lp>& __r) // nothrow 440 { 441 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 442 if (__tmp != 0) 443 __tmp->_M_weak_add_ref(); 444 if (_M_pi != 0) 445 _M_pi->_M_weak_release(); 446 _M_pi = __tmp; 447 return *this; 448 } 449 450 __weak_count<_Lp>& 451 operator=(const __weak_count<_Lp>& __r) // nothrow 452 { 453 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 454 if (__tmp != 0) 455 __tmp->_M_weak_add_ref(); 456 if (_M_pi != 0) 457 _M_pi->_M_weak_release(); 458 _M_pi = __tmp; 459 return *this; 460 } 461 462 void 463 _M_swap(__weak_count<_Lp>& __r) // nothrow 464 { 465 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 466 __r._M_pi = _M_pi; 467 _M_pi = __tmp; 468 } 469 470 long 471 _M_get_use_count() const // nothrow 472 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 473 474 bool 475 _M_less(const __weak_count& __rhs) const 476 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 477 478 bool 479 _M_less(const __shared_count<_Lp>& __rhs) const 480 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 481 482 // friend function injected into enclosing namespace and found by ADL 483 friend inline bool 484 operator==(const __weak_count& __a, const __weak_count& __b) 485 { return __a._M_pi == __b._M_pi; } 486 487 private: 488 friend class __shared_count<_Lp>; 489 490 _Sp_counted_base<_Lp>* _M_pi; 491 }; 492 493 // now that __weak_count is defined we can define this constructor: 494 template<_Lock_policy _Lp> 495 inline 496 __shared_count<_Lp>:: 497 __shared_count(const __weak_count<_Lp>& __r) 498 : _M_pi(__r._M_pi) 499 { 500 if (_M_pi != 0) 501 _M_pi->_M_add_ref_lock(); 502 else 503 __throw_bad_weak_ptr(); 504 } 505 506 // Forward declarations. 507 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 508 class __shared_ptr; 509 510 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 511 class __weak_ptr; 512 513 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 514 class __enable_shared_from_this; 515 516 template<typename _Tp> 517 class shared_ptr; 518 519 template<typename _Tp> 520 class weak_ptr; 521 522 template<typename _Tp> 523 class enable_shared_from_this; 524 525 // Support for enable_shared_from_this. 526 527 // Friend of __enable_shared_from_this. 528 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> 529 void 530 __enable_shared_from_this_helper(const __shared_count<_Lp>&, 531 const __enable_shared_from_this<_Tp1, 532 _Lp>*, const _Tp2*); 533 534 // Friend of enable_shared_from_this. 535 template<typename _Tp1, typename _Tp2> 536 void 537 __enable_shared_from_this_helper(const __shared_count<>&, 538 const enable_shared_from_this<_Tp1>*, 539 const _Tp2*); 540 541 template<_Lock_policy _Lp> 542 inline void 543 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) 544 { } 545 546 547 template<typename _Tp, _Lock_policy _Lp> 548 class __shared_ptr 549 { 550 public: 551 typedef _Tp element_type; 552 553 /** @brief Construct an empty %__shared_ptr. 554 * @post use_count()==0 && get()==0 555 */ 556 __shared_ptr() 557 : _M_ptr(0), _M_refcount() // never throws 558 { } 559 560 /** @brief Construct a %__shared_ptr that owns the pointer @a __p. 561 * @param __p A pointer that is convertible to element_type*. 562 * @post use_count() == 1 && get() == __p 563 * @throw std::bad_alloc, in which case @c delete @a __p is called. 564 */ 565 template<typename _Tp1> 566 explicit 567 __shared_ptr(_Tp1* __p) 568 : _M_ptr(__p), _M_refcount(__p) 569 { 570 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 571 // __glibcxx_function_requires(_CompleteConcept<_Tp1*>) 572 __enable_shared_from_this_helper(_M_refcount, __p, __p); 573 } 574 575 // 576 // Requirements: _Deleter's copy constructor and destructor must 577 // not throw 578 // 579 // __shared_ptr will release __p by calling __d(__p) 580 // 581 /** @brief Construct a %__shared_ptr that owns the pointer @a __p 582 * and the deleter @a __d. 583 * @param __p A pointer. 584 * @param __d A deleter. 585 * @post use_count() == 1 && get() == __p 586 * @throw std::bad_alloc, in which case @a __d(__p) is called. 587 */ 588 template<typename _Tp1, typename _Deleter> 589 __shared_ptr(_Tp1* __p, _Deleter __d) 590 : _M_ptr(__p), _M_refcount(__p, __d) 591 { 592 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 593 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 594 __enable_shared_from_this_helper(_M_refcount, __p, __p); 595 } 596 597 // 598 // Requirements: _Deleter's copy constructor and destructor must 599 // not throw _Alloc's copy constructor and destructor must not 600 // throw. 601 // 602 // __shared_ptr will release __p by calling __d(__p) 603 // 604 /** @brief Construct a %__shared_ptr that owns the pointer @a __p 605 * and the deleter @a __d. 606 * @param __p A pointer. 607 * @param __d A deleter. 608 * @param __a An allocator. 609 * @post use_count() == 1 && get() == __p 610 * @throw std::bad_alloc, in which case @a __d(__p) is called. 611 */ 612 template<typename _Tp1, typename _Deleter, typename _Alloc> 613 __shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a) 614 : _M_ptr(__p), _M_refcount(__p, __d, __a) 615 { 616 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 617 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 618 __enable_shared_from_this_helper(_M_refcount, __p, __p); 619 } 620 621 /** @brief Constructs a %__shared_ptr instance that stores @a __p 622 * and shares ownership with @a __r. 623 * @param __r A %__shared_ptr. 624 * @param __p A pointer that will remain valid while @a *__r is valid. 625 * @post get() == __p && use_count() == __r.use_count() 626 * 627 * This can be used to construct a @c shared_ptr to a sub-object 628 * of an object managed by an existing @c shared_ptr. 629 * 630 * @code 631 * shared_ptr< pair<int,int> > pii(new pair<int,int>()); 632 * shared_ptr<int> pi(pii, &pii->first); 633 * assert(pii.use_count() == 2); 634 * @endcode 635 */ 636 template<typename _Tp1> 637 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) 638 : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws 639 { } 640 641 // generated copy constructor, assignment, destructor are fine. 642 643 /** @brief If @a __r is empty, constructs an empty %__shared_ptr; 644 * otherwise construct a %__shared_ptr that shares ownership 645 * with @a __r. 646 * @param __r A %__shared_ptr. 647 * @post get() == __r.get() && use_count() == __r.use_count() 648 */ 649 template<typename _Tp1> 650 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 651 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 652 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 653 654 /** @brief Move-constructs a %__shared_ptr instance from @a __r. 655 * @param __r A %__shared_ptr rvalue. 656 * @post *this contains the old value of @a __r, @a __r is empty. 657 */ 658 __shared_ptr(__shared_ptr&& __r) 659 : _M_ptr(__r._M_ptr), _M_refcount() // never throws 660 { 661 _M_refcount._M_swap(__r._M_refcount); 662 __r._M_ptr = 0; 663 } 664 665 /** @brief Move-constructs a %__shared_ptr instance from @a __r. 666 * @param __r A %__shared_ptr rvalue. 667 * @post *this contains the old value of @a __r, @a __r is empty. 668 */ 669 template<typename _Tp1> 670 __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) 671 : _M_ptr(__r._M_ptr), _M_refcount() // never throws 672 { 673 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 674 _M_refcount._M_swap(__r._M_refcount); 675 __r._M_ptr = 0; 676 } 677 678 /** @brief Constructs a %__shared_ptr that shares ownership with @a __r 679 * and stores a copy of the pointer stored in @a __r. 680 * @param __r A weak_ptr. 681 * @post use_count() == __r.use_count() 682 * @throw bad_weak_ptr when __r.expired(), 683 * in which case the constructor has no effect. 684 */ 685 template<typename _Tp1> 686 explicit 687 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 688 : _M_refcount(__r._M_refcount) // may throw 689 { 690 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 691 // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount) 692 // did not throw. 693 _M_ptr = __r._M_ptr; 694 } 695 696 template<typename _Tp1, typename _Del> 697 explicit 698 __shared_ptr(const std::unique_ptr<_Tp1, _Del>&) = delete; 699 700 /** 701 * If an exception is thrown this constructor has no effect. 702 */ 703 template<typename _Tp1, typename _Del> 704 explicit 705 __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r) 706 : _M_ptr(__r.get()), _M_refcount() 707 { 708 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 709 _Tp1* __tmp = __r.get(); 710 _M_refcount = __shared_count<_Lp>(std::move(__r)); 711 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); 712 } 713 714#if _GLIBCXX_DEPRECATED 715 /** 716 * @post use_count() == 1 and __r.get() == 0 717 */ 718 template<typename _Tp1> 719 explicit 720 __shared_ptr(std::auto_ptr<_Tp1>&& __r) 721 : _M_ptr(__r.get()), _M_refcount() 722 { 723 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 724 // TODO requires _Tp1 is complete, delete __r.release() well-formed 725 _Tp1* __tmp = __r.get(); 726 _M_refcount = __shared_count<_Lp>(std::move(__r)); 727 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); 728 } 729#endif 730 731 template<typename _Tp1> 732 __shared_ptr& 733 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 734 { 735 _M_ptr = __r._M_ptr; 736 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 737 return *this; 738 } 739 740#if _GLIBCXX_DEPRECATED 741 template<typename _Tp1> 742 __shared_ptr& 743 operator=(std::auto_ptr<_Tp1>&& __r) 744 { 745 __shared_ptr(std::move(__r)).swap(*this); 746 return *this; 747 } 748#endif 749 750 __shared_ptr& 751 operator=(__shared_ptr&& __r) 752 { 753 __shared_ptr(std::move(__r)).swap(*this); 754 return *this; 755 } 756 757 template<class _Tp1> 758 __shared_ptr& 759 operator=(__shared_ptr<_Tp1, _Lp>&& __r) 760 { 761 __shared_ptr(std::move(__r)).swap(*this); 762 return *this; 763 } 764 765 template<typename _Tp1, typename _Del> 766 __shared_ptr& 767 operator=(const std::unique_ptr<_Tp1, _Del>& __r) = delete; 768 769 template<typename _Tp1, typename _Del> 770 __shared_ptr& 771 operator=(std::unique_ptr<_Tp1, _Del>&& __r) 772 { 773 __shared_ptr(std::move(__r)).swap(*this); 774 return *this; 775 } 776 777 void 778 reset() // never throws 779 { __shared_ptr().swap(*this); } 780 781 template<typename _Tp1> 782 void 783 reset(_Tp1* __p) // _Tp1 must be complete. 784 { 785 // Catch self-reset errors. 786 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 787 __shared_ptr(__p).swap(*this); 788 } 789 790 template<typename _Tp1, typename _Deleter> 791 void 792 reset(_Tp1* __p, _Deleter __d) 793 { __shared_ptr(__p, __d).swap(*this); } 794 795 template<typename _Tp1, typename _Deleter, typename _Alloc> 796 void 797 reset(_Tp1* __p, _Deleter __d, const _Alloc& __a) 798 { __shared_ptr(__p, __d, __a).swap(*this); } 799 800 // Allow class instantiation when _Tp is [cv-qual] void. 801 typename std::add_lvalue_reference<_Tp>::type 802 operator*() const // never throws 803 { 804 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 805 return *_M_ptr; 806 } 807 808 _Tp* 809 operator->() const // never throws 810 { 811 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 812 return _M_ptr; 813 } 814 815 _Tp* 816 get() const // never throws 817 { return _M_ptr; } 818 819 // Implicit conversion to "bool" 820 private: 821 typedef _Tp* __shared_ptr::*__unspecified_bool_type; 822 823 public: 824 operator __unspecified_bool_type() const // never throws 825 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; } 826 827 bool 828 unique() const // never throws 829 { return _M_refcount._M_unique(); } 830 831 long 832 use_count() const // never throws 833 { return _M_refcount._M_get_use_count(); } 834 835 void 836 swap(__shared_ptr<_Tp, _Lp>&& __other) // never throws 837 { 838 std::swap(_M_ptr, __other._M_ptr); 839 _M_refcount._M_swap(__other._M_refcount); 840 } 841 842 template<typename _Tp1> 843 bool 844 owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const 845 { return _M_refcount._M_less(__rhs._M_refcount); } 846 847 template<typename _Tp1> 848 bool 849 owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const 850 { return _M_refcount._M_less(__rhs._M_refcount); } 851 852 protected: 853 // This constructor is non-standard, it is used by allocate_shared. 854 template<typename _Alloc, typename... _Args> 855 __shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args) 856 : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a, 857 std::forward<_Args>(__args)...) 858 { 859 // _M_ptr needs to point to the newly constructed object. 860 // This relies on _Sp_counted_ptr_inplace::_M_get_deleter. 861 void* __p = _M_refcount._M_get_deleter(typeid(__tag)); 862 _M_ptr = static_cast<_Tp*>(__p); 863 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr); 864 } 865 866 template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc, 867 typename... _Args> 868 friend __shared_ptr<_Tp1, _Lp1> 869 __allocate_shared(_Alloc __a, _Args&&... __args); 870 871 private: 872 void* 873 _M_get_deleter(const std::type_info& __ti) const 874 { return _M_refcount._M_get_deleter(__ti); } 875 876 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 877 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 878 879 template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 880 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&); 881 882 _Tp* _M_ptr; // Contained pointer. 883 __shared_count<_Lp> _M_refcount; // Reference counter. 884 }; 885 886 // 20.8.13.2.7 shared_ptr comparisons 887 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 888 inline bool 889 operator==(const __shared_ptr<_Tp1, _Lp>& __a, 890 const __shared_ptr<_Tp2, _Lp>& __b) 891 { return __a.get() == __b.get(); } 892 893 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 894 inline bool 895 operator!=(const __shared_ptr<_Tp1, _Lp>& __a, 896 const __shared_ptr<_Tp2, _Lp>& __b) 897 { return __a.get() != __b.get(); } 898 899 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 900 inline bool 901 operator<(const __shared_ptr<_Tp1, _Lp>& __a, 902 const __shared_ptr<_Tp2, _Lp>& __b) 903 { return __a.get() < __b.get(); } 904 905 template<typename _Sp> 906 struct _Sp_less : public binary_function<_Sp, _Sp, bool> 907 { 908 bool 909 operator()(const _Sp& __lhs, const _Sp& __rhs) const 910 { 911 return std::less<typename _Sp::element_type*>()(__lhs.get(), 912 __rhs.get()); 913 } 914 }; 915 916 template<typename _Tp, _Lock_policy _Lp> 917 struct less<__shared_ptr<_Tp, _Lp>> 918 : public _Sp_less<__shared_ptr<_Tp, _Lp>> 919 { }; 920 921 // XXX LessThanComparable<_Tp> concept should provide >, >= and <= 922 template<typename _Tp, _Lock_policy _Lp> 923 inline bool 924 operator>(const __shared_ptr<_Tp, _Lp>& __a, 925 const __shared_ptr<_Tp, _Lp>& __b) 926 { return __a.get() > __b.get(); } 927 928 template<typename _Tp, _Lock_policy _Lp> 929 inline bool 930 operator>=(const __shared_ptr<_Tp, _Lp>& __a, 931 const __shared_ptr<_Tp, _Lp>& __b) 932 { return __a.get() >= __b.get(); } 933 934 template<typename _Tp, _Lock_policy _Lp> 935 inline bool 936 operator<=(const __shared_ptr<_Tp, _Lp>& __a, 937 const __shared_ptr<_Tp, _Lp>& __b) 938 { return __a.get() <= __b.get(); } 939 940 // 2.2.3.8 shared_ptr specialized algorithms. 941 template<typename _Tp, _Lock_policy _Lp> 942 inline void 943 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) 944 { __a.swap(__b); } 945 946 template<typename _Tp, _Lock_policy _Lp> 947 inline void 948 swap(__shared_ptr<_Tp, _Lp>&& __a, __shared_ptr<_Tp, _Lp>& __b) 949 { __a.swap(__b); } 950 951 template<typename _Tp, _Lock_policy _Lp> 952 inline void 953 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>&& __b) 954 { __a.swap(__b); } 955 956 // 2.2.3.9 shared_ptr casts 957 /** @warning The seemingly equivalent 958 * <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code> 959 * will eventually result in undefined behaviour, 960 * attempting to delete the same object twice. 961 */ 962 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 963 inline __shared_ptr<_Tp, _Lp> 964 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 965 { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); } 966 967 /** @warning The seemingly equivalent 968 * <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code> 969 * will eventually result in undefined behaviour, 970 * attempting to delete the same object twice. 971 */ 972 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 973 inline __shared_ptr<_Tp, _Lp> 974 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 975 { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); } 976 977 /** @warning The seemingly equivalent 978 * <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code> 979 * will eventually result in undefined behaviour, 980 * attempting to delete the same object twice. 981 */ 982 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 983 inline __shared_ptr<_Tp, _Lp> 984 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 985 { 986 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get())) 987 return __shared_ptr<_Tp, _Lp>(__r, __p); 988 return __shared_ptr<_Tp, _Lp>(); 989 } 990 991 // 2.2.3.7 shared_ptr I/O 992 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> 993 std::basic_ostream<_Ch, _Tr>& 994 operator<<(std::basic_ostream<_Ch, _Tr>& __os, 995 const __shared_ptr<_Tp, _Lp>& __p) 996 { 997 __os << __p.get(); 998 return __os; 999 } 1000 1001 // 2.2.3.10 shared_ptr get_deleter (experimental) 1002 template<typename _Del, typename _Tp, _Lock_policy _Lp> 1003 inline _Del* 1004 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) 1005 { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); } 1006 1007 1008 template<typename _Tp, _Lock_policy _Lp> 1009 class __weak_ptr 1010 { 1011 public: 1012 typedef _Tp element_type; 1013 1014 __weak_ptr() 1015 : _M_ptr(0), _M_refcount() // never throws 1016 { } 1017 1018 // Generated copy constructor, assignment, destructor are fine. 1019 1020 // The "obvious" converting constructor implementation: 1021 // 1022 // template<typename _Tp1> 1023 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 1024 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 1025 // { } 1026 // 1027 // has a serious problem. 1028 // 1029 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 1030 // conversion may require access to *__r._M_ptr (virtual inheritance). 1031 // 1032 // It is not possible to avoid spurious access violations since 1033 // in multithreaded programs __r._M_ptr may be invalidated at any point. 1034 template<typename _Tp1> 1035 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 1036 : _M_refcount(__r._M_refcount) // never throws 1037 { 1038 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 1039 _M_ptr = __r.lock().get(); 1040 } 1041 1042 template<typename _Tp1> 1043 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 1044 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 1045 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 1046 1047 template<typename _Tp1> 1048 __weak_ptr& 1049 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws 1050 { 1051 _M_ptr = __r.lock().get(); 1052 _M_refcount = __r._M_refcount; 1053 return *this; 1054 } 1055 1056 template<typename _Tp1> 1057 __weak_ptr& 1058 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 1059 { 1060 _M_ptr = __r._M_ptr; 1061 _M_refcount = __r._M_refcount; 1062 return *this; 1063 } 1064 1065 __shared_ptr<_Tp, _Lp> 1066 lock() const // never throws 1067 { 1068#ifdef __GTHREADS 1069 // Optimization: avoid throw overhead. 1070 if (expired()) 1071 return __shared_ptr<element_type, _Lp>(); 1072 1073 __try 1074 { 1075 return __shared_ptr<element_type, _Lp>(*this); 1076 } 1077 __catch(const bad_weak_ptr&) 1078 { 1079 // Q: How can we get here? 1080 // A: Another thread may have invalidated r after the 1081 // use_count test above. 1082 return __shared_ptr<element_type, _Lp>(); 1083 } 1084 1085#else 1086 // Optimization: avoid try/catch overhead when single threaded. 1087 return expired() ? __shared_ptr<element_type, _Lp>() 1088 : __shared_ptr<element_type, _Lp>(*this); 1089 1090#endif 1091 } // XXX MT 1092 1093 long 1094 use_count() const // never throws 1095 { return _M_refcount._M_get_use_count(); } 1096 1097 bool 1098 expired() const // never throws 1099 { return _M_refcount._M_get_use_count() == 0; } 1100 1101 template<typename _Tp1> 1102 bool 1103 owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const 1104 { return _M_refcount._M_less(__rhs._M_refcount); } 1105 1106 template<typename _Tp1> 1107 bool 1108 owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const 1109 { return _M_refcount._M_less(__rhs._M_refcount); } 1110 1111 void 1112 reset() // never throws 1113 { __weak_ptr().swap(*this); } 1114 1115 void 1116 swap(__weak_ptr& __s) // never throws 1117 { 1118 std::swap(_M_ptr, __s._M_ptr); 1119 _M_refcount._M_swap(__s._M_refcount); 1120 } 1121 1122 // comparisons 1123 template<typename _Tp1> 1124 bool operator<(const __weak_ptr<_Tp1, _Lp>&) const = delete; 1125 template<typename _Tp1> 1126 bool operator<=(const __weak_ptr<_Tp1, _Lp>&) const = delete; 1127 template<typename _Tp1> 1128 bool operator>(const __weak_ptr<_Tp1, _Lp>&) const = delete; 1129 template<typename _Tp1> 1130 bool operator>=(const __weak_ptr<_Tp1, _Lp>&) const = delete; 1131 1132 private: 1133 // Used by __enable_shared_from_this. 1134 void 1135 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) 1136 { 1137 _M_ptr = __ptr; 1138 _M_refcount = __refcount; 1139 } 1140 1141 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 1142 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 1143 friend class __enable_shared_from_this<_Tp, _Lp>; 1144 friend class enable_shared_from_this<_Tp>; 1145 1146 _Tp* _M_ptr; // Contained pointer. 1147 __weak_count<_Lp> _M_refcount; // Reference counter. 1148 }; 1149 1150 // 20.8.13.3.7 weak_ptr specialized algorithms. 1151 template<typename _Tp, _Lock_policy _Lp> 1152 inline void 1153 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) 1154 { __a.swap(__b); } 1155 1156 /// owner_less 1157 template<typename _Tp> struct owner_less; 1158 1159 template<typename _Tp, typename _Tp1> 1160 struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool> 1161 { 1162 bool 1163 operator()(const _Tp& __lhs, const _Tp& __rhs) const 1164 { return __lhs.owner_before(__rhs); } 1165 bool 1166 operator()(const _Tp& __lhs, const _Tp1& __rhs) const 1167 { return __lhs.owner_before(__rhs); } 1168 bool 1169 operator()(const _Tp1& __lhs, const _Tp& __rhs) const 1170 { return __lhs.owner_before(__rhs); } 1171 }; 1172 1173 template<typename _Tp, _Lock_policy _Lp> 1174 struct owner_less<__shared_ptr<_Tp, _Lp>> 1175 : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>> 1176 { }; 1177 1178 template<typename _Tp, _Lock_policy _Lp> 1179 struct owner_less<__weak_ptr<_Tp, _Lp>> 1180 : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>> 1181 { 1182 }; 1183 1184 1185 template<typename _Tp, _Lock_policy _Lp> 1186 class __enable_shared_from_this 1187 { 1188 protected: 1189 __enable_shared_from_this() { } 1190 1191 __enable_shared_from_this(const __enable_shared_from_this&) { } 1192 1193 __enable_shared_from_this& 1194 operator=(const __enable_shared_from_this&) 1195 { return *this; } 1196 1197 ~__enable_shared_from_this() { } 1198 1199 public: 1200 __shared_ptr<_Tp, _Lp> 1201 shared_from_this() 1202 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 1203 1204 __shared_ptr<const _Tp, _Lp> 1205 shared_from_this() const 1206 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } 1207 1208 private: 1209 template<typename _Tp1> 1210 void 1211 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const 1212 { _M_weak_this._M_assign(__p, __n); } 1213 1214 template<typename _Tp1> 1215 friend void 1216 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, 1217 const __enable_shared_from_this* __pe, 1218 const _Tp1* __px) 1219 { 1220 if (__pe != 0) 1221 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 1222 } 1223 1224 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 1225 }; 1226 1227 /** 1228 * @brief A smart pointer with reference-counted copy semantics. 1229 * 1230 * The object pointed to is deleted when the last shared_ptr pointing to 1231 * it is destroyed or reset. 1232 */ 1233 template<typename _Tp> 1234 class shared_ptr 1235 : public __shared_ptr<_Tp> 1236 { 1237 public: 1238 shared_ptr() 1239 : __shared_ptr<_Tp>() { } 1240 1241 template<typename _Tp1> 1242 explicit 1243 shared_ptr(_Tp1* __p) 1244 : __shared_ptr<_Tp>(__p) { } 1245 1246 template<typename _Tp1, typename _Deleter> 1247 shared_ptr(_Tp1* __p, _Deleter __d) 1248 : __shared_ptr<_Tp>(__p, __d) { } 1249 1250 template<typename _Tp1, typename _Deleter, typename _Alloc> 1251 shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a) 1252 : __shared_ptr<_Tp>(__p, __d, __a) { } 1253 1254 // Aliasing constructor 1255 template<typename _Tp1> 1256 shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p) 1257 : __shared_ptr<_Tp>(__r, __p) { } 1258 1259 template<typename _Tp1> 1260 shared_ptr(const shared_ptr<_Tp1>& __r) 1261 : __shared_ptr<_Tp>(__r) { } 1262 1263 shared_ptr(shared_ptr&& __r) 1264 : __shared_ptr<_Tp>(std::move(__r)) { } 1265 1266 template<typename _Tp1> 1267 shared_ptr(shared_ptr<_Tp1>&& __r) 1268 : __shared_ptr<_Tp>(std::move(__r)) { } 1269 1270 template<typename _Tp1> 1271 explicit 1272 shared_ptr(const weak_ptr<_Tp1>& __r) 1273 : __shared_ptr<_Tp>(__r) { } 1274 1275#if _GLIBCXX_DEPRECATED 1276 template<typename _Tp1> 1277 explicit 1278 shared_ptr(std::auto_ptr<_Tp1>&& __r) 1279 : __shared_ptr<_Tp>(std::move(__r)) { } 1280#endif 1281 1282 template<typename _Tp1, typename _Del> 1283 explicit 1284 shared_ptr(const std::unique_ptr<_Tp1, _Del>&) = delete; 1285 1286 template<typename _Tp1, typename _Del> 1287 explicit 1288 shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r) 1289 : __shared_ptr<_Tp>(std::move(__r)) { } 1290 1291 template<typename _Tp1> 1292 shared_ptr& 1293 operator=(const shared_ptr<_Tp1>& __r) // never throws 1294 { 1295 this->__shared_ptr<_Tp>::operator=(__r); 1296 return *this; 1297 } 1298 1299#if _GLIBCXX_DEPRECATED 1300 template<typename _Tp1> 1301 shared_ptr& 1302 operator=(std::auto_ptr<_Tp1>&& __r) 1303 { 1304 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 1305 return *this; 1306 } 1307#endif 1308 1309 shared_ptr& 1310 operator=(shared_ptr&& __r) 1311 { 1312 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 1313 return *this; 1314 } 1315 1316 template<class _Tp1> 1317 shared_ptr& 1318 operator=(shared_ptr<_Tp1>&& __r) 1319 { 1320 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 1321 return *this; 1322 } 1323 1324 template<typename _Tp1, typename _Del> 1325 shared_ptr& 1326 operator=(const std::unique_ptr<_Tp1, _Del>& __r) = delete; 1327 1328 template<typename _Tp1, typename _Del> 1329 shared_ptr& 1330 operator=(std::unique_ptr<_Tp1, _Del>&& __r) 1331 { 1332 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 1333 return *this; 1334 } 1335 1336 private: 1337 // This constructor is non-standard, it is used by allocate_shared. 1338 template<typename _Alloc, typename... _Args> 1339 shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args) 1340 : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...) 1341 { } 1342 1343 template<typename _Tp1, typename _Alloc, typename... _Args> 1344 friend shared_ptr<_Tp1> 1345 allocate_shared(_Alloc __a, _Args&&... __args); 1346 }; 1347 1348 // 20.8.13.2.7 shared_ptr comparisons 1349 template<typename _Tp1, typename _Tp2> 1350 inline bool 1351 operator==(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b) 1352 { return __a.get() == __b.get(); } 1353 1354 template<typename _Tp1, typename _Tp2> 1355 inline bool 1356 operator!=(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b) 1357 { return __a.get() != __b.get(); } 1358 1359 template<typename _Tp1, typename _Tp2> 1360 inline bool 1361 operator<(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b) 1362 { return __a.get() < __b.get(); } 1363 1364 template<typename _Tp> 1365 struct less<shared_ptr<_Tp>> 1366 : public _Sp_less<shared_ptr<_Tp>> 1367 { }; 1368 1369 // 20.8.13.2.9 shared_ptr specialized algorithms. 1370 template<typename _Tp> 1371 inline void 1372 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) 1373 { __a.swap(__b); } 1374 1375 template<typename _Tp> 1376 inline void 1377 swap(shared_ptr<_Tp>&& __a, shared_ptr<_Tp>& __b) 1378 { __a.swap(__b); } 1379 1380 template<typename _Tp> 1381 inline void 1382 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>&& __b) 1383 { __a.swap(__b); } 1384 1385 // 20.8.13.2.10 shared_ptr casts. 1386 template<typename _Tp, typename _Tp1> 1387 inline shared_ptr<_Tp> 1388 static_pointer_cast(const shared_ptr<_Tp1>& __r) 1389 { return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); } 1390 1391 template<typename _Tp, typename _Tp1> 1392 inline shared_ptr<_Tp> 1393 const_pointer_cast(const shared_ptr<_Tp1>& __r) 1394 { return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); } 1395 1396 template<typename _Tp, typename _Tp1> 1397 inline shared_ptr<_Tp> 1398 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) 1399 { 1400 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get())) 1401 return shared_ptr<_Tp>(__r, __p); 1402 return shared_ptr<_Tp>(); 1403 } 1404 1405 1406 /** 1407 * @brief A smart pointer with weak semantics. 1408 * 1409 * With forwarding constructors and assignment operators. 1410 */ 1411 template<typename _Tp> 1412 class weak_ptr 1413 : public __weak_ptr<_Tp> 1414 { 1415 public: 1416 weak_ptr() 1417 : __weak_ptr<_Tp>() { } 1418 1419 template<typename _Tp1> 1420 weak_ptr(const weak_ptr<_Tp1>& __r) 1421 : __weak_ptr<_Tp>(__r) { } 1422 1423 template<typename _Tp1> 1424 weak_ptr(const shared_ptr<_Tp1>& __r) 1425 : __weak_ptr<_Tp>(__r) { } 1426 1427 template<typename _Tp1> 1428 weak_ptr& 1429 operator=(const weak_ptr<_Tp1>& __r) // never throws 1430 { 1431 this->__weak_ptr<_Tp>::operator=(__r); 1432 return *this; 1433 } 1434 1435 template<typename _Tp1> 1436 weak_ptr& 1437 operator=(const shared_ptr<_Tp1>& __r) // never throws 1438 { 1439 this->__weak_ptr<_Tp>::operator=(__r); 1440 return *this; 1441 } 1442 1443 shared_ptr<_Tp> 1444 lock() const // never throws 1445 { 1446#ifdef __GTHREADS 1447 if (this->expired()) 1448 return shared_ptr<_Tp>(); 1449 1450 __try 1451 { 1452 return shared_ptr<_Tp>(*this); 1453 } 1454 __catch(const bad_weak_ptr&) 1455 { 1456 return shared_ptr<_Tp>(); 1457 } 1458#else 1459 return this->expired() ? shared_ptr<_Tp>() 1460 : shared_ptr<_Tp>(*this); 1461#endif 1462 } 1463 1464 // comparisons 1465 template<typename _Tp1> 1466 bool operator<(const weak_ptr<_Tp1>&) const = delete; 1467 template<typename _Tp1> 1468 bool operator<=(const weak_ptr<_Tp1>&) const = delete; 1469 template<typename _Tp1> 1470 bool operator>(const weak_ptr<_Tp1>&) const = delete; 1471 template<typename _Tp1> 1472 bool operator>=(const weak_ptr<_Tp1>&) const = delete; 1473 }; 1474 1475 // 20.8.13.3.7 weak_ptr specialized algorithms. 1476 template<typename _Tp> 1477 inline void 1478 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) 1479 { __a.swap(__b); } 1480 1481 /// owner_less 1482 template<typename _Tp> 1483 struct owner_less<shared_ptr<_Tp>> 1484 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> 1485 { }; 1486 1487 template<typename _Tp> 1488 struct owner_less<weak_ptr<_Tp>> 1489 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> 1490 { }; 1491 1492 /** 1493 * @brief Base class allowing use of member function shared_from_this. 1494 */ 1495 template<typename _Tp> 1496 class enable_shared_from_this 1497 { 1498 protected: 1499 enable_shared_from_this() { } 1500 1501 enable_shared_from_this(const enable_shared_from_this&) { } 1502 1503 enable_shared_from_this& 1504 operator=(const enable_shared_from_this&) 1505 { return *this; } 1506 1507 ~enable_shared_from_this() { } 1508 1509 public: 1510 shared_ptr<_Tp> 1511 shared_from_this() 1512 { return shared_ptr<_Tp>(this->_M_weak_this); } 1513 1514 shared_ptr<const _Tp> 1515 shared_from_this() const 1516 { return shared_ptr<const _Tp>(this->_M_weak_this); } 1517 1518 private: 1519 template<typename _Tp1> 1520 void 1521 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const 1522 { _M_weak_this._M_assign(__p, __n); } 1523 1524 template<typename _Tp1> 1525 friend void 1526 __enable_shared_from_this_helper(const __shared_count<>& __pn, 1527 const enable_shared_from_this* __pe, 1528 const _Tp1* __px) 1529 { 1530 if (__pe != 0) 1531 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 1532 } 1533 1534 mutable weak_ptr<_Tp> _M_weak_this; 1535 }; 1536 1537 template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args> 1538 inline __shared_ptr<_Tp, _Lp> 1539 __allocate_shared(_Alloc __a, _Args&&... __args) 1540 { 1541 return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), 1542 std::forward<_Alloc>(__a), std::forward<_Args>(__args)...); 1543 } 1544 1545 template<typename _Tp, _Lock_policy _Lp, typename... _Args> 1546 inline __shared_ptr<_Tp, _Lp> 1547 __make_shared(_Args&&... __args) 1548 { 1549 typedef typename std::remove_const<_Tp>::type _Tp_nc; 1550 return __allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(), 1551 std::forward<_Args>(__args)...); 1552 } 1553 1554 /** @brief Create an object that is owned by a shared_ptr. 1555 * @param __a An allocator. 1556 * @param __args Arguments for the @a _Tp object's constructor. 1557 * @return A shared_ptr that owns the newly created object. 1558 * @throw An exception thrown from @a _Alloc::allocate or from the 1559 * constructor of @a _Tp. 1560 * 1561 * A copy of @a __a will be used to allocate memory for the shared_ptr 1562 * and the new object. 1563 */ 1564 template<typename _Tp, typename _Alloc, typename... _Args> 1565 inline shared_ptr<_Tp> 1566 allocate_shared(_Alloc __a, _Args&&... __args) 1567 { 1568 return shared_ptr<_Tp>(_Sp_make_shared_tag(), std::forward<_Alloc>(__a), 1569 std::forward<_Args>(__args)...); 1570 } 1571 1572 /** @brief Create an object that is owned by a shared_ptr. 1573 * @param __args Arguments for the @a _Tp object's constructor. 1574 * @return A shared_ptr that owns the newly created object. 1575 * @throw std::bad_alloc, or an exception thrown from the 1576 * constructor of @a _Tp. 1577 */ 1578 template<typename _Tp, typename... _Args> 1579 inline shared_ptr<_Tp> 1580 make_shared(_Args&&... __args) 1581 { 1582 typedef typename std::remove_const<_Tp>::type _Tp_nc; 1583 return allocate_shared<_Tp>(std::allocator<_Tp_nc>(), 1584 std::forward<_Args>(__args)...); 1585 } 1586 1587 // @} group pointer_abstractions 1588 1589_GLIBCXX_END_NAMESPACE 1590 1591#endif // _SHARED_PTR_H 1592