libstdc++
|
00001 // shared_ptr and weak_ptr implementation details -*- C++ -*- 00002 00003 // Copyright (C) 2007-2015 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 // GCC Note: Based on files from version 1.32.0 of the Boost library. 00026 00027 // shared_count.hpp 00028 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 00029 00030 // shared_ptr.hpp 00031 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. 00032 // Copyright (C) 2001, 2002, 2003 Peter Dimov 00033 00034 // weak_ptr.hpp 00035 // Copyright (C) 2001, 2002, 2003 Peter Dimov 00036 00037 // enable_shared_from_this.hpp 00038 // Copyright (C) 2002 Peter Dimov 00039 00040 // Distributed under the Boost Software License, Version 1.0. (See 00041 // accompanying file LICENSE_1_0.txt or copy at 00042 // http://www.boost.org/LICENSE_1_0.txt) 00043 00044 /** @file bits/shared_ptr_base.h 00045 * This is an internal header file, included by other library headers. 00046 * Do not attempt to use it directly. @headername{memory} 00047 */ 00048 00049 #ifndef _SHARED_PTR_BASE_H 00050 #define _SHARED_PTR_BASE_H 1 00051 00052 #include <bits/allocated_ptr.h> 00053 #include <ext/aligned_buffer.h> 00054 00055 namespace std _GLIBCXX_VISIBILITY(default) 00056 { 00057 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00058 00059 #if _GLIBCXX_USE_DEPRECATED 00060 template<typename> class auto_ptr; 00061 #endif 00062 00063 /** 00064 * @brief Exception possibly thrown by @c shared_ptr. 00065 * @ingroup exceptions 00066 */ 00067 class bad_weak_ptr : public std::exception 00068 { 00069 public: 00070 virtual char const* 00071 what() const noexcept; 00072 00073 virtual ~bad_weak_ptr() noexcept; 00074 }; 00075 00076 // Substitute for bad_weak_ptr object in the case of -fno-exceptions. 00077 inline void 00078 __throw_bad_weak_ptr() 00079 { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); } 00080 00081 using __gnu_cxx::_Lock_policy; 00082 using __gnu_cxx::__default_lock_policy; 00083 using __gnu_cxx::_S_single; 00084 using __gnu_cxx::_S_mutex; 00085 using __gnu_cxx::_S_atomic; 00086 00087 // Empty helper class except when the template argument is _S_mutex. 00088 template<_Lock_policy _Lp> 00089 class _Mutex_base 00090 { 00091 protected: 00092 // The atomic policy uses fully-fenced builtins, single doesn't care. 00093 enum { _S_need_barriers = 0 }; 00094 }; 00095 00096 template<> 00097 class _Mutex_base<_S_mutex> 00098 : public __gnu_cxx::__mutex 00099 { 00100 protected: 00101 // This policy is used when atomic builtins are not available. 00102 // The replacement atomic operations might not have the necessary 00103 // memory barriers. 00104 enum { _S_need_barriers = 1 }; 00105 }; 00106 00107 template<_Lock_policy _Lp = __default_lock_policy> 00108 class _Sp_counted_base 00109 : public _Mutex_base<_Lp> 00110 { 00111 public: 00112 _Sp_counted_base() noexcept 00113 : _M_use_count(1), _M_weak_count(1) { } 00114 00115 virtual 00116 ~_Sp_counted_base() noexcept 00117 { } 00118 00119 // Called when _M_use_count drops to zero, to release the resources 00120 // managed by *this. 00121 virtual void 00122 _M_dispose() noexcept = 0; 00123 00124 // Called when _M_weak_count drops to zero. 00125 virtual void 00126 _M_destroy() noexcept 00127 { delete this; } 00128 00129 virtual void* 00130 _M_get_deleter(const std::type_info&) noexcept = 0; 00131 00132 void 00133 _M_add_ref_copy() 00134 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } 00135 00136 void 00137 _M_add_ref_lock(); 00138 00139 bool 00140 _M_add_ref_lock_nothrow(); 00141 00142 void 00143 _M_release() noexcept 00144 { 00145 // Be race-detector-friendly. For more info see bits/c++config. 00146 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); 00147 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) 00148 { 00149 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); 00150 _M_dispose(); 00151 // There must be a memory barrier between dispose() and destroy() 00152 // to ensure that the effects of dispose() are observed in the 00153 // thread that runs destroy(). 00154 // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html 00155 if (_Mutex_base<_Lp>::_S_need_barriers) 00156 { 00157 _GLIBCXX_READ_MEM_BARRIER; 00158 _GLIBCXX_WRITE_MEM_BARRIER; 00159 } 00160 00161 // Be race-detector-friendly. For more info see bits/c++config. 00162 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 00163 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, 00164 -1) == 1) 00165 { 00166 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 00167 _M_destroy(); 00168 } 00169 } 00170 } 00171 00172 void 00173 _M_weak_add_ref() noexcept 00174 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } 00175 00176 void 00177 _M_weak_release() noexcept 00178 { 00179 // Be race-detector-friendly. For more info see bits/c++config. 00180 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 00181 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) 00182 { 00183 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 00184 if (_Mutex_base<_Lp>::_S_need_barriers) 00185 { 00186 // See _M_release(), 00187 // destroy() must observe results of dispose() 00188 _GLIBCXX_READ_MEM_BARRIER; 00189 _GLIBCXX_WRITE_MEM_BARRIER; 00190 } 00191 _M_destroy(); 00192 } 00193 } 00194 00195 long 00196 _M_get_use_count() const noexcept 00197 { 00198 // No memory barrier is used here so there is no synchronization 00199 // with other threads. 00200 return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED); 00201 } 00202 00203 private: 00204 _Sp_counted_base(_Sp_counted_base const&) = delete; 00205 _Sp_counted_base& operator=(_Sp_counted_base const&) = delete; 00206 00207 _Atomic_word _M_use_count; // #shared 00208 _Atomic_word _M_weak_count; // #weak + (#shared != 0) 00209 }; 00210 00211 template<> 00212 inline void 00213 _Sp_counted_base<_S_single>:: 00214 _M_add_ref_lock() 00215 { 00216 if (_M_use_count == 0) 00217 __throw_bad_weak_ptr(); 00218 ++_M_use_count; 00219 } 00220 00221 template<> 00222 inline void 00223 _Sp_counted_base<_S_mutex>:: 00224 _M_add_ref_lock() 00225 { 00226 __gnu_cxx::__scoped_lock sentry(*this); 00227 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 00228 { 00229 _M_use_count = 0; 00230 __throw_bad_weak_ptr(); 00231 } 00232 } 00233 00234 template<> 00235 inline void 00236 _Sp_counted_base<_S_atomic>:: 00237 _M_add_ref_lock() 00238 { 00239 // Perform lock-free add-if-not-zero operation. 00240 _Atomic_word __count = _M_get_use_count(); 00241 do 00242 { 00243 if (__count == 0) 00244 __throw_bad_weak_ptr(); 00245 // Replace the current counter value with the old value + 1, as 00246 // long as it's not changed meanwhile. 00247 } 00248 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, 00249 true, __ATOMIC_ACQ_REL, 00250 __ATOMIC_RELAXED)); 00251 } 00252 00253 template<> 00254 inline bool 00255 _Sp_counted_base<_S_single>:: 00256 _M_add_ref_lock_nothrow() 00257 { 00258 if (_M_use_count == 0) 00259 return false; 00260 ++_M_use_count; 00261 return true; 00262 } 00263 00264 template<> 00265 inline bool 00266 _Sp_counted_base<_S_mutex>:: 00267 _M_add_ref_lock_nothrow() 00268 { 00269 __gnu_cxx::__scoped_lock sentry(*this); 00270 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 00271 { 00272 _M_use_count = 0; 00273 return false; 00274 } 00275 return true; 00276 } 00277 00278 template<> 00279 inline bool 00280 _Sp_counted_base<_S_atomic>:: 00281 _M_add_ref_lock_nothrow() 00282 { 00283 // Perform lock-free add-if-not-zero operation. 00284 _Atomic_word __count = _M_get_use_count(); 00285 do 00286 { 00287 if (__count == 0) 00288 return false; 00289 // Replace the current counter value with the old value + 1, as 00290 // long as it's not changed meanwhile. 00291 } 00292 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, 00293 true, __ATOMIC_ACQ_REL, 00294 __ATOMIC_RELAXED)); 00295 return true; 00296 } 00297 00298 template<> 00299 inline void 00300 _Sp_counted_base<_S_single>::_M_add_ref_copy() 00301 { ++_M_use_count; } 00302 00303 template<> 00304 inline void 00305 _Sp_counted_base<_S_single>::_M_release() noexcept 00306 { 00307 if (--_M_use_count == 0) 00308 { 00309 _M_dispose(); 00310 if (--_M_weak_count == 0) 00311 _M_destroy(); 00312 } 00313 } 00314 00315 template<> 00316 inline void 00317 _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept 00318 { ++_M_weak_count; } 00319 00320 template<> 00321 inline void 00322 _Sp_counted_base<_S_single>::_M_weak_release() noexcept 00323 { 00324 if (--_M_weak_count == 0) 00325 _M_destroy(); 00326 } 00327 00328 template<> 00329 inline long 00330 _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept 00331 { return _M_use_count; } 00332 00333 00334 // Forward declarations. 00335 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 00336 class __shared_ptr; 00337 00338 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 00339 class __weak_ptr; 00340 00341 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 00342 class __enable_shared_from_this; 00343 00344 template<typename _Tp> 00345 class shared_ptr; 00346 00347 template<typename _Tp> 00348 class weak_ptr; 00349 00350 template<typename _Tp> 00351 struct owner_less; 00352 00353 template<typename _Tp> 00354 class enable_shared_from_this; 00355 00356 template<_Lock_policy _Lp = __default_lock_policy> 00357 class __weak_count; 00358 00359 template<_Lock_policy _Lp = __default_lock_policy> 00360 class __shared_count; 00361 00362 00363 // Counted ptr with no deleter or allocator support 00364 template<typename _Ptr, _Lock_policy _Lp> 00365 class _Sp_counted_ptr final : public _Sp_counted_base<_Lp> 00366 { 00367 public: 00368 explicit 00369 _Sp_counted_ptr(_Ptr __p) noexcept 00370 : _M_ptr(__p) { } 00371 00372 virtual void 00373 _M_dispose() noexcept 00374 { delete _M_ptr; } 00375 00376 virtual void 00377 _M_destroy() noexcept 00378 { delete this; } 00379 00380 virtual void* 00381 _M_get_deleter(const std::type_info&) noexcept 00382 { return nullptr; } 00383 00384 _Sp_counted_ptr(const _Sp_counted_ptr&) = delete; 00385 _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete; 00386 00387 private: 00388 _Ptr _M_ptr; 00389 }; 00390 00391 template<> 00392 inline void 00393 _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { } 00394 00395 template<> 00396 inline void 00397 _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { } 00398 00399 template<> 00400 inline void 00401 _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { } 00402 00403 template<int _Nm, typename _Tp, 00404 bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)> 00405 struct _Sp_ebo_helper; 00406 00407 /// Specialization using EBO. 00408 template<int _Nm, typename _Tp> 00409 struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp 00410 { 00411 explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { } 00412 00413 static _Tp& 00414 _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); } 00415 }; 00416 00417 /// Specialization not using EBO. 00418 template<int _Nm, typename _Tp> 00419 struct _Sp_ebo_helper<_Nm, _Tp, false> 00420 { 00421 explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { } 00422 00423 static _Tp& 00424 _S_get(_Sp_ebo_helper& __eboh) 00425 { return __eboh._M_tp; } 00426 00427 private: 00428 _Tp _M_tp; 00429 }; 00430 00431 // Support for custom deleter and/or allocator 00432 template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp> 00433 class _Sp_counted_deleter final : public _Sp_counted_base<_Lp> 00434 { 00435 class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc> 00436 { 00437 typedef _Sp_ebo_helper<0, _Deleter> _Del_base; 00438 typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base; 00439 00440 public: 00441 _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept 00442 : _M_ptr(__p), _Del_base(__d), _Alloc_base(__a) 00443 { } 00444 00445 _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); } 00446 _Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); } 00447 00448 _Ptr _M_ptr; 00449 }; 00450 00451 public: 00452 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>; 00453 00454 // __d(__p) must not throw. 00455 _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept 00456 : _M_impl(__p, __d, _Alloc()) { } 00457 00458 // __d(__p) must not throw. 00459 _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept 00460 : _M_impl(__p, __d, __a) { } 00461 00462 ~_Sp_counted_deleter() noexcept { } 00463 00464 virtual void 00465 _M_dispose() noexcept 00466 { _M_impl._M_del()(_M_impl._M_ptr); } 00467 00468 virtual void 00469 _M_destroy() noexcept 00470 { 00471 __allocator_type __a(_M_impl._M_alloc()); 00472 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; 00473 this->~_Sp_counted_deleter(); 00474 } 00475 00476 virtual void* 00477 _M_get_deleter(const std::type_info& __ti) noexcept 00478 { 00479 #if __cpp_rtti 00480 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00481 // 2400. shared_ptr's get_deleter() should use addressof() 00482 return __ti == typeid(_Deleter) 00483 ? std::__addressof(_M_impl._M_del()) 00484 : nullptr; 00485 #else 00486 return nullptr; 00487 #endif 00488 } 00489 00490 private: 00491 _Impl _M_impl; 00492 }; 00493 00494 // helpers for make_shared / allocate_shared 00495 00496 struct _Sp_make_shared_tag { }; 00497 00498 template<typename _Tp, typename _Alloc, _Lock_policy _Lp> 00499 class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> 00500 { 00501 class _Impl : _Sp_ebo_helper<0, _Alloc> 00502 { 00503 typedef _Sp_ebo_helper<0, _Alloc> _A_base; 00504 00505 public: 00506 explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { } 00507 00508 _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); } 00509 00510 __gnu_cxx::__aligned_buffer<_Tp> _M_storage; 00511 }; 00512 00513 public: 00514 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>; 00515 00516 template<typename... _Args> 00517 _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args) 00518 : _M_impl(__a) 00519 { 00520 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00521 // 2070. allocate_shared should use allocator_traits<A>::construct 00522 allocator_traits<_Alloc>::construct(__a, _M_ptr(), 00523 std::forward<_Args>(__args)...); // might throw 00524 } 00525 00526 ~_Sp_counted_ptr_inplace() noexcept { } 00527 00528 virtual void 00529 _M_dispose() noexcept 00530 { 00531 allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr()); 00532 } 00533 00534 // Override because the allocator needs to know the dynamic type 00535 virtual void 00536 _M_destroy() noexcept 00537 { 00538 __allocator_type __a(_M_impl._M_alloc()); 00539 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; 00540 this->~_Sp_counted_ptr_inplace(); 00541 } 00542 00543 // Sneaky trick so __shared_ptr can get the managed pointer 00544 virtual void* 00545 _M_get_deleter(const std::type_info& __ti) noexcept 00546 { 00547 #if __cpp_rtti 00548 if (__ti == typeid(_Sp_make_shared_tag)) 00549 return const_cast<typename remove_cv<_Tp>::type*>(_M_ptr()); 00550 #endif 00551 return nullptr; 00552 } 00553 00554 private: 00555 _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); } 00556 00557 _Impl _M_impl; 00558 }; 00559 00560 00561 template<_Lock_policy _Lp> 00562 class __shared_count 00563 { 00564 public: 00565 constexpr __shared_count() noexcept : _M_pi(0) 00566 { } 00567 00568 template<typename _Ptr> 00569 explicit 00570 __shared_count(_Ptr __p) : _M_pi(0) 00571 { 00572 __try 00573 { 00574 _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); 00575 } 00576 __catch(...) 00577 { 00578 delete __p; 00579 __throw_exception_again; 00580 } 00581 } 00582 00583 template<typename _Ptr, typename _Deleter> 00584 __shared_count(_Ptr __p, _Deleter __d) 00585 : __shared_count(__p, std::move(__d), allocator<void>()) 00586 { } 00587 00588 template<typename _Ptr, typename _Deleter, typename _Alloc> 00589 __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) 00590 { 00591 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; 00592 __try 00593 { 00594 typename _Sp_cd_type::__allocator_type __a2(__a); 00595 auto __guard = std::__allocate_guarded(__a2); 00596 _Sp_cd_type* __mem = __guard.get(); 00597 ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a)); 00598 _M_pi = __mem; 00599 __guard = nullptr; 00600 } 00601 __catch(...) 00602 { 00603 __d(__p); // Call _Deleter on __p. 00604 __throw_exception_again; 00605 } 00606 } 00607 00608 template<typename _Tp, typename _Alloc, typename... _Args> 00609 __shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a, 00610 _Args&&... __args) 00611 : _M_pi(0) 00612 { 00613 typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type; 00614 typename _Sp_cp_type::__allocator_type __a2(__a); 00615 auto __guard = std::__allocate_guarded(__a2); 00616 _Sp_cp_type* __mem = __guard.get(); 00617 ::new (__mem) _Sp_cp_type(std::move(__a), 00618 std::forward<_Args>(__args)...); 00619 _M_pi = __mem; 00620 __guard = nullptr; 00621 } 00622 00623 #if _GLIBCXX_USE_DEPRECATED 00624 // Special case for auto_ptr<_Tp> to provide the strong guarantee. 00625 template<typename _Tp> 00626 explicit 00627 __shared_count(std::auto_ptr<_Tp>&& __r); 00628 #endif 00629 00630 // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee. 00631 template<typename _Tp, typename _Del> 00632 explicit 00633 __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0) 00634 { 00635 using _Ptr = typename unique_ptr<_Tp, _Del>::pointer; 00636 using _Del2 = typename conditional<is_reference<_Del>::value, 00637 reference_wrapper<typename remove_reference<_Del>::type>, 00638 _Del>::type; 00639 using _Sp_cd_type 00640 = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>; 00641 using _Alloc = allocator<_Sp_cd_type>; 00642 using _Alloc_traits = allocator_traits<_Alloc>; 00643 _Alloc __a; 00644 _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1); 00645 _Alloc_traits::construct(__a, __mem, __r.release(), 00646 __r.get_deleter()); // non-throwing 00647 _M_pi = __mem; 00648 } 00649 00650 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 00651 explicit __shared_count(const __weak_count<_Lp>& __r); 00652 00653 // Does not throw if __r._M_get_use_count() == 0, caller must check. 00654 explicit __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t); 00655 00656 ~__shared_count() noexcept 00657 { 00658 if (_M_pi != nullptr) 00659 _M_pi->_M_release(); 00660 } 00661 00662 __shared_count(const __shared_count& __r) noexcept 00663 : _M_pi(__r._M_pi) 00664 { 00665 if (_M_pi != 0) 00666 _M_pi->_M_add_ref_copy(); 00667 } 00668 00669 __shared_count& 00670 operator=(const __shared_count& __r) noexcept 00671 { 00672 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00673 if (__tmp != _M_pi) 00674 { 00675 if (__tmp != 0) 00676 __tmp->_M_add_ref_copy(); 00677 if (_M_pi != 0) 00678 _M_pi->_M_release(); 00679 _M_pi = __tmp; 00680 } 00681 return *this; 00682 } 00683 00684 void 00685 _M_swap(__shared_count& __r) noexcept 00686 { 00687 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00688 __r._M_pi = _M_pi; 00689 _M_pi = __tmp; 00690 } 00691 00692 long 00693 _M_get_use_count() const noexcept 00694 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 00695 00696 bool 00697 _M_unique() const noexcept 00698 { return this->_M_get_use_count() == 1; } 00699 00700 void* 00701 _M_get_deleter(const std::type_info& __ti) const noexcept 00702 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; } 00703 00704 bool 00705 _M_less(const __shared_count& __rhs) const noexcept 00706 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00707 00708 bool 00709 _M_less(const __weak_count<_Lp>& __rhs) const noexcept 00710 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00711 00712 // Friend function injected into enclosing namespace and found by ADL 00713 friend inline bool 00714 operator==(const __shared_count& __a, const __shared_count& __b) noexcept 00715 { return __a._M_pi == __b._M_pi; } 00716 00717 private: 00718 friend class __weak_count<_Lp>; 00719 00720 _Sp_counted_base<_Lp>* _M_pi; 00721 }; 00722 00723 00724 template<_Lock_policy _Lp> 00725 class __weak_count 00726 { 00727 public: 00728 constexpr __weak_count() noexcept : _M_pi(nullptr) 00729 { } 00730 00731 __weak_count(const __shared_count<_Lp>& __r) noexcept 00732 : _M_pi(__r._M_pi) 00733 { 00734 if (_M_pi != nullptr) 00735 _M_pi->_M_weak_add_ref(); 00736 } 00737 00738 __weak_count(const __weak_count& __r) noexcept 00739 : _M_pi(__r._M_pi) 00740 { 00741 if (_M_pi != nullptr) 00742 _M_pi->_M_weak_add_ref(); 00743 } 00744 00745 __weak_count(__weak_count&& __r) noexcept 00746 : _M_pi(__r._M_pi) 00747 { __r._M_pi = nullptr; } 00748 00749 ~__weak_count() noexcept 00750 { 00751 if (_M_pi != nullptr) 00752 _M_pi->_M_weak_release(); 00753 } 00754 00755 __weak_count& 00756 operator=(const __shared_count<_Lp>& __r) noexcept 00757 { 00758 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00759 if (__tmp != nullptr) 00760 __tmp->_M_weak_add_ref(); 00761 if (_M_pi != nullptr) 00762 _M_pi->_M_weak_release(); 00763 _M_pi = __tmp; 00764 return *this; 00765 } 00766 00767 __weak_count& 00768 operator=(const __weak_count& __r) noexcept 00769 { 00770 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00771 if (__tmp != nullptr) 00772 __tmp->_M_weak_add_ref(); 00773 if (_M_pi != nullptr) 00774 _M_pi->_M_weak_release(); 00775 _M_pi = __tmp; 00776 return *this; 00777 } 00778 00779 __weak_count& 00780 operator=(__weak_count&& __r) noexcept 00781 { 00782 if (_M_pi != nullptr) 00783 _M_pi->_M_weak_release(); 00784 _M_pi = __r._M_pi; 00785 __r._M_pi = nullptr; 00786 return *this; 00787 } 00788 00789 void 00790 _M_swap(__weak_count& __r) noexcept 00791 { 00792 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00793 __r._M_pi = _M_pi; 00794 _M_pi = __tmp; 00795 } 00796 00797 long 00798 _M_get_use_count() const noexcept 00799 { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; } 00800 00801 bool 00802 _M_less(const __weak_count& __rhs) const noexcept 00803 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00804 00805 bool 00806 _M_less(const __shared_count<_Lp>& __rhs) const noexcept 00807 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00808 00809 // Friend function injected into enclosing namespace and found by ADL 00810 friend inline bool 00811 operator==(const __weak_count& __a, const __weak_count& __b) noexcept 00812 { return __a._M_pi == __b._M_pi; } 00813 00814 private: 00815 friend class __shared_count<_Lp>; 00816 00817 _Sp_counted_base<_Lp>* _M_pi; 00818 }; 00819 00820 // Now that __weak_count is defined we can define this constructor: 00821 template<_Lock_policy _Lp> 00822 inline 00823 __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r) 00824 : _M_pi(__r._M_pi) 00825 { 00826 if (_M_pi != nullptr) 00827 _M_pi->_M_add_ref_lock(); 00828 else 00829 __throw_bad_weak_ptr(); 00830 } 00831 00832 // Now that __weak_count is defined we can define this constructor: 00833 template<_Lock_policy _Lp> 00834 inline 00835 __shared_count<_Lp>:: 00836 __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) 00837 : _M_pi(__r._M_pi) 00838 { 00839 if (_M_pi != nullptr) 00840 if (!_M_pi->_M_add_ref_lock_nothrow()) 00841 _M_pi = nullptr; 00842 } 00843 00844 // Support for enable_shared_from_this. 00845 00846 // Friend of __enable_shared_from_this. 00847 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> 00848 void 00849 __enable_shared_from_this_helper(const __shared_count<_Lp>&, 00850 const __enable_shared_from_this<_Tp1, 00851 _Lp>*, const _Tp2*) noexcept; 00852 00853 // Friend of enable_shared_from_this. 00854 template<typename _Tp1, typename _Tp2> 00855 void 00856 __enable_shared_from_this_helper(const __shared_count<>&, 00857 const enable_shared_from_this<_Tp1>*, 00858 const _Tp2*) noexcept; 00859 00860 template<_Lock_policy _Lp> 00861 inline void 00862 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) noexcept 00863 { } 00864 00865 00866 template<typename _Tp, _Lock_policy _Lp> 00867 class __shared_ptr 00868 { 00869 template<typename _Ptr> 00870 using _Convertible 00871 = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type; 00872 00873 public: 00874 typedef _Tp element_type; 00875 00876 constexpr __shared_ptr() noexcept 00877 : _M_ptr(0), _M_refcount() 00878 { } 00879 00880 template<typename _Tp1> 00881 explicit __shared_ptr(_Tp1* __p) 00882 : _M_ptr(__p), _M_refcount(__p) 00883 { 00884 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00885 static_assert( !is_void<_Tp1>::value, "incomplete type" ); 00886 static_assert( sizeof(_Tp1) > 0, "incomplete type" ); 00887 __enable_shared_from_this_helper(_M_refcount, __p, __p); 00888 } 00889 00890 template<typename _Tp1, typename _Deleter> 00891 __shared_ptr(_Tp1* __p, _Deleter __d) 00892 : _M_ptr(__p), _M_refcount(__p, __d) 00893 { 00894 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00895 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 00896 __enable_shared_from_this_helper(_M_refcount, __p, __p); 00897 } 00898 00899 template<typename _Tp1, typename _Deleter, typename _Alloc> 00900 __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) 00901 : _M_ptr(__p), _M_refcount(__p, __d, std::move(__a)) 00902 { 00903 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00904 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 00905 __enable_shared_from_this_helper(_M_refcount, __p, __p); 00906 } 00907 00908 template<typename _Deleter> 00909 __shared_ptr(nullptr_t __p, _Deleter __d) 00910 : _M_ptr(0), _M_refcount(__p, __d) 00911 { } 00912 00913 template<typename _Deleter, typename _Alloc> 00914 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 00915 : _M_ptr(0), _M_refcount(__p, __d, std::move(__a)) 00916 { } 00917 00918 template<typename _Tp1> 00919 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept 00920 : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws 00921 { } 00922 00923 __shared_ptr(const __shared_ptr&) noexcept = default; 00924 __shared_ptr& operator=(const __shared_ptr&) noexcept = default; 00925 ~__shared_ptr() = default; 00926 00927 template<typename _Tp1, typename = _Convertible<_Tp1*>> 00928 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 00929 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 00930 { } 00931 00932 __shared_ptr(__shared_ptr&& __r) noexcept 00933 : _M_ptr(__r._M_ptr), _M_refcount() 00934 { 00935 _M_refcount._M_swap(__r._M_refcount); 00936 __r._M_ptr = 0; 00937 } 00938 00939 template<typename _Tp1, typename = _Convertible<_Tp1*>> 00940 __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept 00941 : _M_ptr(__r._M_ptr), _M_refcount() 00942 { 00943 _M_refcount._M_swap(__r._M_refcount); 00944 __r._M_ptr = 0; 00945 } 00946 00947 template<typename _Tp1> 00948 explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 00949 : _M_refcount(__r._M_refcount) // may throw 00950 { 00951 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00952 00953 // It is now safe to copy __r._M_ptr, as 00954 // _M_refcount(__r._M_refcount) did not throw. 00955 _M_ptr = __r._M_ptr; 00956 } 00957 00958 // If an exception is thrown this constructor has no effect. 00959 template<typename _Tp1, typename _Del, typename 00960 = _Convertible<typename unique_ptr<_Tp1, _Del>::pointer>> 00961 __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r) 00962 : _M_ptr(__r.get()), _M_refcount() 00963 { 00964 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00965 auto __raw = _S_raw_ptr(__r.get()); 00966 _M_refcount = __shared_count<_Lp>(std::move(__r)); 00967 __enable_shared_from_this_helper(_M_refcount, __raw, __raw); 00968 } 00969 00970 #if _GLIBCXX_USE_DEPRECATED 00971 // Postcondition: use_count() == 1 and __r.get() == 0 00972 template<typename _Tp1> 00973 __shared_ptr(std::auto_ptr<_Tp1>&& __r); 00974 #endif 00975 00976 constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { } 00977 00978 template<typename _Tp1> 00979 __shared_ptr& 00980 operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 00981 { 00982 _M_ptr = __r._M_ptr; 00983 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 00984 return *this; 00985 } 00986 00987 #if _GLIBCXX_USE_DEPRECATED 00988 template<typename _Tp1> 00989 __shared_ptr& 00990 operator=(std::auto_ptr<_Tp1>&& __r) 00991 { 00992 __shared_ptr(std::move(__r)).swap(*this); 00993 return *this; 00994 } 00995 #endif 00996 00997 __shared_ptr& 00998 operator=(__shared_ptr&& __r) noexcept 00999 { 01000 __shared_ptr(std::move(__r)).swap(*this); 01001 return *this; 01002 } 01003 01004 template<class _Tp1> 01005 __shared_ptr& 01006 operator=(__shared_ptr<_Tp1, _Lp>&& __r) noexcept 01007 { 01008 __shared_ptr(std::move(__r)).swap(*this); 01009 return *this; 01010 } 01011 01012 template<typename _Tp1, typename _Del> 01013 __shared_ptr& 01014 operator=(std::unique_ptr<_Tp1, _Del>&& __r) 01015 { 01016 __shared_ptr(std::move(__r)).swap(*this); 01017 return *this; 01018 } 01019 01020 void 01021 reset() noexcept 01022 { __shared_ptr().swap(*this); } 01023 01024 template<typename _Tp1> 01025 void 01026 reset(_Tp1* __p) // _Tp1 must be complete. 01027 { 01028 // Catch self-reset errors. 01029 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 01030 __shared_ptr(__p).swap(*this); 01031 } 01032 01033 template<typename _Tp1, typename _Deleter> 01034 void 01035 reset(_Tp1* __p, _Deleter __d) 01036 { __shared_ptr(__p, __d).swap(*this); } 01037 01038 template<typename _Tp1, typename _Deleter, typename _Alloc> 01039 void 01040 reset(_Tp1* __p, _Deleter __d, _Alloc __a) 01041 { __shared_ptr(__p, __d, std::move(__a)).swap(*this); } 01042 01043 // Allow class instantiation when _Tp is [cv-qual] void. 01044 typename std::add_lvalue_reference<_Tp>::type 01045 operator*() const noexcept 01046 { 01047 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 01048 return *_M_ptr; 01049 } 01050 01051 _Tp* 01052 operator->() const noexcept 01053 { 01054 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 01055 return _M_ptr; 01056 } 01057 01058 _Tp* 01059 get() const noexcept 01060 { return _M_ptr; } 01061 01062 explicit operator bool() const // never throws 01063 { return _M_ptr == 0 ? false : true; } 01064 01065 bool 01066 unique() const noexcept 01067 { return _M_refcount._M_unique(); } 01068 01069 long 01070 use_count() const noexcept 01071 { return _M_refcount._M_get_use_count(); } 01072 01073 void 01074 swap(__shared_ptr<_Tp, _Lp>& __other) noexcept 01075 { 01076 std::swap(_M_ptr, __other._M_ptr); 01077 _M_refcount._M_swap(__other._M_refcount); 01078 } 01079 01080 template<typename _Tp1> 01081 bool 01082 owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const 01083 { return _M_refcount._M_less(__rhs._M_refcount); } 01084 01085 template<typename _Tp1> 01086 bool 01087 owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const 01088 { return _M_refcount._M_less(__rhs._M_refcount); } 01089 01090 #if __cpp_rtti 01091 protected: 01092 // This constructor is non-standard, it is used by allocate_shared. 01093 template<typename _Alloc, typename... _Args> 01094 __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 01095 _Args&&... __args) 01096 : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a, 01097 std::forward<_Args>(__args)...) 01098 { 01099 // _M_ptr needs to point to the newly constructed object. 01100 // This relies on _Sp_counted_ptr_inplace::_M_get_deleter. 01101 void* __p = _M_refcount._M_get_deleter(typeid(__tag)); 01102 _M_ptr = static_cast<_Tp*>(__p); 01103 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr); 01104 } 01105 #else 01106 template<typename _Alloc> 01107 struct _Deleter 01108 { 01109 void operator()(typename _Alloc::value_type* __ptr) 01110 { 01111 __allocated_ptr<_Alloc> __guard{ _M_alloc, __ptr }; 01112 allocator_traits<_Alloc>::destroy(_M_alloc, __guard.get()); 01113 } 01114 _Alloc _M_alloc; 01115 }; 01116 01117 template<typename _Alloc, typename... _Args> 01118 __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 01119 _Args&&... __args) 01120 : _M_ptr(), _M_refcount() 01121 { 01122 typedef typename allocator_traits<_Alloc>::template 01123 rebind_traits<typename std::remove_cv<_Tp>::type> __traits; 01124 _Deleter<typename __traits::allocator_type> __del = { __a }; 01125 auto __guard = std::__allocate_guarded(__del._M_alloc); 01126 auto __ptr = __guard.get(); 01127 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01128 // 2070. allocate_shared should use allocator_traits<A>::construct 01129 __traits::construct(__del._M_alloc, __ptr, 01130 std::forward<_Args>(__args)...); 01131 __guard = nullptr; 01132 __shared_count<_Lp> __count(__ptr, __del, __del._M_alloc); 01133 _M_refcount._M_swap(__count); 01134 _M_ptr = __ptr; 01135 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr); 01136 } 01137 #endif 01138 01139 template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc, 01140 typename... _Args> 01141 friend __shared_ptr<_Tp1, _Lp1> 01142 __allocate_shared(const _Alloc& __a, _Args&&... __args); 01143 01144 // This constructor is used by __weak_ptr::lock() and 01145 // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t). 01146 __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) 01147 : _M_refcount(__r._M_refcount, std::nothrow) 01148 { 01149 _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr; 01150 } 01151 01152 friend class __weak_ptr<_Tp, _Lp>; 01153 01154 private: 01155 void* 01156 _M_get_deleter(const std::type_info& __ti) const noexcept 01157 { return _M_refcount._M_get_deleter(__ti); } 01158 01159 template<typename _Tp1> 01160 static _Tp1* 01161 _S_raw_ptr(_Tp1* __ptr) 01162 { return __ptr; } 01163 01164 template<typename _Tp1> 01165 static auto 01166 _S_raw_ptr(_Tp1 __ptr) -> decltype(std::__addressof(*__ptr)) 01167 { return std::__addressof(*__ptr); } 01168 01169 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 01170 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 01171 01172 template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 01173 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept; 01174 01175 _Tp* _M_ptr; // Contained pointer. 01176 __shared_count<_Lp> _M_refcount; // Reference counter. 01177 }; 01178 01179 01180 // 20.7.2.2.7 shared_ptr comparisons 01181 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01182 inline bool 01183 operator==(const __shared_ptr<_Tp1, _Lp>& __a, 01184 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01185 { return __a.get() == __b.get(); } 01186 01187 template<typename _Tp, _Lock_policy _Lp> 01188 inline bool 01189 operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01190 { return !__a; } 01191 01192 template<typename _Tp, _Lock_policy _Lp> 01193 inline bool 01194 operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01195 { return !__a; } 01196 01197 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01198 inline bool 01199 operator!=(const __shared_ptr<_Tp1, _Lp>& __a, 01200 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01201 { return __a.get() != __b.get(); } 01202 01203 template<typename _Tp, _Lock_policy _Lp> 01204 inline bool 01205 operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01206 { return (bool)__a; } 01207 01208 template<typename _Tp, _Lock_policy _Lp> 01209 inline bool 01210 operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01211 { return (bool)__a; } 01212 01213 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01214 inline bool 01215 operator<(const __shared_ptr<_Tp1, _Lp>& __a, 01216 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01217 { 01218 typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT; 01219 return std::less<_CT>()(__a.get(), __b.get()); 01220 } 01221 01222 template<typename _Tp, _Lock_policy _Lp> 01223 inline bool 01224 operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01225 { return std::less<_Tp*>()(__a.get(), nullptr); } 01226 01227 template<typename _Tp, _Lock_policy _Lp> 01228 inline bool 01229 operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01230 { return std::less<_Tp*>()(nullptr, __a.get()); } 01231 01232 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01233 inline bool 01234 operator<=(const __shared_ptr<_Tp1, _Lp>& __a, 01235 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01236 { return !(__b < __a); } 01237 01238 template<typename _Tp, _Lock_policy _Lp> 01239 inline bool 01240 operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01241 { return !(nullptr < __a); } 01242 01243 template<typename _Tp, _Lock_policy _Lp> 01244 inline bool 01245 operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01246 { return !(__a < nullptr); } 01247 01248 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01249 inline bool 01250 operator>(const __shared_ptr<_Tp1, _Lp>& __a, 01251 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01252 { return (__b < __a); } 01253 01254 template<typename _Tp, _Lock_policy _Lp> 01255 inline bool 01256 operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01257 { return std::less<_Tp*>()(nullptr, __a.get()); } 01258 01259 template<typename _Tp, _Lock_policy _Lp> 01260 inline bool 01261 operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01262 { return std::less<_Tp*>()(__a.get(), nullptr); } 01263 01264 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01265 inline bool 01266 operator>=(const __shared_ptr<_Tp1, _Lp>& __a, 01267 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01268 { return !(__a < __b); } 01269 01270 template<typename _Tp, _Lock_policy _Lp> 01271 inline bool 01272 operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01273 { return !(__a < nullptr); } 01274 01275 template<typename _Tp, _Lock_policy _Lp> 01276 inline bool 01277 operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01278 { return !(nullptr < __a); } 01279 01280 template<typename _Sp> 01281 struct _Sp_less : public binary_function<_Sp, _Sp, bool> 01282 { 01283 bool 01284 operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept 01285 { 01286 typedef typename _Sp::element_type element_type; 01287 return std::less<element_type*>()(__lhs.get(), __rhs.get()); 01288 } 01289 }; 01290 01291 template<typename _Tp, _Lock_policy _Lp> 01292 struct less<__shared_ptr<_Tp, _Lp>> 01293 : public _Sp_less<__shared_ptr<_Tp, _Lp>> 01294 { }; 01295 01296 // 20.7.2.2.8 shared_ptr specialized algorithms. 01297 template<typename _Tp, _Lock_policy _Lp> 01298 inline void 01299 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept 01300 { __a.swap(__b); } 01301 01302 // 20.7.2.2.9 shared_ptr casts 01303 01304 // The seemingly equivalent code: 01305 // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) 01306 // will eventually result in undefined behaviour, attempting to 01307 // delete the same object twice. 01308 /// static_pointer_cast 01309 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 01310 inline __shared_ptr<_Tp, _Lp> 01311 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01312 { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); } 01313 01314 // The seemingly equivalent code: 01315 // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) 01316 // will eventually result in undefined behaviour, attempting to 01317 // delete the same object twice. 01318 /// const_pointer_cast 01319 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 01320 inline __shared_ptr<_Tp, _Lp> 01321 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01322 { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); } 01323 01324 // The seemingly equivalent code: 01325 // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) 01326 // will eventually result in undefined behaviour, attempting to 01327 // delete the same object twice. 01328 /// dynamic_pointer_cast 01329 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 01330 inline __shared_ptr<_Tp, _Lp> 01331 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01332 { 01333 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get())) 01334 return __shared_ptr<_Tp, _Lp>(__r, __p); 01335 return __shared_ptr<_Tp, _Lp>(); 01336 } 01337 01338 01339 template<typename _Tp, _Lock_policy _Lp> 01340 class __weak_ptr 01341 { 01342 template<typename _Ptr> 01343 using _Convertible 01344 = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type; 01345 01346 public: 01347 typedef _Tp element_type; 01348 01349 constexpr __weak_ptr() noexcept 01350 : _M_ptr(nullptr), _M_refcount() 01351 { } 01352 01353 __weak_ptr(const __weak_ptr&) noexcept = default; 01354 01355 ~__weak_ptr() = default; 01356 01357 // The "obvious" converting constructor implementation: 01358 // 01359 // template<typename _Tp1> 01360 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 01361 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 01362 // { } 01363 // 01364 // has a serious problem. 01365 // 01366 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 01367 // conversion may require access to *__r._M_ptr (virtual inheritance). 01368 // 01369 // It is not possible to avoid spurious access violations since 01370 // in multithreaded programs __r._M_ptr may be invalidated at any point. 01371 template<typename _Tp1, typename = _Convertible<_Tp1*>> 01372 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) noexcept 01373 : _M_refcount(__r._M_refcount) 01374 { _M_ptr = __r.lock().get(); } 01375 01376 template<typename _Tp1, typename = _Convertible<_Tp1*>> 01377 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01378 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 01379 { } 01380 01381 __weak_ptr(__weak_ptr&& __r) noexcept 01382 : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount)) 01383 { __r._M_ptr = nullptr; } 01384 01385 template<typename _Tp1, typename = _Convertible<_Tp1*>> 01386 __weak_ptr(__weak_ptr<_Tp1, _Lp>&& __r) noexcept 01387 : _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount)) 01388 { __r._M_ptr = nullptr; } 01389 01390 __weak_ptr& 01391 operator=(const __weak_ptr& __r) noexcept = default; 01392 01393 template<typename _Tp1> 01394 __weak_ptr& 01395 operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept 01396 { 01397 _M_ptr = __r.lock().get(); 01398 _M_refcount = __r._M_refcount; 01399 return *this; 01400 } 01401 01402 template<typename _Tp1> 01403 __weak_ptr& 01404 operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01405 { 01406 _M_ptr = __r._M_ptr; 01407 _M_refcount = __r._M_refcount; 01408 return *this; 01409 } 01410 01411 __weak_ptr& 01412 operator=(__weak_ptr&& __r) noexcept 01413 { 01414 _M_ptr = __r._M_ptr; 01415 _M_refcount = std::move(__r._M_refcount); 01416 __r._M_ptr = nullptr; 01417 return *this; 01418 } 01419 01420 template<typename _Tp1> 01421 __weak_ptr& 01422 operator=(__weak_ptr<_Tp1, _Lp>&& __r) noexcept 01423 { 01424 _M_ptr = __r.lock().get(); 01425 _M_refcount = std::move(__r._M_refcount); 01426 __r._M_ptr = nullptr; 01427 return *this; 01428 } 01429 01430 __shared_ptr<_Tp, _Lp> 01431 lock() const noexcept 01432 { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); } 01433 01434 long 01435 use_count() const noexcept 01436 { return _M_refcount._M_get_use_count(); } 01437 01438 bool 01439 expired() const noexcept 01440 { return _M_refcount._M_get_use_count() == 0; } 01441 01442 template<typename _Tp1> 01443 bool 01444 owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const 01445 { return _M_refcount._M_less(__rhs._M_refcount); } 01446 01447 template<typename _Tp1> 01448 bool 01449 owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const 01450 { return _M_refcount._M_less(__rhs._M_refcount); } 01451 01452 void 01453 reset() noexcept 01454 { __weak_ptr().swap(*this); } 01455 01456 void 01457 swap(__weak_ptr& __s) noexcept 01458 { 01459 std::swap(_M_ptr, __s._M_ptr); 01460 _M_refcount._M_swap(__s._M_refcount); 01461 } 01462 01463 private: 01464 // Used by __enable_shared_from_this. 01465 void 01466 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept 01467 { 01468 _M_ptr = __ptr; 01469 _M_refcount = __refcount; 01470 } 01471 01472 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 01473 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 01474 friend class __enable_shared_from_this<_Tp, _Lp>; 01475 friend class enable_shared_from_this<_Tp>; 01476 01477 _Tp* _M_ptr; // Contained pointer. 01478 __weak_count<_Lp> _M_refcount; // Reference counter. 01479 }; 01480 01481 // 20.7.2.3.6 weak_ptr specialized algorithms. 01482 template<typename _Tp, _Lock_policy _Lp> 01483 inline void 01484 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept 01485 { __a.swap(__b); } 01486 01487 template<typename _Tp, typename _Tp1> 01488 struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool> 01489 { 01490 bool 01491 operator()(const _Tp& __lhs, const _Tp& __rhs) const 01492 { return __lhs.owner_before(__rhs); } 01493 01494 bool 01495 operator()(const _Tp& __lhs, const _Tp1& __rhs) const 01496 { return __lhs.owner_before(__rhs); } 01497 01498 bool 01499 operator()(const _Tp1& __lhs, const _Tp& __rhs) const 01500 { return __lhs.owner_before(__rhs); } 01501 }; 01502 01503 template<typename _Tp, _Lock_policy _Lp> 01504 struct owner_less<__shared_ptr<_Tp, _Lp>> 01505 : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>> 01506 { }; 01507 01508 template<typename _Tp, _Lock_policy _Lp> 01509 struct owner_less<__weak_ptr<_Tp, _Lp>> 01510 : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>> 01511 { }; 01512 01513 01514 template<typename _Tp, _Lock_policy _Lp> 01515 class __enable_shared_from_this 01516 { 01517 protected: 01518 constexpr __enable_shared_from_this() noexcept { } 01519 01520 __enable_shared_from_this(const __enable_shared_from_this&) noexcept { } 01521 01522 __enable_shared_from_this& 01523 operator=(const __enable_shared_from_this&) noexcept 01524 { return *this; } 01525 01526 ~__enable_shared_from_this() { } 01527 01528 public: 01529 __shared_ptr<_Tp, _Lp> 01530 shared_from_this() 01531 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 01532 01533 __shared_ptr<const _Tp, _Lp> 01534 shared_from_this() const 01535 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } 01536 01537 private: 01538 template<typename _Tp1> 01539 void 01540 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept 01541 { _M_weak_this._M_assign(__p, __n); } 01542 01543 template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2> 01544 friend void 01545 __enable_shared_from_this_helper(const __shared_count<_Lp1>&, 01546 const __enable_shared_from_this<_Tp1, 01547 _Lp1>*, const _Tp2*) noexcept; 01548 01549 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 01550 }; 01551 01552 template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2> 01553 inline void 01554 __enable_shared_from_this_helper(const __shared_count<_Lp1>& __pn, 01555 const __enable_shared_from_this<_Tp1, 01556 _Lp1>* __pe, 01557 const _Tp2* __px) noexcept 01558 { 01559 if (__pe != nullptr) 01560 __pe->_M_weak_assign(const_cast<_Tp2*>(__px), __pn); 01561 } 01562 01563 template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args> 01564 inline __shared_ptr<_Tp, _Lp> 01565 __allocate_shared(const _Alloc& __a, _Args&&... __args) 01566 { 01567 return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a, 01568 std::forward<_Args>(__args)...); 01569 } 01570 01571 template<typename _Tp, _Lock_policy _Lp, typename... _Args> 01572 inline __shared_ptr<_Tp, _Lp> 01573 __make_shared(_Args&&... __args) 01574 { 01575 typedef typename std::remove_const<_Tp>::type _Tp_nc; 01576 return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(), 01577 std::forward<_Args>(__args)...); 01578 } 01579 01580 /// std::hash specialization for __shared_ptr. 01581 template<typename _Tp, _Lock_policy _Lp> 01582 struct hash<__shared_ptr<_Tp, _Lp>> 01583 : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>> 01584 { 01585 size_t 01586 operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept 01587 { return std::hash<_Tp*>()(__s.get()); } 01588 }; 01589 01590 _GLIBCXX_END_NAMESPACE_VERSION 01591 } // namespace 01592 01593 #endif // _SHARED_PTR_BASE_H