1 // shared_ptr and weak_ptr implementation -*- C++ -*- 2 3 // Copyright (C) 2007-2018 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 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 /// 20.7.2.2.11 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 template<typename _Del, typename _Tp, _Lock_policy _Lp> 74 inline _Del* 75 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept 76 { 77 #if __cpp_rtti 78 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 79 #else 80 return 0; 81 #endif 82 } 83 84 /// 20.7.2.2.10 shared_ptr get_deleter 85 template<typename _Del, typename _Tp> 86 inline _Del* 87 get_deleter(const shared_ptr<_Tp>& __p) noexcept 88 { 89 #if __cpp_rtti 90 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 91 #else 92 return 0; 93 #endif 94 } 95 96 /** 97 * @brief A smart pointer with reference-counted copy semantics. 98 * 99 * The object pointed to is deleted when the last shared_ptr pointing to 100 * it is destroyed or reset. 101 */ 102 template<typename _Tp> 103 class shared_ptr : public __shared_ptr<_Tp> 104 { 105 template<typename... _Args> 106 using _Constructible = typename enable_if< 107 is_constructible<__shared_ptr<_Tp>, _Args...>::value 108 >::type; 109 110 template<typename _Arg> 111 using _Assignable = typename enable_if< 112 is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr& 113 >::type; 114 115 public: 116 117 using element_type = typename __shared_ptr<_Tp>::element_type; 118 119 #if __cplusplus > 201402L 120 # define __cpp_lib_shared_ptr_weak_type 201606 121 using weak_type = weak_ptr<_Tp>; 122 #endif 123 /** 124 * @brief Construct an empty %shared_ptr. 125 * @post use_count()==0 && get()==0 126 */ 127 constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { } 128 129 shared_ptr(const shared_ptr&) noexcept = default; 130 131 /** 132 * @brief Construct a %shared_ptr that owns the pointer @a __p. 133 * @param __p A pointer that is convertible to element_type*. 134 * @post use_count() == 1 && get() == __p 135 * @throw std::bad_alloc, in which case @c delete @a __p is called. 136 */ 137 template<typename _Yp, typename = _Constructible<_Yp*>> 138 explicit 139 shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { } 140 141 /** 142 * @brief Construct a %shared_ptr that owns the pointer @a __p 143 * and the deleter @a __d. 144 * @param __p A pointer. 145 * @param __d A deleter. 146 * @post use_count() == 1 && get() == __p 147 * @throw std::bad_alloc, in which case @a __d(__p) is called. 148 * 149 * Requirements: _Deleter's copy constructor and destructor must 150 * not throw 151 * 152 * __shared_ptr will release __p by calling __d(__p) 153 */ 154 template<typename _Yp, typename _Deleter, 155 typename = _Constructible<_Yp*, _Deleter>> 156 shared_ptr(_Yp* __p, _Deleter __d) 157 : __shared_ptr<_Tp>(__p, std::move(__d)) { } 158 159 /** 160 * @brief Construct a %shared_ptr that owns a null pointer 161 * and the deleter @a __d. 162 * @param __p A null pointer constant. 163 * @param __d A deleter. 164 * @post use_count() == 1 && get() == __p 165 * @throw std::bad_alloc, in which case @a __d(__p) is called. 166 * 167 * Requirements: _Deleter's copy constructor and destructor must 168 * not throw 169 * 170 * The last owner will call __d(__p) 171 */ 172 template<typename _Deleter> 173 shared_ptr(nullptr_t __p, _Deleter __d) 174 : __shared_ptr<_Tp>(__p, std::move(__d)) { } 175 176 /** 177 * @brief Construct a %shared_ptr that owns the pointer @a __p 178 * and the deleter @a __d. 179 * @param __p A pointer. 180 * @param __d A deleter. 181 * @param __a An allocator. 182 * @post use_count() == 1 && get() == __p 183 * @throw std::bad_alloc, in which case @a __d(__p) is called. 184 * 185 * Requirements: _Deleter's copy constructor and destructor must 186 * not throw _Alloc's copy constructor and destructor must not 187 * throw. 188 * 189 * __shared_ptr will release __p by calling __d(__p) 190 */ 191 template<typename _Yp, typename _Deleter, typename _Alloc, 192 typename = _Constructible<_Yp*, _Deleter, _Alloc>> 193 shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a) 194 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } 195 196 /** 197 * @brief Construct a %shared_ptr that owns a null pointer 198 * and the deleter @a __d. 199 * @param __p A null pointer constant. 200 * @param __d A deleter. 201 * @param __a An allocator. 202 * @post use_count() == 1 && get() == __p 203 * @throw std::bad_alloc, in which case @a __d(__p) is called. 204 * 205 * Requirements: _Deleter's copy constructor and destructor must 206 * not throw _Alloc's copy constructor and destructor must not 207 * throw. 208 * 209 * The last owner will call __d(__p) 210 */ 211 template<typename _Deleter, typename _Alloc> 212 shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 213 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } 214 215 // Aliasing constructor 216 217 /** 218 * @brief Constructs a %shared_ptr instance that stores @a __p 219 * and shares ownership with @a __r. 220 * @param __r A %shared_ptr. 221 * @param __p A pointer that will remain valid while @a *__r is valid. 222 * @post get() == __p && use_count() == __r.use_count() 223 * 224 * This can be used to construct a @c shared_ptr to a sub-object 225 * of an object managed by an existing @c shared_ptr. 226 * 227 * @code 228 * shared_ptr< pair<int,int> > pii(new pair<int,int>()); 229 * shared_ptr<int> pi(pii, &pii->first); 230 * assert(pii.use_count() == 2); 231 * @endcode 232 */ 233 template<typename _Yp> 234 shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept 235 : __shared_ptr<_Tp>(__r, __p) { } 236 237 /** 238 * @brief If @a __r is empty, constructs an empty %shared_ptr; 239 * otherwise construct a %shared_ptr that shares ownership 240 * with @a __r. 241 * @param __r A %shared_ptr. 242 * @post get() == __r.get() && use_count() == __r.use_count() 243 */ 244 template<typename _Yp, 245 typename = _Constructible<const shared_ptr<_Yp>&>> 246 shared_ptr(const shared_ptr<_Yp>& __r) noexcept 247 : __shared_ptr<_Tp>(__r) { } 248 249 /** 250 * @brief Move-constructs a %shared_ptr instance from @a __r. 251 * @param __r A %shared_ptr rvalue. 252 * @post *this contains the old value of @a __r, @a __r is empty. 253 */ 254 shared_ptr(shared_ptr&& __r) noexcept 255 : __shared_ptr<_Tp>(std::move(__r)) { } 256 257 /** 258 * @brief Move-constructs a %shared_ptr instance from @a __r. 259 * @param __r A %shared_ptr rvalue. 260 * @post *this contains the old value of @a __r, @a __r is empty. 261 */ 262 template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>> 263 shared_ptr(shared_ptr<_Yp>&& __r) noexcept 264 : __shared_ptr<_Tp>(std::move(__r)) { } 265 266 /** 267 * @brief Constructs a %shared_ptr that shares ownership with @a __r 268 * and stores a copy of the pointer stored in @a __r. 269 * @param __r A weak_ptr. 270 * @post use_count() == __r.use_count() 271 * @throw bad_weak_ptr when __r.expired(), 272 * in which case the constructor has no effect. 273 */ 274 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> 275 explicit shared_ptr(const weak_ptr<_Yp>& __r) 276 : __shared_ptr<_Tp>(__r) { } 277 278 #if _GLIBCXX_USE_DEPRECATED 279 #pragma GCC diagnostic push 280 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 281 template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>> 282 shared_ptr(auto_ptr<_Yp>&& __r); 283 #pragma GCC diagnostic pop 284 #endif 285 286 // _GLIBCXX_RESOLVE_LIB_DEFECTS 287 // 2399. shared_ptr's constructor from unique_ptr should be constrained 288 template<typename _Yp, typename _Del, 289 typename = _Constructible<unique_ptr<_Yp, _Del>>> 290 shared_ptr(unique_ptr<_Yp, _Del>&& __r) 291 : __shared_ptr<_Tp>(std::move(__r)) { } 292 293 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED 294 // This non-standard constructor exists to support conversions that 295 // were possible in C++11 and C++14 but are ill-formed in C++17. 296 // If an exception is thrown this constructor has no effect. 297 template<typename _Yp, typename _Del, 298 _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0> 299 shared_ptr(unique_ptr<_Yp, _Del>&& __r) 300 : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { } 301 #endif 302 303 /** 304 * @brief Construct an empty %shared_ptr. 305 * @post use_count() == 0 && get() == nullptr 306 */ 307 constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { } 308 309 shared_ptr& operator=(const shared_ptr&) noexcept = default; 310 311 template<typename _Yp> 312 _Assignable<const shared_ptr<_Yp>&> 313 operator=(const shared_ptr<_Yp>& __r) noexcept 314 { 315 this->__shared_ptr<_Tp>::operator=(__r); 316 return *this; 317 } 318 319 #if _GLIBCXX_USE_DEPRECATED 320 #pragma GCC diagnostic push 321 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 322 template<typename _Yp> 323 _Assignable<auto_ptr<_Yp>> 324 operator=(auto_ptr<_Yp>&& __r) 325 { 326 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 327 return *this; 328 } 329 #pragma GCC diagnostic pop 330 #endif 331 332 shared_ptr& 333 operator=(shared_ptr&& __r) noexcept 334 { 335 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 336 return *this; 337 } 338 339 template<class _Yp> 340 _Assignable<shared_ptr<_Yp>> 341 operator=(shared_ptr<_Yp>&& __r) noexcept 342 { 343 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 344 return *this; 345 } 346 347 template<typename _Yp, typename _Del> 348 _Assignable<unique_ptr<_Yp, _Del>> 349 operator=(unique_ptr<_Yp, _Del>&& __r) 350 { 351 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 352 return *this; 353 } 354 355 private: 356 // This constructor is non-standard, it is used by allocate_shared. 357 template<typename _Alloc, typename... _Args> 358 shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) 359 : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...) 360 { } 361 362 template<typename _Yp, typename _Alloc, typename... _Args> 363 friend shared_ptr<_Yp> 364 allocate_shared(const _Alloc& __a, _Args&&... __args); 365 366 // This constructor is non-standard, it is used by weak_ptr::lock(). 367 shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) 368 : __shared_ptr<_Tp>(__r, std::nothrow) { } 369 370 friend class weak_ptr<_Tp>; 371 }; 372 373 #if __cpp_deduction_guides >= 201606 374 template<typename _Tp> 375 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; 376 template<typename _Tp, typename _Del> 377 shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>; 378 #endif 379 380 // 20.7.2.2.7 shared_ptr comparisons 381 template<typename _Tp, typename _Up> 382 inline bool 383 operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 384 { return __a.get() == __b.get(); } 385 386 template<typename _Tp> 387 inline bool 388 operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 389 { return !__a; } 390 391 template<typename _Tp> 392 inline bool 393 operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 394 { return !__a; } 395 396 template<typename _Tp, typename _Up> 397 inline bool 398 operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 399 { return __a.get() != __b.get(); } 400 401 template<typename _Tp> 402 inline bool 403 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 404 { return (bool)__a; } 405 406 template<typename _Tp> 407 inline bool 408 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 409 { return (bool)__a; } 410 411 template<typename _Tp, typename _Up> 412 inline bool 413 operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 414 { 415 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 416 using _Up_elt = typename shared_ptr<_Up>::element_type; 417 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; 418 return less<_Vp>()(__a.get(), __b.get()); 419 } 420 421 template<typename _Tp> 422 inline bool 423 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 424 { 425 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 426 return less<_Tp_elt*>()(__a.get(), nullptr); 427 } 428 429 template<typename _Tp> 430 inline bool 431 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 432 { 433 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 434 return less<_Tp_elt*>()(nullptr, __a.get()); 435 } 436 437 template<typename _Tp, typename _Up> 438 inline bool 439 operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 440 { return !(__b < __a); } 441 442 template<typename _Tp> 443 inline bool 444 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 445 { return !(nullptr < __a); } 446 447 template<typename _Tp> 448 inline bool 449 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 450 { return !(__a < nullptr); } 451 452 template<typename _Tp, typename _Up> 453 inline bool 454 operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 455 { return (__b < __a); } 456 457 template<typename _Tp> 458 inline bool 459 operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 460 { return nullptr < __a; } 461 462 template<typename _Tp> 463 inline bool 464 operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 465 { return __a < nullptr; } 466 467 template<typename _Tp, typename _Up> 468 inline bool 469 operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 470 { return !(__a < __b); } 471 472 template<typename _Tp> 473 inline bool 474 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 475 { return !(__a < nullptr); } 476 477 template<typename _Tp> 478 inline bool 479 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 480 { return !(nullptr < __a); } 481 482 template<typename _Tp> 483 struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> 484 { }; 485 486 // 20.7.2.2.8 shared_ptr specialized algorithms. 487 template<typename _Tp> 488 inline void 489 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept 490 { __a.swap(__b); } 491 492 // 20.7.2.2.9 shared_ptr casts. 493 template<typename _Tp, typename _Up> 494 inline shared_ptr<_Tp> 495 static_pointer_cast(const shared_ptr<_Up>& __r) noexcept 496 { 497 using _Sp = shared_ptr<_Tp>; 498 return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get())); 499 } 500 501 template<typename _Tp, typename _Up> 502 inline shared_ptr<_Tp> 503 const_pointer_cast(const shared_ptr<_Up>& __r) noexcept 504 { 505 using _Sp = shared_ptr<_Tp>; 506 return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get())); 507 } 508 509 template<typename _Tp, typename _Up> 510 inline shared_ptr<_Tp> 511 dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept 512 { 513 using _Sp = shared_ptr<_Tp>; 514 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get())) 515 return _Sp(__r, __p); 516 return _Sp(); 517 } 518 519 #if __cplusplus > 201402L 520 template<typename _Tp, typename _Up> 521 inline shared_ptr<_Tp> 522 reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept 523 { 524 using _Sp = shared_ptr<_Tp>; 525 return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get())); 526 } 527 #endif 528 529 /** 530 * @brief A smart pointer with weak semantics. 531 * 532 * With forwarding constructors and assignment operators. 533 */ 534 template<typename _Tp> 535 class weak_ptr : public __weak_ptr<_Tp> 536 { 537 template<typename _Arg> 538 using _Constructible = typename enable_if< 539 is_constructible<__weak_ptr<_Tp>, _Arg>::value 540 >::type; 541 542 template<typename _Arg> 543 using _Assignable = typename enable_if< 544 is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr& 545 >::type; 546 547 public: 548 constexpr weak_ptr() noexcept = default; 549 550 template<typename _Yp, 551 typename = _Constructible<const shared_ptr<_Yp>&>> 552 weak_ptr(const shared_ptr<_Yp>& __r) noexcept 553 : __weak_ptr<_Tp>(__r) { } 554 555 weak_ptr(const weak_ptr&) noexcept = default; 556 557 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> 558 weak_ptr(const weak_ptr<_Yp>& __r) noexcept 559 : __weak_ptr<_Tp>(__r) { } 560 561 weak_ptr(weak_ptr&&) noexcept = default; 562 563 template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>> 564 weak_ptr(weak_ptr<_Yp>&& __r) noexcept 565 : __weak_ptr<_Tp>(std::move(__r)) { } 566 567 weak_ptr& 568 operator=(const weak_ptr& __r) noexcept = default; 569 570 template<typename _Yp> 571 _Assignable<const weak_ptr<_Yp>&> 572 operator=(const weak_ptr<_Yp>& __r) noexcept 573 { 574 this->__weak_ptr<_Tp>::operator=(__r); 575 return *this; 576 } 577 578 template<typename _Yp> 579 _Assignable<const shared_ptr<_Yp>&> 580 operator=(const shared_ptr<_Yp>& __r) noexcept 581 { 582 this->__weak_ptr<_Tp>::operator=(__r); 583 return *this; 584 } 585 586 weak_ptr& 587 operator=(weak_ptr&& __r) noexcept = default; 588 589 template<typename _Yp> 590 _Assignable<weak_ptr<_Yp>> 591 operator=(weak_ptr<_Yp>&& __r) noexcept 592 { 593 this->__weak_ptr<_Tp>::operator=(std::move(__r)); 594 return *this; 595 } 596 597 shared_ptr<_Tp> 598 lock() const noexcept 599 { return shared_ptr<_Tp>(*this, std::nothrow); } 600 }; 601 602 #if __cpp_deduction_guides >= 201606 603 template<typename _Tp> 604 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; 605 #endif 606 607 // 20.7.2.3.6 weak_ptr specialized algorithms. 608 template<typename _Tp> 609 inline void 610 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept 611 { __a.swap(__b); } 612 613 614 /// Primary template owner_less 615 template<typename _Tp = void> 616 struct owner_less; 617 618 /// Void specialization of owner_less 619 template<> 620 struct owner_less<void> : _Sp_owner_less<void, void> 621 { }; 622 623 /// Partial specialization of owner_less for shared_ptr. 624 template<typename _Tp> 625 struct owner_less<shared_ptr<_Tp>> 626 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> 627 { }; 628 629 /// Partial specialization of owner_less for weak_ptr. 630 template<typename _Tp> 631 struct owner_less<weak_ptr<_Tp>> 632 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> 633 { }; 634 635 /** 636 * @brief Base class allowing use of member function shared_from_this. 637 */ 638 template<typename _Tp> 639 class enable_shared_from_this 640 { 641 protected: 642 constexpr enable_shared_from_this() noexcept { } 643 644 enable_shared_from_this(const enable_shared_from_this&) noexcept { } 645 646 enable_shared_from_this& 647 operator=(const enable_shared_from_this&) noexcept 648 { return *this; } 649 650 ~enable_shared_from_this() { } 651 652 public: 653 shared_ptr<_Tp> 654 shared_from_this() 655 { return shared_ptr<_Tp>(this->_M_weak_this); } 656 657 shared_ptr<const _Tp> 658 shared_from_this() const 659 { return shared_ptr<const _Tp>(this->_M_weak_this); } 660 661 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 662 #define __cpp_lib_enable_shared_from_this 201603 663 weak_ptr<_Tp> 664 weak_from_this() noexcept 665 { return this->_M_weak_this; } 666 667 weak_ptr<const _Tp> 668 weak_from_this() const noexcept 669 { return this->_M_weak_this; } 670 #endif 671 672 private: 673 template<typename _Tp1> 674 void 675 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept 676 { _M_weak_this._M_assign(__p, __n); } 677 678 // Found by ADL when this is an associated class. 679 friend const enable_shared_from_this* 680 __enable_shared_from_this_base(const __shared_count<>&, 681 const enable_shared_from_this* __p) 682 { return __p; } 683 684 template<typename, _Lock_policy> 685 friend class __shared_ptr; 686 687 mutable weak_ptr<_Tp> _M_weak_this; 688 }; 689 690 /** 691 * @brief Create an object that is owned by a shared_ptr. 692 * @param __a An allocator. 693 * @param __args Arguments for the @a _Tp object's constructor. 694 * @return A shared_ptr that owns the newly created object. 695 * @throw An exception thrown from @a _Alloc::allocate or from the 696 * constructor of @a _Tp. 697 * 698 * A copy of @a __a will be used to allocate memory for the shared_ptr 699 * and the new object. 700 */ 701 template<typename _Tp, typename _Alloc, typename... _Args> 702 inline shared_ptr<_Tp> 703 allocate_shared(const _Alloc& __a, _Args&&... __args) 704 { 705 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a}, 706 std::forward<_Args>(__args)...); 707 } 708 709 /** 710 * @brief Create an object that is owned by a shared_ptr. 711 * @param __args Arguments for the @a _Tp object's constructor. 712 * @return A shared_ptr that owns the newly created object. 713 * @throw std::bad_alloc, or an exception thrown from the 714 * constructor of @a _Tp. 715 */ 716 template<typename _Tp, typename... _Args> 717 inline shared_ptr<_Tp> 718 make_shared(_Args&&... __args) 719 { 720 typedef typename std::remove_cv<_Tp>::type _Tp_nc; 721 return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), 722 std::forward<_Args>(__args)...); 723 } 724 725 /// std::hash specialization for shared_ptr. 726 template<typename _Tp> 727 struct hash<shared_ptr<_Tp>> 728 : public __hash_base<size_t, shared_ptr<_Tp>> 729 { 730 size_t 731 operator()(const shared_ptr<_Tp>& __s) const noexcept 732 { 733 return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get()); 734 } 735 }; 736 737 // @} group pointer_abstractions 738 739 _GLIBCXX_END_NAMESPACE_VERSION 740 } // namespace 741 742 #endif // _SHARED_PTR_H 743