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