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 54namespace 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) 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() 101 : __shared_ptr<_Tp>() { } 102 103 shared_ptr(const shared_ptr&) = default; // never throws 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) 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) 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) 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) 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) 267 : __shared_ptr<_Tp>(__p) { } 268 269 shared_ptr& operator=(const shared_ptr&) = default; 270 271 template<typename _Tp1> 272 shared_ptr& 273 operator=(const shared_ptr<_Tp1>& __r) // never throws 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) 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) 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, const shared_ptr<_Tp2>& __b) 329 { return __a.get() == __b.get(); } 330 331 template<typename _Tp> 332 inline bool 333 operator==(const shared_ptr<_Tp>& __a, nullptr_t) 334 { return __a.get() == nullptr; } 335 336 template<typename _Tp> 337 inline bool 338 operator==(nullptr_t, const shared_ptr<_Tp>& __b) 339 { return nullptr == __b.get(); } 340 341 template<typename _Tp1, typename _Tp2> 342 inline bool 343 operator!=(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b) 344 { return __a.get() != __b.get(); } 345 346 template<typename _Tp> 347 inline bool 348 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) 349 { return __a.get() != nullptr; } 350 351 template<typename _Tp> 352 inline bool 353 operator!=(nullptr_t, const shared_ptr<_Tp>& __b) 354 { return nullptr != __b.get(); } 355 356 template<typename _Tp1, typename _Tp2> 357 inline bool 358 operator<(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b) 359 { return __a.get() < __b.get(); } 360 361 template<typename _Tp> 362 struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> 363 { }; 364 365 // 20.8.13.2.9 shared_ptr specialized algorithms. 366 template<typename _Tp> 367 inline void 368 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) 369 { __a.swap(__b); } 370 371 // 20.8.13.2.10 shared_ptr casts. 372 template<typename _Tp, typename _Tp1> 373 inline shared_ptr<_Tp> 374 static_pointer_cast(const shared_ptr<_Tp1>& __r) 375 { return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); } 376 377 template<typename _Tp, typename _Tp1> 378 inline shared_ptr<_Tp> 379 const_pointer_cast(const shared_ptr<_Tp1>& __r) 380 { return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); } 381 382 template<typename _Tp, typename _Tp1> 383 inline shared_ptr<_Tp> 384 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) 385 { 386 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get())) 387 return shared_ptr<_Tp>(__r, __p); 388 return shared_ptr<_Tp>(); 389 } 390 391 392 /** 393 * @brief A smart pointer with weak semantics. 394 * 395 * With forwarding constructors and assignment operators. 396 */ 397 template<typename _Tp> 398 class weak_ptr : public __weak_ptr<_Tp> 399 { 400 public: 401 constexpr weak_ptr() 402 : __weak_ptr<_Tp>() { } 403 404 template<typename _Tp1, typename = typename 405 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 406 weak_ptr(const weak_ptr<_Tp1>& __r) 407 : __weak_ptr<_Tp>(__r) { } 408 409 template<typename _Tp1, typename = typename 410 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 411 weak_ptr(const shared_ptr<_Tp1>& __r) 412 : __weak_ptr<_Tp>(__r) { } 413 414 template<typename _Tp1> 415 weak_ptr& 416 operator=(const weak_ptr<_Tp1>& __r) // never throws 417 { 418 this->__weak_ptr<_Tp>::operator=(__r); 419 return *this; 420 } 421 422 template<typename _Tp1> 423 weak_ptr& 424 operator=(const shared_ptr<_Tp1>& __r) // never throws 425 { 426 this->__weak_ptr<_Tp>::operator=(__r); 427 return *this; 428 } 429 430 shared_ptr<_Tp> 431 lock() const // never throws 432 { 433#ifdef __GTHREADS 434 if (this->expired()) 435 return shared_ptr<_Tp>(); 436 437 __try 438 { 439 return shared_ptr<_Tp>(*this); 440 } 441 __catch(const bad_weak_ptr&) 442 { 443 return shared_ptr<_Tp>(); 444 } 445#else 446 return this->expired() ? shared_ptr<_Tp>() : shared_ptr<_Tp>(*this); 447#endif 448 } 449 }; 450 451 // 20.8.13.3.7 weak_ptr specialized algorithms. 452 template<typename _Tp> 453 inline void 454 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) 455 { __a.swap(__b); } 456 457 458 /// Primary template owner_less 459 template<typename _Tp> 460 struct owner_less; 461 462 /// Partial specialization of owner_less for shared_ptr. 463 template<typename _Tp> 464 struct owner_less<shared_ptr<_Tp>> 465 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> 466 { }; 467 468 /// Partial specialization of owner_less for weak_ptr. 469 template<typename _Tp> 470 struct owner_less<weak_ptr<_Tp>> 471 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> 472 { }; 473 474 /** 475 * @brief Base class allowing use of member function shared_from_this. 476 */ 477 template<typename _Tp> 478 class enable_shared_from_this 479 { 480 protected: 481 constexpr enable_shared_from_this() { } 482 483 enable_shared_from_this(const enable_shared_from_this&) { } 484 485 enable_shared_from_this& 486 operator=(const enable_shared_from_this&) 487 { return *this; } 488 489 ~enable_shared_from_this() { } 490 491 public: 492 shared_ptr<_Tp> 493 shared_from_this() 494 { return shared_ptr<_Tp>(this->_M_weak_this); } 495 496 shared_ptr<const _Tp> 497 shared_from_this() const 498 { return shared_ptr<const _Tp>(this->_M_weak_this); } 499 500 private: 501 template<typename _Tp1> 502 void 503 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const 504 { _M_weak_this._M_assign(__p, __n); } 505 506 template<typename _Tp1> 507 friend void 508 __enable_shared_from_this_helper(const __shared_count<>& __pn, 509 const enable_shared_from_this* __pe, 510 const _Tp1* __px) 511 { 512 if (__pe != 0) 513 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 514 } 515 516 mutable weak_ptr<_Tp> _M_weak_this; 517 }; 518 519 /** 520 * @brief Create an object that is owned by a shared_ptr. 521 * @param __a An allocator. 522 * @param __args Arguments for the @a _Tp object's constructor. 523 * @return A shared_ptr that owns the newly created object. 524 * @throw An exception thrown from @a _Alloc::allocate or from the 525 * constructor of @a _Tp. 526 * 527 * A copy of @a __a will be used to allocate memory for the shared_ptr 528 * and the new object. 529 */ 530 template<typename _Tp, typename _Alloc, typename... _Args> 531 inline shared_ptr<_Tp> 532 allocate_shared(const _Alloc& __a, _Args&&... __args) 533 { 534 return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a, 535 std::forward<_Args>(__args)...); 536 } 537 538 /** 539 * @brief Create an object that is owned by a shared_ptr. 540 * @param __args Arguments for the @a _Tp object's constructor. 541 * @return A shared_ptr that owns the newly created object. 542 * @throw std::bad_alloc, or an exception thrown from the 543 * constructor of @a _Tp. 544 */ 545 template<typename _Tp, typename... _Args> 546 inline shared_ptr<_Tp> 547 make_shared(_Args&&... __args) 548 { 549 typedef typename std::remove_const<_Tp>::type _Tp_nc; 550 return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), 551 std::forward<_Args>(__args)...); 552 } 553 554 /// std::hash specialization for shared_ptr. 555 template<typename _Tp> 556 struct hash<shared_ptr<_Tp>> 557 : public std::unary_function<shared_ptr<_Tp>, size_t> 558 { 559 size_t 560 operator()(const shared_ptr<_Tp>& __s) const noexcept 561 { return std::hash<_Tp*>()(__s.get()); } 562 }; 563 564 // @} group pointer_abstractions 565 566_GLIBCXX_END_NAMESPACE_VERSION 567} // namespace 568 569#endif // _SHARED_PTR_H 570