Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/11/bits/shared_ptr.h
$ cat -n /usr/include/c++/11/bits/shared_ptr.h 1 // shared_ptr and weak_ptr implementation -*- C++ -*- 2 3 // Copyright (C) 2007-2021 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 //
. 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
// std::basic_ostream 53 #include
54 55 namespace std _GLIBCXX_VISIBILITY(default) 56 { 57 _GLIBCXX_BEGIN_NAMESPACE_VERSION 58 59 /** 60 * @addtogroup pointer_abstractions 61 * @{ 62 */ 63 64 // 20.7.2.2.11 shared_ptr I/O 65 66 /// Write the stored pointer to an ostream. 67 /// @relates shared_ptr 68 template
69 inline std::basic_ostream<_Ch, _Tr>& 70 operator<<(std::basic_ostream<_Ch, _Tr>& __os, 71 const __shared_ptr<_Tp, _Lp>& __p) 72 { 73 __os << __p.get(); 74 return __os; 75 } 76 77 template
78 inline _Del* 79 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept 80 { 81 #if __cpp_rtti 82 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 83 #else 84 return 0; 85 #endif 86 } 87 88 /// 20.7.2.2.10 shared_ptr get_deleter 89 90 /// If `__p` has a deleter of type `_Del`, return a pointer to it. 91 /// @relates shared_ptr 92 template
93 inline _Del* 94 get_deleter(const shared_ptr<_Tp>& __p) noexcept 95 { 96 #if __cpp_rtti 97 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 98 #else 99 return 0; 100 #endif 101 } 102 103 /** 104 * @brief A smart pointer with reference-counted copy semantics. 105 * 106 * A `shared_ptr` object is either empty or _owns_ a pointer passed 107 * to the constructor. Copies of a `shared_ptr` share ownership of 108 * the same pointer. When the last `shared_ptr` that owns the pointer 109 * is destroyed or reset, the owned pointer is freed (either by `delete` 110 * or by invoking a custom deleter that was passed to the constructor). 111 * 112 * A `shared_ptr` also stores another pointer, which is usually 113 * (but not always) the same pointer as it owns. The stored pointer 114 * can be retrieved by calling the `get()` member function. 115 * 116 * The equality and relational operators for `shared_ptr` only compare 117 * the stored pointer returned by `get()`, not the owned pointer. 118 * To test whether two `shared_ptr` objects share ownership of the same 119 * pointer see `std::shared_ptr::owner_before` and `std::owner_less`. 120 */ 121 template
122 class shared_ptr : public __shared_ptr<_Tp> 123 { 124 template
125 using _Constructible = typename enable_if< 126 is_constructible<__shared_ptr<_Tp>, _Args...>::value 127 >::type; 128 129 template
130 using _Assignable = typename enable_if< 131 is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr& 132 >::type; 133 134 public: 135 136 /// The type pointed to by the stored pointer, remove_extent_t<_Tp> 137 using element_type = typename __shared_ptr<_Tp>::element_type; 138 139 #if __cplusplus >= 201703L 140 # define __cpp_lib_shared_ptr_weak_type 201606 141 /// The corresponding weak_ptr type for this shared_ptr 142 using weak_type = weak_ptr<_Tp>; 143 #endif 144 /** 145 * @brief Construct an empty %shared_ptr. 146 * @post use_count()==0 && get()==0 147 */ 148 constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { } 149 150 shared_ptr(const shared_ptr&) noexcept = default; ///< Copy constructor 151 152 /** 153 * @brief Construct a %shared_ptr that owns the pointer @a __p. 154 * @param __p A pointer that is convertible to element_type*. 155 * @post use_count() == 1 && get() == __p 156 * @throw std::bad_alloc, in which case @c delete @a __p is called. 157 */ 158 template
> 159 explicit 160 shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { } 161 162 /** 163 * @brief Construct a %shared_ptr that owns the pointer @a __p 164 * and the deleter @a __d. 165 * @param __p A pointer. 166 * @param __d A deleter. 167 * @post use_count() == 1 && get() == __p 168 * @throw std::bad_alloc, in which case @a __d(__p) is called. 169 * 170 * Requirements: _Deleter's copy constructor and destructor must 171 * not throw 172 * 173 * __shared_ptr will release __p by calling __d(__p) 174 */ 175 template
> 177 shared_ptr(_Yp* __p, _Deleter __d) 178 : __shared_ptr<_Tp>(__p, std::move(__d)) { } 179 180 /** 181 * @brief Construct a %shared_ptr that owns a null pointer 182 * and the deleter @a __d. 183 * @param __p A null pointer constant. 184 * @param __d A deleter. 185 * @post use_count() == 1 && get() == __p 186 * @throw std::bad_alloc, in which case @a __d(__p) is called. 187 * 188 * Requirements: _Deleter's copy constructor and destructor must 189 * not throw 190 * 191 * The last owner will call __d(__p) 192 */ 193 template
194 shared_ptr(nullptr_t __p, _Deleter __d) 195 : __shared_ptr<_Tp>(__p, std::move(__d)) { } 196 197 /** 198 * @brief Construct a %shared_ptr that owns the pointer @a __p 199 * and the deleter @a __d. 200 * @param __p A pointer. 201 * @param __d A deleter. 202 * @param __a An allocator. 203 * @post use_count() == 1 && get() == __p 204 * @throw std::bad_alloc, in which case @a __d(__p) is called. 205 * 206 * Requirements: _Deleter's copy constructor and destructor must 207 * not throw _Alloc's copy constructor and destructor must not 208 * throw. 209 * 210 * __shared_ptr will release __p by calling __d(__p) 211 */ 212 template
> 214 shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a) 215 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } 216 217 /** 218 * @brief Construct a %shared_ptr that owns a null pointer 219 * and the deleter @a __d. 220 * @param __p A null pointer constant. 221 * @param __d A deleter. 222 * @param __a An allocator. 223 * @post use_count() == 1 && get() == __p 224 * @throw std::bad_alloc, in which case @a __d(__p) is called. 225 * 226 * Requirements: _Deleter's copy constructor and destructor must 227 * not throw _Alloc's copy constructor and destructor must not 228 * throw. 229 * 230 * The last owner will call __d(__p) 231 */ 232 template
233 shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 234 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } 235 236 // Aliasing constructor 237 238 /** 239 * @brief Constructs a `shared_ptr` instance that stores `__p` 240 * and shares ownership with `__r`. 241 * @param __r A `shared_ptr`. 242 * @param __p A pointer that will remain valid while `*__r` is valid. 243 * @post `get() == __p && use_count() == __r.use_count()` 244 * 245 * This can be used to construct a `shared_ptr` to a sub-object 246 * of an object managed by an existing `shared_ptr`. The complete 247 * object will remain valid while any `shared_ptr` owns it, even 248 * if they don't store a pointer to the complete object. 249 * 250 * @code 251 * shared_ptr
> pii(new pair
()); 252 * shared_ptr
pi(pii, &pii->first); 253 * assert(pii.use_count() == 2); 254 * @endcode 255 */ 256 template
257 shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept 258 : __shared_ptr<_Tp>(__r, __p) { } 259 260 #if __cplusplus > 201703L 261 // _GLIBCXX_RESOLVE_LIB_DEFECTS 262 // 2996. Missing rvalue overloads for shared_ptr operations 263 /** 264 * @brief Constructs a `shared_ptr` instance that stores `__p` 265 * and shares ownership with `__r`. 266 * @param __r A `shared_ptr`. 267 * @param __p A pointer that will remain valid while `*__r` is valid. 268 * @post `get() == __p && !__r.use_count() && !__r.get()` 269 * 270 * This can be used to construct a `shared_ptr` to a sub-object 271 * of an object managed by an existing `shared_ptr`. The complete 272 * object will remain valid while any `shared_ptr` owns it, even 273 * if they don't store a pointer to the complete object. 274 * 275 * @code 276 * shared_ptr
> pii(new pair
()); 277 * shared_ptr
pi1(pii, &pii->first); 278 * assert(pii.use_count() == 2); 279 * shared_ptr
pi2(std::move(pii), &pii->second); 280 * assert(pii.use_count() == 0); 281 * @endcode 282 */ 283 template
284 shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept 285 : __shared_ptr<_Tp>(std::move(__r), __p) { } 286 #endif 287 /** 288 * @brief If @a __r is empty, constructs an empty %shared_ptr; 289 * otherwise construct a %shared_ptr that shares ownership 290 * with @a __r. 291 * @param __r A %shared_ptr. 292 * @post get() == __r.get() && use_count() == __r.use_count() 293 */ 294 template
&>> 296 shared_ptr(const shared_ptr<_Yp>& __r) noexcept 297 : __shared_ptr<_Tp>(__r) { } 298 299 /** 300 * @brief Move-constructs a %shared_ptr instance from @a __r. 301 * @param __r A %shared_ptr rvalue. 302 * @post *this contains the old value of @a __r, @a __r is empty. 303 */ 304 shared_ptr(shared_ptr&& __r) noexcept 305 : __shared_ptr<_Tp>(std::move(__r)) { } 306 307 /** 308 * @brief Move-constructs a %shared_ptr instance from @a __r. 309 * @param __r A %shared_ptr rvalue. 310 * @post *this contains the old value of @a __r, @a __r is empty. 311 */ 312 template
>> 313 shared_ptr(shared_ptr<_Yp>&& __r) noexcept 314 : __shared_ptr<_Tp>(std::move(__r)) { } 315 316 /** 317 * @brief Constructs a %shared_ptr that shares ownership with @a __r 318 * and stores a copy of the pointer stored in @a __r. 319 * @param __r A weak_ptr. 320 * @post use_count() == __r.use_count() 321 * @throw bad_weak_ptr when __r.expired(), 322 * in which case the constructor has no effect. 323 */ 324 template
&>> 325 explicit shared_ptr(const weak_ptr<_Yp>& __r) 326 : __shared_ptr<_Tp>(__r) { } 327 328 #if _GLIBCXX_USE_DEPRECATED 329 #pragma GCC diagnostic push 330 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 331 template
>> 332 shared_ptr(auto_ptr<_Yp>&& __r); 333 #pragma GCC diagnostic pop 334 #endif 335 336 // _GLIBCXX_RESOLVE_LIB_DEFECTS 337 // 2399. shared_ptr's constructor from unique_ptr should be constrained 338 template
>> 340 shared_ptr(unique_ptr<_Yp, _Del>&& __r) 341 : __shared_ptr<_Tp>(std::move(__r)) { } 342 343 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED 344 // This non-standard constructor exists to support conversions that 345 // were possible in C++11 and C++14 but are ill-formed in C++17. 346 // If an exception is thrown this constructor has no effect. 347 template
, __sp_array_delete>* = 0> 349 shared_ptr(unique_ptr<_Yp, _Del>&& __r) 350 : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { } 351 #endif 352 353 /** 354 * @brief Construct an empty %shared_ptr. 355 * @post use_count() == 0 && get() == nullptr 356 */ 357 constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { } 358 359 shared_ptr& operator=(const shared_ptr&) noexcept = default; 360 361 template
362 _Assignable
&> 363 operator=(const shared_ptr<_Yp>& __r) noexcept 364 { 365 this->__shared_ptr<_Tp>::operator=(__r); 366 return *this; 367 } 368 369 #if _GLIBCXX_USE_DEPRECATED 370 #pragma GCC diagnostic push 371 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 372 template
373 _Assignable
> 374 operator=(auto_ptr<_Yp>&& __r) 375 { 376 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 377 return *this; 378 } 379 #pragma GCC diagnostic pop 380 #endif 381 382 shared_ptr& 383 operator=(shared_ptr&& __r) noexcept 384 { 385 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 386 return *this; 387 } 388 389 template
390 _Assignable
> 391 operator=(shared_ptr<_Yp>&& __r) noexcept 392 { 393 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 394 return *this; 395 } 396 397 template
398 _Assignable
> 399 operator=(unique_ptr<_Yp, _Del>&& __r) 400 { 401 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 402 return *this; 403 } 404 405 private: 406 // This constructor is non-standard, it is used by allocate_shared. 407 template
408 shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) 409 : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...) 410 { } 411 412 template
413 friend shared_ptr<_Yp> 414 allocate_shared(const _Alloc& __a, _Args&&... __args); 415 416 // This constructor is non-standard, it is used by weak_ptr::lock(). 417 shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) noexcept 418 : __shared_ptr<_Tp>(__r, std::nothrow) { } 419 420 friend class weak_ptr<_Tp>; 421 }; 422 423 #if __cpp_deduction_guides >= 201606 424 template
425 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; 426 template
427 shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>; 428 #endif 429 430 // 20.7.2.2.7 shared_ptr comparisons 431 432 /// @relates shared_ptr @{ 433 434 /// Equality operator for shared_ptr objects, compares the stored pointers 435 template
436 _GLIBCXX_NODISCARD inline bool 437 operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 438 { return __a.get() == __b.get(); } 439 440 /// shared_ptr comparison with nullptr 441 template
442 _GLIBCXX_NODISCARD inline bool 443 operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 444 { return !__a; } 445 446 #ifdef __cpp_lib_three_way_comparison 447 template
448 inline strong_ordering 449 operator<=>(const shared_ptr<_Tp>& __a, 450 const shared_ptr<_Up>& __b) noexcept 451 { return compare_three_way()(__a.get(), __b.get()); } 452 453 template
454 inline strong_ordering 455 operator<=>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 456 { 457 using pointer = typename shared_ptr<_Tp>::element_type*; 458 return compare_three_way()(__a.get(), static_cast
(nullptr)); 459 } 460 #else 461 /// shared_ptr comparison with nullptr 462 template
463 _GLIBCXX_NODISCARD inline bool 464 operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 465 { return !__a; } 466 467 /// Inequality operator for shared_ptr objects, compares the stored pointers 468 template
469 _GLIBCXX_NODISCARD inline bool 470 operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 471 { return __a.get() != __b.get(); } 472 473 /// shared_ptr comparison with nullptr 474 template
475 _GLIBCXX_NODISCARD inline bool 476 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 477 { return (bool)__a; } 478 479 /// shared_ptr comparison with nullptr 480 template
481 _GLIBCXX_NODISCARD inline bool 482 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 483 { return (bool)__a; } 484 485 /// Relational operator for shared_ptr objects, compares the stored pointers 486 template
487 _GLIBCXX_NODISCARD inline bool 488 operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 489 { 490 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 491 using _Up_elt = typename shared_ptr<_Up>::element_type; 492 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; 493 return less<_Vp>()(__a.get(), __b.get()); 494 } 495 496 /// shared_ptr comparison with nullptr 497 template
498 _GLIBCXX_NODISCARD inline bool 499 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 500 { 501 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 502 return less<_Tp_elt*>()(__a.get(), nullptr); 503 } 504 505 /// shared_ptr comparison with nullptr 506 template
507 _GLIBCXX_NODISCARD inline bool 508 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 509 { 510 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 511 return less<_Tp_elt*>()(nullptr, __a.get()); 512 } 513 514 /// Relational operator for shared_ptr objects, compares the stored pointers 515 template
516 _GLIBCXX_NODISCARD inline bool 517 operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 518 { return !(__b < __a); } 519 520 /// shared_ptr comparison with nullptr 521 template
522 _GLIBCXX_NODISCARD inline bool 523 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 524 { return !(nullptr < __a); } 525 526 /// shared_ptr comparison with nullptr 527 template
528 _GLIBCXX_NODISCARD inline bool 529 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 530 { return !(__a < nullptr); } 531 532 /// Relational operator for shared_ptr objects, compares the stored pointers 533 template
534 _GLIBCXX_NODISCARD inline bool 535 operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 536 { return (__b < __a); } 537 538 /// shared_ptr comparison with nullptr 539 template
540 _GLIBCXX_NODISCARD inline bool 541 operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 542 { return nullptr < __a; } 543 544 /// shared_ptr comparison with nullptr 545 template
546 _GLIBCXX_NODISCARD inline bool 547 operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 548 { return __a < nullptr; } 549 550 /// Relational operator for shared_ptr objects, compares the stored pointers 551 template
552 _GLIBCXX_NODISCARD inline bool 553 operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 554 { return !(__a < __b); } 555 556 /// shared_ptr comparison with nullptr 557 template
558 _GLIBCXX_NODISCARD inline bool 559 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 560 { return !(__a < nullptr); } 561 562 /// shared_ptr comparison with nullptr 563 template
564 _GLIBCXX_NODISCARD inline bool 565 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 566 { return !(nullptr < __a); } 567 #endif 568 569 // 20.7.2.2.8 shared_ptr specialized algorithms. 570 571 /// Swap overload for shared_ptr 572 template
573 inline void 574 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept 575 { __a.swap(__b); } 576 577 // 20.7.2.2.9 shared_ptr casts. 578 579 /// Convert type of `shared_ptr`, via `static_cast` 580 template
581 inline shared_ptr<_Tp> 582 static_pointer_cast(const shared_ptr<_Up>& __r) noexcept 583 { 584 using _Sp = shared_ptr<_Tp>; 585 return _Sp(__r, static_cast
(__r.get())); 586 } 587 588 /// Convert type of `shared_ptr`, via `const_cast` 589 template
590 inline shared_ptr<_Tp> 591 const_pointer_cast(const shared_ptr<_Up>& __r) noexcept 592 { 593 using _Sp = shared_ptr<_Tp>; 594 return _Sp(__r, const_cast
(__r.get())); 595 } 596 597 /// Convert type of `shared_ptr`, via `dynamic_cast` 598 template
599 inline shared_ptr<_Tp> 600 dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept 601 { 602 using _Sp = shared_ptr<_Tp>; 603 if (auto* __p = dynamic_cast
(__r.get())) 604 return _Sp(__r, __p); 605 return _Sp(); 606 } 607 608 #if __cplusplus >= 201703L 609 /// Convert type of `shared_ptr`, via `reinterpret_cast` 610 template
611 inline shared_ptr<_Tp> 612 reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept 613 { 614 using _Sp = shared_ptr<_Tp>; 615 return _Sp(__r, reinterpret_cast
(__r.get())); 616 } 617 618 #if __cplusplus > 201703L 619 // _GLIBCXX_RESOLVE_LIB_DEFECTS 620 // 2996. Missing rvalue overloads for shared_ptr operations 621 622 /// Convert type of `shared_ptr` rvalue, via `static_cast` 623 template
624 inline shared_ptr<_Tp> 625 static_pointer_cast(shared_ptr<_Up>&& __r) noexcept 626 { 627 using _Sp = shared_ptr<_Tp>; 628 return _Sp(std::move(__r), 629 static_cast
(__r.get())); 630 } 631 632 /// Convert type of `shared_ptr` rvalue, via `const_cast` 633 template
634 inline shared_ptr<_Tp> 635 const_pointer_cast(shared_ptr<_Up>&& __r) noexcept 636 { 637 using _Sp = shared_ptr<_Tp>; 638 return _Sp(std::move(__r), 639 const_cast
(__r.get())); 640 } 641 642 /// Convert type of `shared_ptr` rvalue, via `dynamic_cast` 643 template
644 inline shared_ptr<_Tp> 645 dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept 646 { 647 using _Sp = shared_ptr<_Tp>; 648 if (auto* __p = dynamic_cast
(__r.get())) 649 return _Sp(std::move(__r), __p); 650 return _Sp(); 651 } 652 653 /// Convert type of `shared_ptr` rvalue, via `reinterpret_cast` 654 template
655 inline shared_ptr<_Tp> 656 reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept 657 { 658 using _Sp = shared_ptr<_Tp>; 659 return _Sp(std::move(__r), 660 reinterpret_cast
(__r.get())); 661 } 662 #endif // C++20 663 #endif // C++17 664 665 /// @} 666 667 /** 668 * @brief A non-owning observer for a pointer owned by a shared_ptr 669 * 670 * A weak_ptr provides a safe alternative to a raw pointer when you want 671 * a non-owning reference to an object that is managed by a shared_ptr. 672 * 673 * Unlike a raw pointer, a weak_ptr can be converted to a new shared_ptr 674 * that shares ownership with every other shared_ptr that already owns 675 * the pointer. In other words you can upgrade from a non-owning "weak" 676 * reference to an owning shared_ptr, without having access to any of 677 * the existing shared_ptr objects. 678 * 679 * Also unlike a raw pointer, a weak_ptr does not become "dangling" after 680 * the object it points to has been destroyed. Instead, a weak_ptr 681 * becomes _expired_ and can no longer be converted to a shared_ptr that 682 * owns the freed pointer, so you cannot accidentally access the pointed-to 683 * object after it has been destroyed. 684 */ 685 template
686 class weak_ptr : public __weak_ptr<_Tp> 687 { 688 template
689 using _Constructible = typename enable_if< 690 is_constructible<__weak_ptr<_Tp>, _Arg>::value 691 >::type; 692 693 template
694 using _Assignable = typename enable_if< 695 is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr& 696 >::type; 697 698 public: 699 constexpr weak_ptr() noexcept = default; 700 701 template
&>> 703 weak_ptr(const shared_ptr<_Yp>& __r) noexcept 704 : __weak_ptr<_Tp>(__r) { } 705 706 weak_ptr(const weak_ptr&) noexcept = default; 707 708 template
&>> 709 weak_ptr(const weak_ptr<_Yp>& __r) noexcept 710 : __weak_ptr<_Tp>(__r) { } 711 712 weak_ptr(weak_ptr&&) noexcept = default; 713 714 template
>> 715 weak_ptr(weak_ptr<_Yp>&& __r) noexcept 716 : __weak_ptr<_Tp>(std::move(__r)) { } 717 718 weak_ptr& 719 operator=(const weak_ptr& __r) noexcept = default; 720 721 template
722 _Assignable
&> 723 operator=(const weak_ptr<_Yp>& __r) noexcept 724 { 725 this->__weak_ptr<_Tp>::operator=(__r); 726 return *this; 727 } 728 729 template
730 _Assignable
&> 731 operator=(const shared_ptr<_Yp>& __r) noexcept 732 { 733 this->__weak_ptr<_Tp>::operator=(__r); 734 return *this; 735 } 736 737 weak_ptr& 738 operator=(weak_ptr&& __r) noexcept = default; 739 740 template
741 _Assignable
> 742 operator=(weak_ptr<_Yp>&& __r) noexcept 743 { 744 this->__weak_ptr<_Tp>::operator=(std::move(__r)); 745 return *this; 746 } 747 748 shared_ptr<_Tp> 749 lock() const noexcept 750 { return shared_ptr<_Tp>(*this, std::nothrow); } 751 }; 752 753 #if __cpp_deduction_guides >= 201606 754 template
755 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; 756 #endif 757 758 // 20.7.2.3.6 weak_ptr specialized algorithms. 759 /// Swap overload for weak_ptr 760 /// @relates weak_ptr 761 template
762 inline void 763 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept 764 { __a.swap(__b); } 765 766 767 /// Primary template owner_less 768 template
769 struct owner_less; 770 771 /// Void specialization of owner_less compares either shared_ptr or weak_ptr 772 template<> 773 struct owner_less
: _Sp_owner_less
774 { }; 775 776 /// Partial specialization of owner_less for shared_ptr. 777 template
778 struct owner_less
> 779 : public _Sp_owner_less
, weak_ptr<_Tp>> 780 { }; 781 782 /// Partial specialization of owner_less for weak_ptr. 783 template
784 struct owner_less
> 785 : public _Sp_owner_less
, shared_ptr<_Tp>> 786 { }; 787 788 /** 789 * @brief Base class allowing use of member function shared_from_this. 790 */ 791 template
792 class enable_shared_from_this 793 { 794 protected: 795 constexpr enable_shared_from_this() noexcept { } 796 797 enable_shared_from_this(const enable_shared_from_this&) noexcept { } 798 799 enable_shared_from_this& 800 operator=(const enable_shared_from_this&) noexcept 801 { return *this; } 802 803 ~enable_shared_from_this() { } 804 805 public: 806 shared_ptr<_Tp> 807 shared_from_this() 808 { return shared_ptr<_Tp>(this->_M_weak_this); } 809 810 shared_ptr
811 shared_from_this() const 812 { return shared_ptr
(this->_M_weak_this); } 813 814 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 815 #define __cpp_lib_enable_shared_from_this 201603 816 weak_ptr<_Tp> 817 weak_from_this() noexcept 818 { return this->_M_weak_this; } 819 820 weak_ptr
821 weak_from_this() const noexcept 822 { return this->_M_weak_this; } 823 #endif 824 825 private: 826 template
827 void 828 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept 829 { _M_weak_this._M_assign(__p, __n); } 830 831 // Found by ADL when this is an associated class. 832 friend const enable_shared_from_this* 833 __enable_shared_from_this_base(const __shared_count<>&, 834 const enable_shared_from_this* __p) 835 { return __p; } 836 837 template
838 friend class __shared_ptr; 839 840 mutable weak_ptr<_Tp> _M_weak_this; 841 }; 842 843 /// @relates shared_ptr @{ 844 845 /** 846 * @brief Create an object that is owned by a shared_ptr. 847 * @param __a An allocator. 848 * @param __args Arguments for the @a _Tp object's constructor. 849 * @return A shared_ptr that owns the newly created object. 850 * @throw An exception thrown from @a _Alloc::allocate or from the 851 * constructor of @a _Tp. 852 * 853 * A copy of @a __a will be used to allocate memory for the shared_ptr 854 * and the new object. 855 */ 856 template
857 inline shared_ptr<_Tp> 858 allocate_shared(const _Alloc& __a, _Args&&... __args) 859 { 860 static_assert(!is_array<_Tp>::value, "make_shared
not supported"); 861 862 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a}, 863 std::forward<_Args>(__args)...); 864 } 865 866 /** 867 * @brief Create an object that is owned by a shared_ptr. 868 * @param __args Arguments for the @a _Tp object's constructor. 869 * @return A shared_ptr that owns the newly created object. 870 * @throw std::bad_alloc, or an exception thrown from the 871 * constructor of @a _Tp. 872 */ 873 template
874 inline shared_ptr<_Tp> 875 make_shared(_Args&&... __args) 876 { 877 typedef typename std::remove_cv<_Tp>::type _Tp_nc; 878 return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), 879 std::forward<_Args>(__args)...); 880 } 881 882 /// std::hash specialization for shared_ptr. 883 template
884 struct hash
> 885 : public __hash_base
> 886 { 887 size_t 888 operator()(const shared_ptr<_Tp>& __s) const noexcept 889 { 890 return std::hash
::element_type*>()(__s.get()); 891 } 892 }; 893 894 /// @} relates shared_ptr 895 /// @} group pointer_abstractions 896 897 #if __cplusplus >= 201703L 898 namespace __detail::__variant 899 { 900 template
struct _Never_valueless_alt; // see
901 902 // Provide the strong exception-safety guarantee when emplacing a 903 // shared_ptr into a variant. 904 template
905 struct _Never_valueless_alt
> 906 : std::true_type 907 { }; 908 909 // Provide the strong exception-safety guarantee when emplacing a 910 // weak_ptr into a variant. 911 template
912 struct _Never_valueless_alt
> 913 : std::true_type 914 { }; 915 } // namespace __detail::__variant 916 #endif // C++17 917 918 _GLIBCXX_END_NAMESPACE_VERSION 919 } // namespace 920 921 #endif // _SHARED_PTR_H
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™