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