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