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_make_shared_tag __tag, const _Alloc& __a, 359 _Args&&... __args) 360 : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...) 361 { } 362 363 template<typename _Yp, typename _Alloc, typename... _Args> 364 friend shared_ptr<_Yp> 365 allocate_shared(const _Alloc& __a, _Args&&... __args); 366 367 // This constructor is non-standard, it is used by weak_ptr::lock(). 368 shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) 369 : __shared_ptr<_Tp>(__r, std::nothrow) { } 370 371 friend class weak_ptr<_Tp>; 372 }; 373 374 #if __cpp_deduction_guides >= 201606 375 template<typename _Tp> 376 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; 377 template<typename _Tp, typename _Del> 378 shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>; 379 #endif 380 381 // 20.7.2.2.7 shared_ptr comparisons 382 template<typename _Tp, typename _Up> 383 inline bool 384 operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 385 { return __a.get() == __b.get(); } 386 387 template<typename _Tp> 388 inline bool 389 operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 390 { return !__a; } 391 392 template<typename _Tp> 393 inline bool 394 operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 395 { return !__a; } 396 397 template<typename _Tp, typename _Up> 398 inline bool 399 operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 400 { return __a.get() != __b.get(); } 401 402 template<typename _Tp> 403 inline bool 404 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 405 { return (bool)__a; } 406 407 template<typename _Tp> 408 inline bool 409 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 410 { return (bool)__a; } 411 412 template<typename _Tp, typename _Up> 413 inline bool 414 operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 415 { 416 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 417 using _Up_elt = typename shared_ptr<_Up>::element_type; 418 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; 419 return less<_Vp>()(__a.get(), __b.get()); 420 } 421 422 template<typename _Tp> 423 inline bool 424 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 425 { 426 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 427 return less<_Tp_elt*>()(__a.get(), nullptr); 428 } 429 430 template<typename _Tp> 431 inline bool 432 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 433 { 434 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 435 return less<_Tp_elt*>()(nullptr, __a.get()); 436 } 437 438 template<typename _Tp, typename _Up> 439 inline bool 440 operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 441 { return !(__b < __a); } 442 443 template<typename _Tp> 444 inline bool 445 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 446 { return !(nullptr < __a); } 447 448 template<typename _Tp> 449 inline bool 450 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 451 { return !(__a < nullptr); } 452 453 template<typename _Tp, typename _Up> 454 inline bool 455 operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 456 { return (__b < __a); } 457 458 template<typename _Tp> 459 inline bool 460 operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 461 { return nullptr < __a; } 462 463 template<typename _Tp> 464 inline bool 465 operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 466 { return __a < nullptr; } 467 468 template<typename _Tp, typename _Up> 469 inline bool 470 operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 471 { return !(__a < __b); } 472 473 template<typename _Tp> 474 inline bool 475 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 476 { return !(__a < nullptr); } 477 478 template<typename _Tp> 479 inline bool 480 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 481 { return !(nullptr < __a); } 482 483 template<typename _Tp> 484 struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> 485 { }; 486 487 // 20.7.2.2.8 shared_ptr specialized algorithms. 488 template<typename _Tp> 489 inline void 490 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept 491 { __a.swap(__b); } 492 493 // 20.7.2.2.9 shared_ptr casts. 494 template<typename _Tp, typename _Up> 495 inline shared_ptr<_Tp> 496 static_pointer_cast(const shared_ptr<_Up>& __r) noexcept 497 { 498 using _Sp = shared_ptr<_Tp>; 499 return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get())); 500 } 501 502 template<typename _Tp, typename _Up> 503 inline shared_ptr<_Tp> 504 const_pointer_cast(const shared_ptr<_Up>& __r) noexcept 505 { 506 using _Sp = shared_ptr<_Tp>; 507 return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get())); 508 } 509 510 template<typename _Tp, typename _Up> 511 inline shared_ptr<_Tp> 512 dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept 513 { 514 using _Sp = shared_ptr<_Tp>; 515 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get())) 516 return _Sp(__r, __p); 517 return _Sp(); 518 } 519 520 #if __cplusplus > 201402L 521 template<typename _Tp, typename _Up> 522 inline shared_ptr<_Tp> 523 reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept 524 { 525 using _Sp = shared_ptr<_Tp>; 526 return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get())); 527 } 528 #endif 529 530 /** 531 * @brief A smart pointer with weak semantics. 532 * 533 * With forwarding constructors and assignment operators. 534 */ 535 template<typename _Tp> 536 class weak_ptr : public __weak_ptr<_Tp> 537 { 538 template<typename _Arg> 539 using _Constructible = typename enable_if< 540 is_constructible<__weak_ptr<_Tp>, _Arg>::value 541 >::type; 542 543 template<typename _Arg> 544 using _Assignable = typename enable_if< 545 is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr& 546 >::type; 547 548 public: 549 constexpr weak_ptr() noexcept = default; 550 551 template<typename _Yp, 552 typename = _Constructible<const shared_ptr<_Yp>&>> 553 weak_ptr(const shared_ptr<_Yp>& __r) noexcept 554 : __weak_ptr<_Tp>(__r) { } 555 556 weak_ptr(const weak_ptr&) noexcept = default; 557 558 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> 559 weak_ptr(const weak_ptr<_Yp>& __r) noexcept 560 : __weak_ptr<_Tp>(__r) { } 561 562 weak_ptr(weak_ptr&&) noexcept = default; 563 564 template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>> 565 weak_ptr(weak_ptr<_Yp>&& __r) noexcept 566 : __weak_ptr<_Tp>(std::move(__r)) { } 567 568 weak_ptr& 569 operator=(const weak_ptr& __r) noexcept = default; 570 571 template<typename _Yp> 572 _Assignable<const weak_ptr<_Yp>&> 573 operator=(const weak_ptr<_Yp>& __r) noexcept 574 { 575 this->__weak_ptr<_Tp>::operator=(__r); 576 return *this; 577 } 578 579 template<typename _Yp> 580 _Assignable<const shared_ptr<_Yp>&> 581 operator=(const shared_ptr<_Yp>& __r) noexcept 582 { 583 this->__weak_ptr<_Tp>::operator=(__r); 584 return *this; 585 } 586 587 weak_ptr& 588 operator=(weak_ptr&& __r) noexcept = default; 589 590 template<typename _Yp> 591 _Assignable<weak_ptr<_Yp>> 592 operator=(weak_ptr<_Yp>&& __r) noexcept 593 { 594 this->__weak_ptr<_Tp>::operator=(std::move(__r)); 595 return *this; 596 } 597 598 shared_ptr<_Tp> 599 lock() const noexcept 600 { return shared_ptr<_Tp>(*this, std::nothrow); } 601 }; 602 603 #if __cpp_deduction_guides >= 201606 604 template<typename _Tp> 605 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; 606 #endif 607 608 // 20.7.2.3.6 weak_ptr specialized algorithms. 609 template<typename _Tp> 610 inline void 611 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept 612 { __a.swap(__b); } 613 614 615 /// Primary template owner_less 616 template<typename _Tp = void> 617 struct owner_less; 618 619 /// Void specialization of owner_less 620 template<> 621 struct owner_less<void> : _Sp_owner_less<void, void> 622 { }; 623 624 /// Partial specialization of owner_less for shared_ptr. 625 template<typename _Tp> 626 struct owner_less<shared_ptr<_Tp>> 627 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> 628 { }; 629 630 /// Partial specialization of owner_less for weak_ptr. 631 template<typename _Tp> 632 struct owner_less<weak_ptr<_Tp>> 633 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> 634 { }; 635 636 /** 637 * @brief Base class allowing use of member function shared_from_this. 638 */ 639 template<typename _Tp> 640 class enable_shared_from_this 641 { 642 protected: 643 constexpr enable_shared_from_this() noexcept { } 644 645 enable_shared_from_this(const enable_shared_from_this&) noexcept { } 646 647 enable_shared_from_this& 648 operator=(const enable_shared_from_this&) noexcept 649 { return *this; } 650 651 ~enable_shared_from_this() { } 652 653 public: 654 shared_ptr<_Tp> 655 shared_from_this() 656 { return shared_ptr<_Tp>(this->_M_weak_this); } 657 658 shared_ptr<const _Tp> 659 shared_from_this() const 660 { return shared_ptr<const _Tp>(this->_M_weak_this); } 661 662 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 663 #define __cpp_lib_enable_shared_from_this 201603 664 weak_ptr<_Tp> 665 weak_from_this() noexcept 666 { return this->_M_weak_this; } 667 668 weak_ptr<const _Tp> 669 weak_from_this() const noexcept 670 { return this->_M_weak_this; } 671 #endif 672 673 private: 674 template<typename _Tp1> 675 void 676 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept 677 { _M_weak_this._M_assign(__p, __n); } 678 679 // Found by ADL when this is an associated class. 680 friend const enable_shared_from_this* 681 __enable_shared_from_this_base(const __shared_count<>&, 682 const enable_shared_from_this* __p) 683 { return __p; } 684 685 template<typename, _Lock_policy> 686 friend class __shared_ptr; 687 688 mutable weak_ptr<_Tp> _M_weak_this; 689 }; 690 691 /** 692 * @brief Create an object that is owned by a shared_ptr. 693 * @param __a An allocator. 694 * @param __args Arguments for the @a _Tp object's constructor. 695 * @return A shared_ptr that owns the newly created object. 696 * @throw An exception thrown from @a _Alloc::allocate or from the 697 * constructor of @a _Tp. 698 * 699 * A copy of @a __a will be used to allocate memory for the shared_ptr 700 * and the new object. 701 */ 702 template<typename _Tp, typename _Alloc, typename... _Args> 703 inline shared_ptr<_Tp> 704 allocate_shared(const _Alloc& __a, _Args&&... __args) 705 { 706 return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a, 707 std::forward<_Args>(__args)...); 708 } 709 710 /** 711 * @brief Create an object that is owned by a shared_ptr. 712 * @param __args Arguments for the @a _Tp object's constructor. 713 * @return A shared_ptr that owns the newly created object. 714 * @throw std::bad_alloc, or an exception thrown from the 715 * constructor of @a _Tp. 716 */ 717 template<typename _Tp, typename... _Args> 718 inline shared_ptr<_Tp> 719 make_shared(_Args&&... __args) 720 { 721 typedef typename std::remove_const<_Tp>::type _Tp_nc; 722 return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), 723 std::forward<_Args>(__args)...); 724 } 725 726 /// std::hash specialization for shared_ptr. 727 template<typename _Tp> 728 struct hash<shared_ptr<_Tp>> 729 : public __hash_base<size_t, shared_ptr<_Tp>> 730 { 731 size_t 732 operator()(const shared_ptr<_Tp>& __s) const noexcept 733 { 734 return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get()); 735 } 736 }; 737 738 // @} group pointer_abstractions 739 740 _GLIBCXX_END_NAMESPACE_VERSION 741 } // namespace 742 743 #endif // _SHARED_PTR_H 744