1 // shared_ptr and weak_ptr implementation -*- C++ -*- 2 3 // Copyright (C) 2007, 2008, 2009, 2010, 2011 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.h 45 * This is an internal header file, included by other library headers. 46 * Do not attempt to use it directly. @headername{memory} 47 */ 48 49 #ifndef _SHARED_PTR_H 50 #define _SHARED_PTR_H 1 51 52 #include <bits/shared_ptr_base.h> 53 54 namespace std _GLIBCXX_VISIBILITY(default) 55 { 56 _GLIBCXX_BEGIN_NAMESPACE_VERSION 57 58 /** 59 * @addtogroup pointer_abstractions 60 * @{ 61 */ 62 63 /// 2.2.3.7 shared_ptr I/O 64 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> 65 inline std::basic_ostream<_Ch, _Tr>& 66 operator<<(std::basic_ostream<_Ch, _Tr>& __os, 67 const __shared_ptr<_Tp, _Lp>& __p) 68 { 69 __os << __p.get(); 70 return __os; 71 } 72 73 /// 2.2.3.10 shared_ptr get_deleter (experimental) 74 template<typename _Del, typename _Tp, _Lock_policy _Lp> 75 inline _Del* 76 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept 77 { 78 #ifdef __GXX_RTTI 79 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 80 #else 81 return 0; 82 #endif 83 } 84 85 86 /** 87 * @brief A smart pointer with reference-counted copy semantics. 88 * 89 * The object pointed to is deleted when the last shared_ptr pointing to 90 * it is destroyed or reset. 91 */ 92 template<typename _Tp> 93 class shared_ptr : public __shared_ptr<_Tp> 94 { 95 public: 96 /** 97 * @brief Construct an empty %shared_ptr. 98 * @post use_count()==0 && get()==0 99 */ 100 constexpr shared_ptr() noexcept 101 : __shared_ptr<_Tp>() { } 102 103 shared_ptr(const shared_ptr&) noexcept = default; 104 105 /** 106 * @brief Construct a %shared_ptr that owns the pointer @a __p. 107 * @param __p A pointer that is convertible to element_type*. 108 * @post use_count() == 1 && get() == __p 109 * @throw std::bad_alloc, in which case @c delete @a __p is called. 110 */ 111 template<typename _Tp1> 112 explicit shared_ptr(_Tp1* __p) 113 : __shared_ptr<_Tp>(__p) { } 114 115 /** 116 * @brief Construct a %shared_ptr that owns the pointer @a __p 117 * and the deleter @a __d. 118 * @param __p A pointer. 119 * @param __d A deleter. 120 * @post use_count() == 1 && get() == __p 121 * @throw std::bad_alloc, in which case @a __d(__p) is called. 122 * 123 * Requirements: _Deleter's copy constructor and destructor must 124 * not throw 125 * 126 * __shared_ptr will release __p by calling __d(__p) 127 */ 128 template<typename _Tp1, typename _Deleter> 129 shared_ptr(_Tp1* __p, _Deleter __d) 130 : __shared_ptr<_Tp>(__p, __d) { } 131 132 /** 133 * @brief Construct a %shared_ptr that owns a null pointer 134 * and the deleter @a __d. 135 * @param __p A null pointer constant. 136 * @param __d A deleter. 137 * @post use_count() == 1 && get() == __p 138 * @throw std::bad_alloc, in which case @a __d(__p) is called. 139 * 140 * Requirements: _Deleter's copy constructor and destructor must 141 * not throw 142 * 143 * The last owner will call __d(__p) 144 */ 145 template<typename _Deleter> 146 shared_ptr(nullptr_t __p, _Deleter __d) 147 : __shared_ptr<_Tp>(__p, __d) { } 148 149 /** 150 * @brief Construct a %shared_ptr that owns the pointer @a __p 151 * and the deleter @a __d. 152 * @param __p A pointer. 153 * @param __d A deleter. 154 * @param __a An allocator. 155 * @post use_count() == 1 && get() == __p 156 * @throw std::bad_alloc, in which case @a __d(__p) is called. 157 * 158 * Requirements: _Deleter's copy constructor and destructor must 159 * not throw _Alloc's copy constructor and destructor must not 160 * throw. 161 * 162 * __shared_ptr will release __p by calling __d(__p) 163 */ 164 template<typename _Tp1, typename _Deleter, typename _Alloc> 165 shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) 166 : __shared_ptr<_Tp>(__p, __d, std::move(__a)) { } 167 168 /** 169 * @brief Construct a %shared_ptr that owns a null pointer 170 * and the deleter @a __d. 171 * @param __p A null pointer constant. 172 * @param __d A deleter. 173 * @param __a An allocator. 174 * @post use_count() == 1 && get() == __p 175 * @throw std::bad_alloc, in which case @a __d(__p) is called. 176 * 177 * Requirements: _Deleter's copy constructor and destructor must 178 * not throw _Alloc's copy constructor and destructor must not 179 * throw. 180 * 181 * The last owner will call __d(__p) 182 */ 183 template<typename _Deleter, typename _Alloc> 184 shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 185 : __shared_ptr<_Tp>(__p, __d, std::move(__a)) { } 186 187 // Aliasing constructor 188 189 /** 190 * @brief Constructs a %shared_ptr instance that stores @a __p 191 * and shares ownership with @a __r. 192 * @param __r A %shared_ptr. 193 * @param __p A pointer that will remain valid while @a *__r is valid. 194 * @post get() == __p && use_count() == __r.use_count() 195 * 196 * This can be used to construct a @c shared_ptr to a sub-object 197 * of an object managed by an existing @c shared_ptr. 198 * 199 * @code 200 * shared_ptr< pair<int,int> > pii(new pair<int,int>()); 201 * shared_ptr<int> pi(pii, &pii->first); 202 * assert(pii.use_count() == 2); 203 * @endcode 204 */ 205 template<typename _Tp1> 206 shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p) noexcept 207 : __shared_ptr<_Tp>(__r, __p) { } 208 209 /** 210 * @brief If @a __r is empty, constructs an empty %shared_ptr; 211 * otherwise construct a %shared_ptr that shares ownership 212 * with @a __r. 213 * @param __r A %shared_ptr. 214 * @post get() == __r.get() && use_count() == __r.use_count() 215 */ 216 template<typename _Tp1, typename = typename 217 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 218 shared_ptr(const shared_ptr<_Tp1>& __r) noexcept 219 : __shared_ptr<_Tp>(__r) { } 220 221 /** 222 * @brief Move-constructs a %shared_ptr instance from @a __r. 223 * @param __r A %shared_ptr rvalue. 224 * @post *this contains the old value of @a __r, @a __r is empty. 225 */ 226 shared_ptr(shared_ptr&& __r) noexcept 227 : __shared_ptr<_Tp>(std::move(__r)) { } 228 229 /** 230 * @brief Move-constructs a %shared_ptr instance from @a __r. 231 * @param __r A %shared_ptr rvalue. 232 * @post *this contains the old value of @a __r, @a __r is empty. 233 */ 234 template<typename _Tp1, typename = typename 235 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 236 shared_ptr(shared_ptr<_Tp1>&& __r) noexcept 237 : __shared_ptr<_Tp>(std::move(__r)) { } 238 239 /** 240 * @brief Constructs a %shared_ptr that shares ownership with @a __r 241 * and stores a copy of the pointer stored in @a __r. 242 * @param __r A weak_ptr. 243 * @post use_count() == __r.use_count() 244 * @throw bad_weak_ptr when __r.expired(), 245 * in which case the constructor has no effect. 246 */ 247 template<typename _Tp1> 248 explicit shared_ptr(const weak_ptr<_Tp1>& __r) 249 : __shared_ptr<_Tp>(__r) { } 250 251 #if _GLIBCXX_USE_DEPRECATED 252 template<typename _Tp1> 253 shared_ptr(std::auto_ptr<_Tp1>&& __r) 254 : __shared_ptr<_Tp>(std::move(__r)) { } 255 #endif 256 257 template<typename _Tp1, typename _Del> 258 shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r) 259 : __shared_ptr<_Tp>(std::move(__r)) { } 260 261 /** 262 * @brief Construct an empty %shared_ptr. 263 * @param __p A null pointer constant. 264 * @post use_count() == 0 && get() == nullptr 265 */ 266 constexpr shared_ptr(nullptr_t __p) noexcept 267 : __shared_ptr<_Tp>(__p) { } 268 269 shared_ptr& operator=(const shared_ptr&) noexcept = default; 270 271 template<typename _Tp1> 272 shared_ptr& 273 operator=(const shared_ptr<_Tp1>& __r) noexcept 274 { 275 this->__shared_ptr<_Tp>::operator=(__r); 276 return *this; 277 } 278 279 #if _GLIBCXX_USE_DEPRECATED 280 template<typename _Tp1> 281 shared_ptr& 282 operator=(std::auto_ptr<_Tp1>&& __r) 283 { 284 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 285 return *this; 286 } 287 #endif 288 289 shared_ptr& 290 operator=(shared_ptr&& __r) noexcept 291 { 292 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 293 return *this; 294 } 295 296 template<class _Tp1> 297 shared_ptr& 298 operator=(shared_ptr<_Tp1>&& __r) noexcept 299 { 300 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 301 return *this; 302 } 303 304 template<typename _Tp1, typename _Del> 305 shared_ptr& 306 operator=(std::unique_ptr<_Tp1, _Del>&& __r) 307 { 308 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 309 return *this; 310 } 311 312 private: 313 // This constructor is non-standard, it is used by allocate_shared. 314 template<typename _Alloc, typename... _Args> 315 shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 316 _Args&&... __args) 317 : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...) 318 { } 319 320 template<typename _Tp1, typename _Alloc, typename... _Args> 321 friend shared_ptr<_Tp1> 322 allocate_shared(const _Alloc& __a, _Args&&... __args); 323 }; 324 325 // 20.8.13.2.7 shared_ptr comparisons 326 template<typename _Tp1, typename _Tp2> 327 inline bool 328 operator==(const shared_ptr<_Tp1>& __a, 329 const shared_ptr<_Tp2>& __b) noexcept 330 { return __a.get() == __b.get(); } 331 332 template<typename _Tp> 333 inline bool 334 operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 335 { return !__a; } 336 337 template<typename _Tp> 338 inline bool 339 operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 340 { return !__a; } 341 342 template<typename _Tp1, typename _Tp2> 343 inline bool 344 operator!=(const shared_ptr<_Tp1>& __a, 345 const shared_ptr<_Tp2>& __b) noexcept 346 { return __a.get() != __b.get(); } 347 348 template<typename _Tp> 349 inline bool 350 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 351 { return (bool)__a; } 352 353 template<typename _Tp> 354 inline bool 355 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 356 { return (bool)__a; } 357 358 template<typename _Tp1, typename _Tp2> 359 inline bool 360 operator<(const shared_ptr<_Tp1>& __a, 361 const shared_ptr<_Tp2>& __b) noexcept 362 { 363 typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT; 364 return std::less<_CT>()(__a.get(), __b.get()); 365 } 366 367 template<typename _Tp> 368 inline bool 369 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 370 { return std::less<_Tp*>()(__a.get(), nullptr); } 371 372 template<typename _Tp> 373 inline bool 374 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 375 { return std::less<_Tp*>()(nullptr, __a.get()); } 376 377 template<typename _Tp1, typename _Tp2> 378 inline bool 379 operator<=(const shared_ptr<_Tp1>& __a, 380 const shared_ptr<_Tp2>& __b) noexcept 381 { return !(__b < __a); } 382 383 template<typename _Tp> 384 inline bool 385 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 386 { return !(nullptr < __a); } 387 388 template<typename _Tp> 389 inline bool 390 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 391 { return !(__a < nullptr); } 392 393 template<typename _Tp1, typename _Tp2> 394 inline bool 395 operator>(const shared_ptr<_Tp1>& __a, 396 const shared_ptr<_Tp2>& __b) noexcept 397 { return (__b < __a); } 398 399 template<typename _Tp> 400 inline bool 401 operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 402 { return std::less<_Tp*>()(nullptr, __a.get()); } 403 404 template<typename _Tp> 405 inline bool 406 operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 407 { return std::less<_Tp*>()(__a.get(), nullptr); } 408 409 template<typename _Tp1, typename _Tp2> 410 inline bool 411 operator>=(const shared_ptr<_Tp1>& __a, 412 const shared_ptr<_Tp2>& __b) noexcept 413 { return !(__a < __b); } 414 415 template<typename _Tp> 416 inline bool 417 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 418 { return !(__a < nullptr); } 419 420 template<typename _Tp> 421 inline bool 422 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 423 { return !(nullptr < __a); } 424 425 template<typename _Tp> 426 struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> 427 { }; 428 429 // 20.8.13.2.9 shared_ptr specialized algorithms. 430 template<typename _Tp> 431 inline void 432 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept 433 { __a.swap(__b); } 434 435 // 20.8.13.2.10 shared_ptr casts. 436 template<typename _Tp, typename _Tp1> 437 inline shared_ptr<_Tp> 438 static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept 439 { return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); } 440 441 template<typename _Tp, typename _Tp1> 442 inline shared_ptr<_Tp> 443 const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept 444 { return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); } 445 446 template<typename _Tp, typename _Tp1> 447 inline shared_ptr<_Tp> 448 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept 449 { 450 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get())) 451 return shared_ptr<_Tp>(__r, __p); 452 return shared_ptr<_Tp>(); 453 } 454 455 456 /** 457 * @brief A smart pointer with weak semantics. 458 * 459 * With forwarding constructors and assignment operators. 460 */ 461 template<typename _Tp> 462 class weak_ptr : public __weak_ptr<_Tp> 463 { 464 public: 465 constexpr weak_ptr() noexcept 466 : __weak_ptr<_Tp>() { } 467 468 template<typename _Tp1, typename = typename 469 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 470 weak_ptr(const weak_ptr<_Tp1>& __r) noexcept 471 : __weak_ptr<_Tp>(__r) { } 472 473 template<typename _Tp1, typename = typename 474 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 475 weak_ptr(const shared_ptr<_Tp1>& __r) noexcept 476 : __weak_ptr<_Tp>(__r) { } 477 478 template<typename _Tp1> 479 weak_ptr& 480 operator=(const weak_ptr<_Tp1>& __r) noexcept 481 { 482 this->__weak_ptr<_Tp>::operator=(__r); 483 return *this; 484 } 485 486 template<typename _Tp1> 487 weak_ptr& 488 operator=(const shared_ptr<_Tp1>& __r) noexcept 489 { 490 this->__weak_ptr<_Tp>::operator=(__r); 491 return *this; 492 } 493 494 shared_ptr<_Tp> 495 lock() const noexcept 496 { 497 #ifdef __GTHREADS 498 if (this->expired()) 499 return shared_ptr<_Tp>(); 500 501 __try 502 { 503 return shared_ptr<_Tp>(*this); 504 } 505 __catch(const bad_weak_ptr&) 506 { 507 return shared_ptr<_Tp>(); 508 } 509 #else 510 return this->expired() ? shared_ptr<_Tp>() : shared_ptr<_Tp>(*this); 511 #endif 512 } 513 }; 514 515 // 20.8.13.3.7 weak_ptr specialized algorithms. 516 template<typename _Tp> 517 inline void 518 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept 519 { __a.swap(__b); } 520 521 522 /// Primary template owner_less 523 template<typename _Tp> 524 struct owner_less; 525 526 /// Partial specialization of owner_less for shared_ptr. 527 template<typename _Tp> 528 struct owner_less<shared_ptr<_Tp>> 529 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> 530 { }; 531 532 /// Partial specialization of owner_less for weak_ptr. 533 template<typename _Tp> 534 struct owner_less<weak_ptr<_Tp>> 535 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> 536 { }; 537 538 /** 539 * @brief Base class allowing use of member function shared_from_this. 540 */ 541 template<typename _Tp> 542 class enable_shared_from_this 543 { 544 protected: 545 constexpr enable_shared_from_this() noexcept { } 546 547 enable_shared_from_this(const enable_shared_from_this&) noexcept { } 548 549 enable_shared_from_this& 550 operator=(const enable_shared_from_this&) noexcept 551 { return *this; } 552 553 ~enable_shared_from_this() { } 554 555 public: 556 shared_ptr<_Tp> 557 shared_from_this() 558 { return shared_ptr<_Tp>(this->_M_weak_this); } 559 560 shared_ptr<const _Tp> 561 shared_from_this() const 562 { return shared_ptr<const _Tp>(this->_M_weak_this); } 563 564 private: 565 template<typename _Tp1> 566 void 567 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept 568 { _M_weak_this._M_assign(__p, __n); } 569 570 template<typename _Tp1> 571 friend void 572 __enable_shared_from_this_helper(const __shared_count<>& __pn, 573 const enable_shared_from_this* __pe, 574 const _Tp1* __px) noexcept 575 { 576 if (__pe != 0) 577 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 578 } 579 580 mutable weak_ptr<_Tp> _M_weak_this; 581 }; 582 583 /** 584 * @brief Create an object that is owned by a shared_ptr. 585 * @param __a An allocator. 586 * @param __args Arguments for the @a _Tp object's constructor. 587 * @return A shared_ptr that owns the newly created object. 588 * @throw An exception thrown from @a _Alloc::allocate or from the 589 * constructor of @a _Tp. 590 * 591 * A copy of @a __a will be used to allocate memory for the shared_ptr 592 * and the new object. 593 */ 594 template<typename _Tp, typename _Alloc, typename... _Args> 595 inline shared_ptr<_Tp> 596 allocate_shared(const _Alloc& __a, _Args&&... __args) 597 { 598 return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a, 599 std::forward<_Args>(__args)...); 600 } 601 602 /** 603 * @brief Create an object that is owned by a shared_ptr. 604 * @param __args Arguments for the @a _Tp object's constructor. 605 * @return A shared_ptr that owns the newly created object. 606 * @throw std::bad_alloc, or an exception thrown from the 607 * constructor of @a _Tp. 608 */ 609 template<typename _Tp, typename... _Args> 610 inline shared_ptr<_Tp> 611 make_shared(_Args&&... __args) 612 { 613 typedef typename std::remove_const<_Tp>::type _Tp_nc; 614 return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), 615 std::forward<_Args>(__args)...); 616 } 617 618 /// std::hash specialization for shared_ptr. 619 template<typename _Tp> 620 struct hash<shared_ptr<_Tp>> 621 : public __hash_base<size_t, shared_ptr<_Tp>> 622 { 623 size_t 624 operator()(const shared_ptr<_Tp>& __s) const noexcept 625 { return std::hash<_Tp*>()(__s.get()); } 626 }; 627 628 // @} group pointer_abstractions 629 630 _GLIBCXX_END_NAMESPACE_VERSION 631 } // namespace 632 633 #endif // _SHARED_PTR_H 634