Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/tr1/shared_ptr.h
$ cat -n /usr/include/c++/13/tr1/shared_ptr.h 1 //
-*- C++ -*- 2 3 // Copyright (C) 2007-2023 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 // shared_count.hpp 26 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 27 28 // shared_ptr.hpp 29 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. 30 // Copyright (C) 2001, 2002, 2003 Peter Dimov 31 32 // weak_ptr.hpp 33 // Copyright (C) 2001, 2002, 2003 Peter Dimov 34 35 // enable_shared_from_this.hpp 36 // Copyright (C) 2002 Peter Dimov 37 38 // Distributed under the Boost Software License, Version 1.0. (See 39 // accompanying file LICENSE_1_0.txt or copy at 40 // http://www.boost.org/LICENSE_1_0.txt) 41 42 // GCC Note: based on version 1.32.0 of the Boost library. 43 44 /** @file tr1/shared_ptr.h 45 * This is an internal header file, included by other library headers. 46 * Do not attempt to use it directly. @headername{tr1/memory} 47 */ 48 49 #ifndef _TR1_SHARED_PTR_H 50 #define _TR1_SHARED_PTR_H 1 51 52 namespace std _GLIBCXX_VISIBILITY(default) 53 { 54 _GLIBCXX_BEGIN_NAMESPACE_VERSION 55 56 namespace tr1 57 { 58 /** 59 * @brief Exception possibly thrown by @c shared_ptr. 60 * @ingroup exceptions 61 */ 62 class bad_weak_ptr : public std::exception 63 { 64 public: 65 virtual char const* 66 what() const throw() 67 { return "tr1::bad_weak_ptr"; } 68 }; 69 70 // Substitute for bad_weak_ptr object in the case of -fno-exceptions. 71 inline void 72 __throw_bad_weak_ptr() 73 { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); } 74 75 using __gnu_cxx::_Lock_policy; 76 using __gnu_cxx::__default_lock_policy; 77 using __gnu_cxx::_S_single; 78 using __gnu_cxx::_S_mutex; 79 using __gnu_cxx::_S_atomic; 80 81 // Empty helper class except when the template argument is _S_mutex. 82 template<_Lock_policy _Lp> 83 class _Mutex_base 84 { 85 protected: 86 // The atomic policy uses fully-fenced builtins, single doesn't care. 87 enum { _S_need_barriers = 0 }; 88 }; 89 90 template<> 91 class _Mutex_base<_S_mutex> 92 : public __gnu_cxx::__mutex 93 { 94 protected: 95 // This policy is used when atomic builtins are not available. 96 // The replacement atomic operations might not have the necessary 97 // memory barriers. 98 enum { _S_need_barriers = 1 }; 99 }; 100 101 template<_Lock_policy _Lp = __default_lock_policy> 102 class _Sp_counted_base 103 : public _Mutex_base<_Lp> 104 { 105 public: 106 _Sp_counted_base() 107 : _M_use_count(1), _M_weak_count(1) { } 108 109 virtual 110 ~_Sp_counted_base() // nothrow 111 { } 112 113 // Called when _M_use_count drops to zero, to release the resources 114 // managed by *this. 115 virtual void 116 _M_dispose() = 0; // nothrow 117 118 // Called when _M_weak_count drops to zero. 119 virtual void 120 _M_destroy() // nothrow 121 { delete this; } 122 123 virtual void* 124 _M_get_deleter(const std::type_info&) = 0; 125 126 void 127 _M_add_ref_copy() 128 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } 129 130 void 131 _M_add_ref_lock(); 132 133 void 134 _M_release() // nothrow 135 { 136 // Be race-detector-friendly. For more info see bits/c++config. 137 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); 138 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) 139 { 140 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); 141 _M_dispose(); 142 // There must be a memory barrier between dispose() and destroy() 143 // to ensure that the effects of dispose() are observed in the 144 // thread that runs destroy(). 145 // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html 146 if (_Mutex_base<_Lp>::_S_need_barriers) 147 { 148 __atomic_thread_fence (__ATOMIC_ACQ_REL); 149 } 150 151 // Be race-detector-friendly. For more info see bits/c++config. 152 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 153 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, 154 -1) == 1) 155 { 156 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 157 _M_destroy(); 158 } 159 } 160 } 161 162 void 163 _M_weak_add_ref() // nothrow 164 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } 165 166 void 167 _M_weak_release() // nothrow 168 { 169 // Be race-detector-friendly. For more info see bits/c++config. 170 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 171 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) 172 { 173 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 174 if (_Mutex_base<_Lp>::_S_need_barriers) 175 { 176 // See _M_release(), 177 // destroy() must observe results of dispose() 178 __atomic_thread_fence (__ATOMIC_ACQ_REL); 179 } 180 _M_destroy(); 181 } 182 } 183 184 long 185 _M_get_use_count() const // nothrow 186 { 187 // No memory barrier is used here so there is no synchronization 188 // with other threads. 189 return const_cast
(_M_use_count); 190 } 191 192 private: 193 _Sp_counted_base(_Sp_counted_base const&); 194 _Sp_counted_base& operator=(_Sp_counted_base const&); 195 196 _Atomic_word _M_use_count; // #shared 197 _Atomic_word _M_weak_count; // #weak + (#shared != 0) 198 }; 199 200 template<> 201 inline void 202 _Sp_counted_base<_S_single>:: 203 _M_add_ref_lock() 204 { 205 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 206 { 207 _M_use_count = 0; 208 __throw_bad_weak_ptr(); 209 } 210 } 211 212 template<> 213 inline void 214 _Sp_counted_base<_S_mutex>:: 215 _M_add_ref_lock() 216 { 217 __gnu_cxx::__scoped_lock sentry(*this); 218 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 219 { 220 _M_use_count = 0; 221 __throw_bad_weak_ptr(); 222 } 223 } 224 225 template<> 226 inline void 227 _Sp_counted_base<_S_atomic>:: 228 _M_add_ref_lock() 229 { 230 // Perform lock-free add-if-not-zero operation. 231 _Atomic_word __count = _M_use_count; 232 do 233 { 234 if (__count == 0) 235 __throw_bad_weak_ptr(); 236 // Replace the current counter value with the old value + 1, as 237 // long as it's not changed meanwhile. 238 } 239 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, 240 true, __ATOMIC_ACQ_REL, 241 __ATOMIC_RELAXED)); 242 } 243 244 template
245 class _Sp_counted_base_impl 246 : public _Sp_counted_base<_Lp> 247 { 248 public: 249 // Precondition: __d(__p) must not throw. 250 _Sp_counted_base_impl(_Ptr __p, _Deleter __d) 251 : _M_ptr(__p), _M_del(__d) { } 252 253 virtual void 254 _M_dispose() // nothrow 255 { _M_del(_M_ptr); } 256 257 virtual void* 258 _M_get_deleter(const std::type_info& __ti) 259 { 260 #if __cpp_rtti 261 return __ti == typeid(_Deleter) ? &_M_del : 0; 262 #else 263 return 0; 264 #endif 265 } 266 267 private: 268 _Sp_counted_base_impl(const _Sp_counted_base_impl&); 269 _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&); 270 271 _Ptr _M_ptr; // copy constructor must not throw 272 _Deleter _M_del; // copy constructor must not throw 273 }; 274 275 template<_Lock_policy _Lp = __default_lock_policy> 276 class __weak_count; 277 278 template
279 struct _Sp_deleter 280 { 281 typedef void result_type; 282 typedef _Tp* argument_type; 283 void operator()(_Tp* __p) const { delete __p; } 284 }; 285 286 template<_Lock_policy _Lp = __default_lock_policy> 287 class __shared_count 288 { 289 public: 290 __shared_count() 291 : _M_pi(0) // nothrow 292 { } 293 294 template
295 __shared_count(_Ptr __p) : _M_pi(0) 296 { 297 __try 298 { 299 typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp; 300 _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>( 301 __p, _Sp_deleter<_Tp>()); 302 } 303 __catch(...) 304 { 305 delete __p; 306 __throw_exception_again; 307 } 308 } 309 310 template
311 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) 312 { 313 __try 314 { 315 _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d); 316 } 317 __catch(...) 318 { 319 __d(__p); // Call _Deleter on __p. 320 __throw_exception_again; 321 } 322 } 323 324 #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED 325 #pragma GCC diagnostic push 326 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 327 // Special case for auto_ptr<_Tp> to provide the strong guarantee. 328 template
329 explicit 330 __shared_count(std::auto_ptr<_Tp>& __r) 331 : _M_pi(new _Sp_counted_base_impl<_Tp*, 332 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>())) 333 { __r.release(); } 334 #pragma GCC diagnostic pop 335 #endif 336 337 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 338 explicit 339 __shared_count(const __weak_count<_Lp>& __r); 340 341 ~__shared_count() // nothrow 342 { 343 if (_M_pi != 0) 344 _M_pi->_M_release(); 345 } 346 347 __shared_count(const __shared_count& __r) 348 : _M_pi(__r._M_pi) // nothrow 349 { 350 if (_M_pi != 0) 351 _M_pi->_M_add_ref_copy(); 352 } 353 354 __shared_count& 355 operator=(const __shared_count& __r) // nothrow 356 { 357 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 358 if (__tmp != _M_pi) 359 { 360 if (__tmp != 0) 361 __tmp->_M_add_ref_copy(); 362 if (_M_pi != 0) 363 _M_pi->_M_release(); 364 _M_pi = __tmp; 365 } 366 return *this; 367 } 368 369 void 370 _M_swap(__shared_count& __r) // nothrow 371 { 372 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 373 __r._M_pi = _M_pi; 374 _M_pi = __tmp; 375 } 376 377 long 378 _M_get_use_count() const // nothrow 379 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 380 381 bool 382 _M_unique() const // nothrow 383 { return this->_M_get_use_count() == 1; } 384 385 friend inline bool 386 operator==(const __shared_count& __a, const __shared_count& __b) 387 { return __a._M_pi == __b._M_pi; } 388 389 friend inline bool 390 operator<(const __shared_count& __a, const __shared_count& __b) 391 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } 392 393 void* 394 _M_get_deleter(const std::type_info& __ti) const 395 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; } 396 397 private: 398 friend class __weak_count<_Lp>; 399 400 _Sp_counted_base<_Lp>* _M_pi; 401 }; 402 403 404 template<_Lock_policy _Lp> 405 class __weak_count 406 { 407 public: 408 __weak_count() 409 : _M_pi(0) // nothrow 410 { } 411 412 __weak_count(const __shared_count<_Lp>& __r) 413 : _M_pi(__r._M_pi) // nothrow 414 { 415 if (_M_pi != 0) 416 _M_pi->_M_weak_add_ref(); 417 } 418 419 __weak_count(const __weak_count<_Lp>& __r) 420 : _M_pi(__r._M_pi) // nothrow 421 { 422 if (_M_pi != 0) 423 _M_pi->_M_weak_add_ref(); 424 } 425 426 ~__weak_count() // nothrow 427 { 428 if (_M_pi != 0) 429 _M_pi->_M_weak_release(); 430 } 431 432 __weak_count<_Lp>& 433 operator=(const __shared_count<_Lp>& __r) // nothrow 434 { 435 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 436 if (__tmp != 0) 437 __tmp->_M_weak_add_ref(); 438 if (_M_pi != 0) 439 _M_pi->_M_weak_release(); 440 _M_pi = __tmp; 441 return *this; 442 } 443 444 __weak_count<_Lp>& 445 operator=(const __weak_count<_Lp>& __r) // nothrow 446 { 447 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 448 if (__tmp != 0) 449 __tmp->_M_weak_add_ref(); 450 if (_M_pi != 0) 451 _M_pi->_M_weak_release(); 452 _M_pi = __tmp; 453 return *this; 454 } 455 456 void 457 _M_swap(__weak_count<_Lp>& __r) // nothrow 458 { 459 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 460 __r._M_pi = _M_pi; 461 _M_pi = __tmp; 462 } 463 464 long 465 _M_get_use_count() const // nothrow 466 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 467 468 friend inline bool 469 operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) 470 { return __a._M_pi == __b._M_pi; } 471 472 friend inline bool 473 operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) 474 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } 475 476 private: 477 friend class __shared_count<_Lp>; 478 479 _Sp_counted_base<_Lp>* _M_pi; 480 }; 481 482 // now that __weak_count is defined we can define this constructor: 483 template<_Lock_policy _Lp> 484 inline 485 __shared_count<_Lp>:: 486 __shared_count(const __weak_count<_Lp>& __r) 487 : _M_pi(__r._M_pi) 488 { 489 if (_M_pi != 0) 490 _M_pi->_M_add_ref_lock(); 491 else 492 __throw_bad_weak_ptr(); 493 } 494 495 // Forward declarations. 496 template
497 class __shared_ptr; 498 499 template
500 class __weak_ptr; 501 502 template
503 class __enable_shared_from_this; 504 505 template
506 class shared_ptr; 507 508 template
509 class weak_ptr; 510 511 template
512 class enable_shared_from_this; 513 514 // Support for enable_shared_from_this. 515 516 // Friend of __enable_shared_from_this. 517 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> 518 void 519 __enable_shared_from_this_helper(const __shared_count<_Lp>&, 520 const __enable_shared_from_this<_Tp1, 521 _Lp>*, const _Tp2*); 522 523 // Friend of enable_shared_from_this. 524 template
525 void 526 __enable_shared_from_this_helper(const __shared_count<>&, 527 const enable_shared_from_this<_Tp1>*, 528 const _Tp2*); 529 530 template<_Lock_policy _Lp> 531 inline void 532 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) 533 { } 534 535 536 struct __static_cast_tag { }; 537 struct __const_cast_tag { }; 538 struct __dynamic_cast_tag { }; 539 540 // A smart pointer with reference-counted copy semantics. The 541 // object pointed to is deleted when the last shared_ptr pointing to 542 // it is destroyed or reset. 543 template
544 class __shared_ptr 545 { 546 public: 547 typedef _Tp element_type; 548 549 __shared_ptr() 550 : _M_ptr(0), _M_refcount() // never throws 551 { } 552 553 template
554 explicit 555 __shared_ptr(_Tp1* __p) 556 : _M_ptr(__p), _M_refcount(__p) 557 { 558 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 559 typedef int _IsComplete[sizeof(_Tp1)]; 560 __enable_shared_from_this_helper(_M_refcount, __p, __p); 561 } 562 563 template
564 __shared_ptr(_Tp1* __p, _Deleter __d) 565 : _M_ptr(__p), _M_refcount(__p, __d) 566 { 567 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 568 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 569 __enable_shared_from_this_helper(_M_refcount, __p, __p); 570 } 571 572 // generated copy constructor, assignment, destructor are fine. 573 574 template
575 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 576 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 577 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 578 579 template
580 explicit 581 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 582 : _M_refcount(__r._M_refcount) // may throw 583 { 584 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 585 // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount) 586 // did not throw. 587 _M_ptr = __r._M_ptr; 588 } 589 590 #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED 591 #pragma GCC diagnostic push 592 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 593 // Postcondition: use_count() == 1 and __r.get() == 0 594 template
595 explicit 596 __shared_ptr(std::auto_ptr<_Tp1>& __r) 597 : _M_ptr(__r.get()), _M_refcount() 598 { // TODO requries delete __r.release() well-formed 599 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 600 typedef int _IsComplete[sizeof(_Tp1)]; 601 _Tp1* __tmp = __r.get(); 602 _M_refcount = __shared_count<_Lp>(__r); 603 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); 604 } 605 #pragma GCC diagnostic pop 606 #endif 607 608 template
609 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag) 610 : _M_ptr(static_cast
(__r._M_ptr)), 611 _M_refcount(__r._M_refcount) 612 { } 613 614 template
615 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag) 616 : _M_ptr(const_cast
(__r._M_ptr)), 617 _M_refcount(__r._M_refcount) 618 { } 619 620 template
621 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag) 622 : _M_ptr(dynamic_cast
(__r._M_ptr)), 623 _M_refcount(__r._M_refcount) 624 { 625 if (_M_ptr == 0) // need to allocate new counter -- the cast failed 626 _M_refcount = __shared_count<_Lp>(); 627 } 628 629 template
630 __shared_ptr& 631 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 632 { 633 _M_ptr = __r._M_ptr; 634 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 635 return *this; 636 } 637 638 #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED 639 #pragma GCC diagnostic push 640 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 641 template
642 __shared_ptr& 643 operator=(std::auto_ptr<_Tp1>& __r) 644 { 645 __shared_ptr(__r).swap(*this); 646 return *this; 647 } 648 #pragma GCC diagnostic pop 649 #endif 650 651 void 652 reset() // never throws 653 { __shared_ptr().swap(*this); } 654 655 template
656 void 657 reset(_Tp1* __p) // _Tp1 must be complete. 658 { 659 // Catch self-reset errors. 660 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 661 __shared_ptr(__p).swap(*this); 662 } 663 664 template
665 void 666 reset(_Tp1* __p, _Deleter __d) 667 { __shared_ptr(__p, __d).swap(*this); } 668 669 // Allow class instantiation when _Tp is [cv-qual] void. 670 typename std::tr1::add_reference<_Tp>::type 671 operator*() const // never throws 672 { 673 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 674 return *_M_ptr; 675 } 676 677 _Tp* 678 operator->() const // never throws 679 { 680 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 681 return _M_ptr; 682 } 683 684 _Tp* 685 get() const // never throws 686 { return _M_ptr; } 687 688 // Implicit conversion to "bool" 689 private: 690 typedef _Tp* __shared_ptr::*__unspecified_bool_type; 691 692 public: 693 operator __unspecified_bool_type() const // never throws 694 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; } 695 696 bool 697 unique() const // never throws 698 { return _M_refcount._M_unique(); } 699 700 long 701 use_count() const // never throws 702 { return _M_refcount._M_get_use_count(); } 703 704 void 705 swap(__shared_ptr<_Tp, _Lp>& __other) // never throws 706 { 707 std::swap(_M_ptr, __other._M_ptr); 708 _M_refcount._M_swap(__other._M_refcount); 709 } 710 711 private: 712 void* 713 _M_get_deleter(const std::type_info& __ti) const 714 { return _M_refcount._M_get_deleter(__ti); } 715 716 template
717 bool 718 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const 719 { return _M_refcount < __rhs._M_refcount; } 720 721 template
friend class __shared_ptr; 722 template
friend class __weak_ptr; 723 724 template
725 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&); 726 727 // Friends injected into enclosing namespace and found by ADL: 728 template
729 friend inline bool 730 operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 731 { return __a.get() == __b.get(); } 732 733 template
734 friend inline bool 735 operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 736 { return __a.get() != __b.get(); } 737 738 template
739 friend inline bool 740 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 741 { return __a._M_less(__b); } 742 743 _Tp* _M_ptr; // Contained pointer. 744 __shared_count<_Lp> _M_refcount; // Reference counter. 745 }; 746 747 // 2.2.3.8 shared_ptr specialized algorithms. 748 template
749 inline void 750 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) 751 { __a.swap(__b); } 752 753 // 2.2.3.9 shared_ptr casts 754 /* The seemingly equivalent 755 * shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) 756 * will eventually result in undefined behaviour, 757 * attempting to delete the same object twice. 758 */ 759 template
760 inline __shared_ptr<_Tp, _Lp> 761 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 762 { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); } 763 764 /* The seemingly equivalent 765 * shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) 766 * will eventually result in undefined behaviour, 767 * attempting to delete the same object twice. 768 */ 769 template
770 inline __shared_ptr<_Tp, _Lp> 771 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 772 { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); } 773 774 /* The seemingly equivalent 775 * shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) 776 * will eventually result in undefined behaviour, 777 * attempting to delete the same object twice. 778 */ 779 template
780 inline __shared_ptr<_Tp, _Lp> 781 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 782 { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); } 783 784 // 2.2.3.7 shared_ptr I/O 785 template
786 std::basic_ostream<_Ch, _Tr>& 787 operator<<(std::basic_ostream<_Ch, _Tr>& __os, 788 const __shared_ptr<_Tp, _Lp>& __p) 789 { 790 __os << __p.get(); 791 return __os; 792 } 793 794 // 2.2.3.10 shared_ptr get_deleter (experimental) 795 template
796 inline _Del* 797 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) 798 { 799 #if __cpp_rtti 800 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 801 #else 802 return 0; 803 #endif 804 } 805 806 807 template
808 class __weak_ptr 809 { 810 public: 811 typedef _Tp element_type; 812 813 __weak_ptr() 814 : _M_ptr(0), _M_refcount() // never throws 815 { } 816 817 // Generated copy constructor, assignment, destructor are fine. 818 819 // The "obvious" converting constructor implementation: 820 // 821 // template
822 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 823 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 824 // { } 825 // 826 // has a serious problem. 827 // 828 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 829 // conversion may require access to *__r._M_ptr (virtual inheritance). 830 // 831 // It is not possible to avoid spurious access violations since 832 // in multithreaded programs __r._M_ptr may be invalidated at any point. 833 template
834 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 835 : _M_refcount(__r._M_refcount) // never throws 836 { 837 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 838 _M_ptr = __r.lock().get(); 839 } 840 841 template
842 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 843 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 844 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 845 846 template
847 __weak_ptr& 848 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws 849 { 850 _M_ptr = __r.lock().get(); 851 _M_refcount = __r._M_refcount; 852 return *this; 853 } 854 855 template
856 __weak_ptr& 857 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 858 { 859 _M_ptr = __r._M_ptr; 860 _M_refcount = __r._M_refcount; 861 return *this; 862 } 863 864 __shared_ptr<_Tp, _Lp> 865 lock() const // never throws 866 { 867 #ifdef __GTHREADS 868 // Optimization: avoid throw overhead. 869 if (expired()) 870 return __shared_ptr
(); 871 872 __try 873 { 874 return __shared_ptr
(*this); 875 } 876 __catch(const bad_weak_ptr&) 877 { 878 // Q: How can we get here? 879 // A: Another thread may have invalidated r after the 880 // use_count test above. 881 return __shared_ptr
(); 882 } 883 884 #else 885 // Optimization: avoid try/catch overhead when single threaded. 886 return expired() ? __shared_ptr
() 887 : __shared_ptr
(*this); 888 889 #endif 890 } // XXX MT 891 892 long 893 use_count() const // never throws 894 { return _M_refcount._M_get_use_count(); } 895 896 bool 897 expired() const // never throws 898 { return _M_refcount._M_get_use_count() == 0; } 899 900 void 901 reset() // never throws 902 { __weak_ptr().swap(*this); } 903 904 void 905 swap(__weak_ptr& __s) // never throws 906 { 907 std::swap(_M_ptr, __s._M_ptr); 908 _M_refcount._M_swap(__s._M_refcount); 909 } 910 911 private: 912 // Used by __enable_shared_from_this. 913 void 914 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) 915 { 916 _M_ptr = __ptr; 917 _M_refcount = __refcount; 918 } 919 920 template
921 bool 922 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const 923 { return _M_refcount < __rhs._M_refcount; } 924 925 template
friend class __shared_ptr; 926 template
friend class __weak_ptr; 927 friend class __enable_shared_from_this<_Tp, _Lp>; 928 friend class enable_shared_from_this<_Tp>; 929 930 // Friend injected into namespace and found by ADL. 931 template
932 friend inline bool 933 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs) 934 { return __lhs._M_less(__rhs); } 935 936 _Tp* _M_ptr; // Contained pointer. 937 __weak_count<_Lp> _M_refcount; // Reference counter. 938 }; 939 940 // 2.2.4.7 weak_ptr specialized algorithms. 941 template
942 inline void 943 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) 944 { __a.swap(__b); } 945 946 947 template
948 class __enable_shared_from_this 949 { 950 protected: 951 __enable_shared_from_this() { } 952 953 __enable_shared_from_this(const __enable_shared_from_this&) { } 954 955 __enable_shared_from_this& 956 operator=(const __enable_shared_from_this&) 957 { return *this; } 958 959 ~__enable_shared_from_this() { } 960 961 public: 962 __shared_ptr<_Tp, _Lp> 963 shared_from_this() 964 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 965 966 __shared_ptr
967 shared_from_this() const 968 { return __shared_ptr
(this->_M_weak_this); } 969 970 private: 971 template
972 void 973 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const 974 { _M_weak_this._M_assign(__p, __n); } 975 976 template
977 friend void 978 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, 979 const __enable_shared_from_this* __pe, 980 const _Tp1* __px) 981 { 982 if (__pe != 0) 983 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 984 } 985 986 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 987 }; 988 989 990 // The actual shared_ptr, with forwarding constructors and 991 // assignment operators. 992 template
993 class shared_ptr 994 : public __shared_ptr<_Tp> 995 { 996 public: 997 shared_ptr() 998 : __shared_ptr<_Tp>() { } 999 1000 template
1001 explicit 1002 shared_ptr(_Tp1* __p) 1003 : __shared_ptr<_Tp>(__p) { } 1004 1005 template
1006 shared_ptr(_Tp1* __p, _Deleter __d) 1007 : __shared_ptr<_Tp>(__p, __d) { } 1008 1009 template
1010 shared_ptr(const shared_ptr<_Tp1>& __r) 1011 : __shared_ptr<_Tp>(__r) { } 1012 1013 template
1014 explicit 1015 shared_ptr(const weak_ptr<_Tp1>& __r) 1016 : __shared_ptr<_Tp>(__r) { } 1017 1018 #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED 1019 #pragma GCC diagnostic push 1020 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 1021 template
1022 explicit 1023 shared_ptr(std::auto_ptr<_Tp1>& __r) 1024 : __shared_ptr<_Tp>(__r) { } 1025 #pragma GCC diagnostic pop 1026 #endif 1027 1028 template
1029 shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag) 1030 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { } 1031 1032 template
1033 shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag) 1034 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { } 1035 1036 template
1037 shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag) 1038 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { } 1039 1040 template
1041 shared_ptr& 1042 operator=(const shared_ptr<_Tp1>& __r) // never throws 1043 { 1044 this->__shared_ptr<_Tp>::operator=(__r); 1045 return *this; 1046 } 1047 1048 #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED 1049 #pragma GCC diagnostic push 1050 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 1051 template
1052 shared_ptr& 1053 operator=(std::auto_ptr<_Tp1>& __r) 1054 { 1055 this->__shared_ptr<_Tp>::operator=(__r); 1056 return *this; 1057 } 1058 #pragma GCC diagnostic pop 1059 #endif 1060 }; 1061 1062 // 2.2.3.8 shared_ptr specialized algorithms. 1063 template
1064 inline void 1065 swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b) 1066 { __a.swap(__b); } 1067 1068 template
1069 inline shared_ptr<_Tp> 1070 static_pointer_cast(const shared_ptr<_Tp1>& __r) 1071 { return shared_ptr<_Tp>(__r, __static_cast_tag()); } 1072 1073 template
1074 inline shared_ptr<_Tp> 1075 const_pointer_cast(const shared_ptr<_Tp1>& __r) 1076 { return shared_ptr<_Tp>(__r, __const_cast_tag()); } 1077 1078 template
1079 inline shared_ptr<_Tp> 1080 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) 1081 { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); } 1082 1083 1084 // The actual weak_ptr, with forwarding constructors and 1085 // assignment operators. 1086 template
1087 class weak_ptr 1088 : public __weak_ptr<_Tp> 1089 { 1090 public: 1091 weak_ptr() 1092 : __weak_ptr<_Tp>() { } 1093 1094 template
1095 weak_ptr(const weak_ptr<_Tp1>& __r) 1096 : __weak_ptr<_Tp>(__r) { } 1097 1098 template
1099 weak_ptr(const shared_ptr<_Tp1>& __r) 1100 : __weak_ptr<_Tp>(__r) { } 1101 1102 template
1103 weak_ptr& 1104 operator=(const weak_ptr<_Tp1>& __r) // never throws 1105 { 1106 this->__weak_ptr<_Tp>::operator=(__r); 1107 return *this; 1108 } 1109 1110 template
1111 weak_ptr& 1112 operator=(const shared_ptr<_Tp1>& __r) // never throws 1113 { 1114 this->__weak_ptr<_Tp>::operator=(__r); 1115 return *this; 1116 } 1117 1118 shared_ptr<_Tp> 1119 lock() const // never throws 1120 { 1121 #ifdef __GTHREADS 1122 if (this->expired()) 1123 return shared_ptr<_Tp>(); 1124 1125 __try 1126 { 1127 return shared_ptr<_Tp>(*this); 1128 } 1129 __catch(const bad_weak_ptr&) 1130 { 1131 return shared_ptr<_Tp>(); 1132 } 1133 #else 1134 return this->expired() ? shared_ptr<_Tp>() 1135 : shared_ptr<_Tp>(*this); 1136 #endif 1137 } 1138 }; 1139 1140 template
1141 class enable_shared_from_this 1142 { 1143 protected: 1144 enable_shared_from_this() { } 1145 1146 enable_shared_from_this(const enable_shared_from_this&) { } 1147 1148 enable_shared_from_this& 1149 operator=(const enable_shared_from_this&) 1150 { return *this; } 1151 1152 ~enable_shared_from_this() { } 1153 1154 public: 1155 shared_ptr<_Tp> 1156 shared_from_this() 1157 { return shared_ptr<_Tp>(this->_M_weak_this); } 1158 1159 shared_ptr
1160 shared_from_this() const 1161 { return shared_ptr
(this->_M_weak_this); } 1162 1163 private: 1164 template
1165 void 1166 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const 1167 { _M_weak_this._M_assign(__p, __n); } 1168 1169 template
1170 friend void 1171 __enable_shared_from_this_helper(const __shared_count<>& __pn, 1172 const enable_shared_from_this* __pe, 1173 const _Tp1* __px) 1174 { 1175 if (__pe != 0) 1176 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 1177 } 1178 1179 mutable weak_ptr<_Tp> _M_weak_this; 1180 }; 1181 } 1182 1183 _GLIBCXX_END_NAMESPACE_VERSION 1184 } 1185 1186 #endif // _TR1_SHARED_PTR_H
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™