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 virtual void 00347 _M_dispose() noexcept 00348 { _M_del._M_del(_M_ptr); } 00349 00350 virtual void 00351 _M_destroy() noexcept 00352 { 00353 typedef typename allocator_traits<_Alloc>::template 00354 rebind_traits<_Sp_counted_deleter> _Alloc_traits; 00355 typename _Alloc_traits::allocator_type __a(_M_del); 00356 _Alloc_traits::destroy(__a, this); 00357 _Alloc_traits::deallocate(__a, this, 1); 00358 } 00359 00360 virtual void* 00361 _M_get_deleter(const std::type_info& __ti) 00362 { 00363 #ifdef __GXX_RTTI 00364 return __ti == typeid(_Deleter) ? &_M_del._M_del : 0; 00365 #else 00366 return 0; 00367 #endif 00368 } 00369 00370 protected: 00371 _Ptr _M_ptr; // copy constructor must not throw 00372 _My_Deleter _M_del; // copy constructor must not throw 00373 }; 00374 00375 // helpers for make_shared / allocate_shared 00376 00377 struct _Sp_make_shared_tag { }; 00378 00379 template<typename _Tp, typename _Alloc, _Lock_policy _Lp> 00380 class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> 00381 { 00382 // Helper class that stores the pointer and also acts as an allocator. 00383 // Used to dispose of the owned pointer and the internal refcount 00384 // Requires that copies of _Alloc can free each other's memory. 00385 struct _Impl 00386 : public _Alloc // copy constructor must not throw 00387 { 00388 _Impl(_Alloc __a) : _Alloc(__a), _M_ptr() { } 00389 _Tp* _M_ptr; 00390 }; 00391 00392 public: 00393 template<typename... _Args> 00394 _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args) 00395 : _M_impl(__a), _M_storage() 00396 { 00397 _M_impl._M_ptr = static_cast<_Tp*>(static_cast<void*>(&_M_storage)); 00398 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00399 // 2070. allocate_shared should use allocator_traits<A>::construct 00400 allocator_traits<_Alloc>::construct(__a, _M_impl._M_ptr, 00401 std::forward<_Args>(__args)...); // might throw 00402 } 00403 00404 virtual void 00405 _M_dispose() noexcept 00406 { allocator_traits<_Alloc>::destroy(_M_impl, _M_impl._M_ptr); } 00407 00408 // Override because the allocator needs to know the dynamic type 00409 virtual void 00410 _M_destroy() noexcept 00411 { 00412 typedef typename allocator_traits<_Alloc>::template 00413 rebind_traits<_Sp_counted_ptr_inplace> _Alloc_traits; 00414 typename _Alloc_traits::allocator_type __a(_M_impl); 00415 _Alloc_traits::destroy(__a, this); 00416 _Alloc_traits::deallocate(__a, this, 1); 00417 } 00418 00419 // Sneaky trick so __shared_ptr can get the managed pointer 00420 virtual void* 00421 _M_get_deleter(const std::type_info& __ti) noexcept 00422 { 00423 #ifdef __GXX_RTTI 00424 return __ti == typeid(_Sp_make_shared_tag) 00425 ? static_cast<void*>(&_M_storage) 00426 : 0; 00427 #else 00428 return 0; 00429 #endif 00430 } 00431 00432 private: 00433 _Impl _M_impl; 00434 typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type 00435 _M_storage; 00436 }; 00437 00438 template<_Lock_policy _Lp> 00439 class __shared_count 00440 { 00441 public: 00442 constexpr __shared_count() noexcept : _M_pi(0) 00443 { } 00444 00445 template<typename _Ptr> 00446 explicit 00447 __shared_count(_Ptr __p) : _M_pi(0) 00448 { 00449 __try 00450 { 00451 _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); 00452 } 00453 __catch(...) 00454 { 00455 delete __p; 00456 __throw_exception_again; 00457 } 00458 } 00459 00460 template<typename _Ptr, typename _Deleter> 00461 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) 00462 { 00463 // The allocator's value_type doesn't matter, will rebind it anyway. 00464 typedef std::allocator<int> _Alloc; 00465 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; 00466 typedef typename allocator_traits<_Alloc>::template 00467 rebind_traits<_Sp_cd_type> _Alloc_traits; 00468 typename _Alloc_traits::allocator_type __a; 00469 _Sp_cd_type* __mem = 0; 00470 __try 00471 { 00472 __mem = _Alloc_traits::allocate(__a, 1); 00473 _Alloc_traits::construct(__a, __mem, __p, std::move(__d)); 00474 _M_pi = __mem; 00475 } 00476 __catch(...) 00477 { 00478 __d(__p); // Call _Deleter on __p. 00479 if (__mem) 00480 _Alloc_traits::deallocate(__a, __mem, 1); 00481 __throw_exception_again; 00482 } 00483 } 00484 00485 template<typename _Ptr, typename _Deleter, typename _Alloc> 00486 __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) 00487 { 00488 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; 00489 typedef typename allocator_traits<_Alloc>::template 00490 rebind_traits<_Sp_cd_type> _Alloc_traits; 00491 typename _Alloc_traits::allocator_type __a2(__a); 00492 _Sp_cd_type* __mem = 0; 00493 __try 00494 { 00495 __mem = _Alloc_traits::allocate(__a2, 1); 00496 _Alloc_traits::construct(__a2, __mem, 00497 __p, std::move(__d), std::move(__a)); 00498 _M_pi = __mem; 00499 } 00500 __catch(...) 00501 { 00502 __d(__p); // Call _Deleter on __p. 00503 if (__mem) 00504 _Alloc_traits::deallocate(__a2, __mem, 1); 00505 __throw_exception_again; 00506 } 00507 } 00508 00509 template<typename _Tp, typename _Alloc, typename... _Args> 00510 __shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a, 00511 _Args&&... __args) 00512 : _M_pi(0) 00513 { 00514 typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type; 00515 typedef typename allocator_traits<_Alloc>::template 00516 rebind_traits<_Sp_cp_type> _Alloc_traits; 00517 typename _Alloc_traits::allocator_type __a2(__a); 00518 _Sp_cp_type* __mem = _Alloc_traits::allocate(__a2, 1); 00519 __try 00520 { 00521 _Alloc_traits::construct(__a2, __mem, std::move(__a), 00522 std::forward<_Args>(__args)...); 00523 _M_pi = __mem; 00524 } 00525 __catch(...) 00526 { 00527 _Alloc_traits::deallocate(__a2, __mem, 1); 00528 __throw_exception_again; 00529 } 00530 } 00531 00532 #if _GLIBCXX_USE_DEPRECATED 00533 // Special case for auto_ptr<_Tp> to provide the strong guarantee. 00534 template<typename _Tp> 00535 explicit 00536 __shared_count(std::auto_ptr<_Tp>&& __r) 00537 : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get())) 00538 { __r.release(); } 00539 #endif 00540 00541 // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee. 00542 template<typename _Tp, typename _Del> 00543 explicit 00544 __shared_count(std::unique_ptr<_Tp, _Del>&& __r) 00545 : _M_pi(_S_create_from_up(std::move(__r))) 00546 { __r.release(); } 00547 00548 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 00549 explicit __shared_count(const __weak_count<_Lp>& __r); 00550 00551 ~__shared_count() noexcept 00552 { 00553 if (_M_pi != 0) 00554 _M_pi->_M_release(); 00555 } 00556 00557 __shared_count(const __shared_count& __r) noexcept 00558 : _M_pi(__r._M_pi) 00559 { 00560 if (_M_pi != 0) 00561 _M_pi->_M_add_ref_copy(); 00562 } 00563 00564 __shared_count& 00565 operator=(const __shared_count& __r) noexcept 00566 { 00567 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00568 if (__tmp != _M_pi) 00569 { 00570 if (__tmp != 0) 00571 __tmp->_M_add_ref_copy(); 00572 if (_M_pi != 0) 00573 _M_pi->_M_release(); 00574 _M_pi = __tmp; 00575 } 00576 return *this; 00577 } 00578 00579 void 00580 _M_swap(__shared_count& __r) noexcept 00581 { 00582 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00583 __r._M_pi = _M_pi; 00584 _M_pi = __tmp; 00585 } 00586 00587 long 00588 _M_get_use_count() const noexcept 00589 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 00590 00591 bool 00592 _M_unique() const noexcept 00593 { return this->_M_get_use_count() == 1; } 00594 00595 void* 00596 _M_get_deleter(const std::type_info& __ti) const noexcept 00597 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; } 00598 00599 bool 00600 _M_less(const __shared_count& __rhs) const noexcept 00601 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00602 00603 bool 00604 _M_less(const __weak_count<_Lp>& __rhs) const noexcept 00605 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00606 00607 // Friend function injected into enclosing namespace and found by ADL 00608 friend inline bool 00609 operator==(const __shared_count& __a, const __shared_count& __b) noexcept 00610 { return __a._M_pi == __b._M_pi; } 00611 00612 private: 00613 friend class __weak_count<_Lp>; 00614 00615 template<typename _Tp, typename _Del> 00616 static _Sp_counted_base<_Lp>* 00617 _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r, 00618 typename std::enable_if<!std::is_reference<_Del>::value>::type* = 0) 00619 { 00620 return new _Sp_counted_deleter<_Tp*, _Del, std::allocator<_Tp>, 00621 _Lp>(__r.get(), __r.get_deleter()); 00622 } 00623 00624 template<typename _Tp, typename _Del> 00625 static _Sp_counted_base<_Lp>* 00626 _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r, 00627 typename std::enable_if<std::is_reference<_Del>::value>::type* = 0) 00628 { 00629 typedef typename std::remove_reference<_Del>::type _Del1; 00630 typedef std::reference_wrapper<_Del1> _Del2; 00631 return new _Sp_counted_deleter<_Tp*, _Del2, std::allocator<_Tp>, 00632 _Lp>(__r.get(), std::ref(__r.get_deleter())); 00633 } 00634 00635 _Sp_counted_base<_Lp>* _M_pi; 00636 }; 00637 00638 00639 template<_Lock_policy _Lp> 00640 class __weak_count 00641 { 00642 public: 00643 constexpr __weak_count() noexcept : _M_pi(0) 00644 { } 00645 00646 __weak_count(const __shared_count<_Lp>& __r) noexcept 00647 : _M_pi(__r._M_pi) 00648 { 00649 if (_M_pi != 0) 00650 _M_pi->_M_weak_add_ref(); 00651 } 00652 00653 __weak_count(const __weak_count<_Lp>& __r) noexcept 00654 : _M_pi(__r._M_pi) 00655 { 00656 if (_M_pi != 0) 00657 _M_pi->_M_weak_add_ref(); 00658 } 00659 00660 ~__weak_count() noexcept 00661 { 00662 if (_M_pi != 0) 00663 _M_pi->_M_weak_release(); 00664 } 00665 00666 __weak_count<_Lp>& 00667 operator=(const __shared_count<_Lp>& __r) noexcept 00668 { 00669 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00670 if (__tmp != 0) 00671 __tmp->_M_weak_add_ref(); 00672 if (_M_pi != 0) 00673 _M_pi->_M_weak_release(); 00674 _M_pi = __tmp; 00675 return *this; 00676 } 00677 00678 __weak_count<_Lp>& 00679 operator=(const __weak_count<_Lp>& __r) noexcept 00680 { 00681 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00682 if (__tmp != 0) 00683 __tmp->_M_weak_add_ref(); 00684 if (_M_pi != 0) 00685 _M_pi->_M_weak_release(); 00686 _M_pi = __tmp; 00687 return *this; 00688 } 00689 00690 void 00691 _M_swap(__weak_count<_Lp>& __r) noexcept 00692 { 00693 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00694 __r._M_pi = _M_pi; 00695 _M_pi = __tmp; 00696 } 00697 00698 long 00699 _M_get_use_count() const noexcept 00700 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 00701 00702 bool 00703 _M_less(const __weak_count& __rhs) const noexcept 00704 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00705 00706 bool 00707 _M_less(const __shared_count<_Lp>& __rhs) const noexcept 00708 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00709 00710 // Friend function injected into enclosing namespace and found by ADL 00711 friend inline bool 00712 operator==(const __weak_count& __a, const __weak_count& __b) noexcept 00713 { return __a._M_pi == __b._M_pi; } 00714 00715 private: 00716 friend class __shared_count<_Lp>; 00717 00718 _Sp_counted_base<_Lp>* _M_pi; 00719 }; 00720 00721 // Now that __weak_count is defined we can define this constructor: 00722 template<_Lock_policy _Lp> 00723 inline __shared_count<_Lp>:: __shared_count(const __weak_count<_Lp>& __r) 00724 : _M_pi(__r._M_pi) 00725 { 00726 if (_M_pi != 0) 00727 _M_pi->_M_add_ref_lock(); 00728 else 00729 __throw_bad_weak_ptr(); 00730 } 00731 00732 00733 // Support for enable_shared_from_this. 00734 00735 // Friend of __enable_shared_from_this. 00736 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> 00737 void 00738 __enable_shared_from_this_helper(const __shared_count<_Lp>&, 00739 const __enable_shared_from_this<_Tp1, 00740 _Lp>*, const _Tp2*) noexcept; 00741 00742 // Friend of enable_shared_from_this. 00743 template<typename _Tp1, typename _Tp2> 00744 void 00745 __enable_shared_from_this_helper(const __shared_count<>&, 00746 const enable_shared_from_this<_Tp1>*, 00747 const _Tp2*) noexcept; 00748 00749 template<_Lock_policy _Lp> 00750 inline void 00751 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) noexcept 00752 { } 00753 00754 00755 template<typename _Tp, _Lock_policy _Lp> 00756 class __shared_ptr 00757 { 00758 public: 00759 typedef _Tp element_type; 00760 00761 constexpr __shared_ptr() noexcept 00762 : _M_ptr(0), _M_refcount() 00763 { } 00764 00765 template<typename _Tp1> 00766 explicit __shared_ptr(_Tp1* __p) 00767 : _M_ptr(__p), _M_refcount(__p) 00768 { 00769 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00770 static_assert( sizeof(_Tp1) > 0, "incomplete type" ); 00771 __enable_shared_from_this_helper(_M_refcount, __p, __p); 00772 } 00773 00774 template<typename _Tp1, typename _Deleter> 00775 __shared_ptr(_Tp1* __p, _Deleter __d) 00776 : _M_ptr(__p), _M_refcount(__p, __d) 00777 { 00778 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00779 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 00780 __enable_shared_from_this_helper(_M_refcount, __p, __p); 00781 } 00782 00783 template<typename _Tp1, typename _Deleter, typename _Alloc> 00784 __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) 00785 : _M_ptr(__p), _M_refcount(__p, __d, std::move(__a)) 00786 { 00787 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00788 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 00789 __enable_shared_from_this_helper(_M_refcount, __p, __p); 00790 } 00791 00792 template<typename _Deleter> 00793 __shared_ptr(nullptr_t __p, _Deleter __d) 00794 : _M_ptr(0), _M_refcount(__p, __d) 00795 { } 00796 00797 template<typename _Deleter, typename _Alloc> 00798 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 00799 : _M_ptr(0), _M_refcount(__p, __d, std::move(__a)) 00800 { } 00801 00802 template<typename _Tp1> 00803 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept 00804 : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws 00805 { } 00806 00807 __shared_ptr(const __shared_ptr&) noexcept = default; 00808 __shared_ptr& operator=(const __shared_ptr&) noexcept = default; 00809 ~__shared_ptr() = default; 00810 00811 template<typename _Tp1, typename = typename 00812 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 00813 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 00814 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 00815 { } 00816 00817 __shared_ptr(__shared_ptr&& __r) noexcept 00818 : _M_ptr(__r._M_ptr), _M_refcount() 00819 { 00820 _M_refcount._M_swap(__r._M_refcount); 00821 __r._M_ptr = 0; 00822 } 00823 00824 template<typename _Tp1, typename = typename 00825 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 00826 __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept 00827 : _M_ptr(__r._M_ptr), _M_refcount() 00828 { 00829 _M_refcount._M_swap(__r._M_refcount); 00830 __r._M_ptr = 0; 00831 } 00832 00833 template<typename _Tp1> 00834 explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 00835 : _M_refcount(__r._M_refcount) // may throw 00836 { 00837 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00838 00839 // It is now safe to copy __r._M_ptr, as 00840 // _M_refcount(__r._M_refcount) did not throw. 00841 _M_ptr = __r._M_ptr; 00842 } 00843 00844 // If an exception is thrown this constructor has no effect. 00845 template<typename _Tp1, typename _Del> 00846 __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r) 00847 : _M_ptr(__r.get()), _M_refcount() 00848 { 00849 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00850 _Tp1* __tmp = __r.get(); 00851 _M_refcount = __shared_count<_Lp>(std::move(__r)); 00852 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); 00853 } 00854 00855 #if _GLIBCXX_USE_DEPRECATED 00856 // Postcondition: use_count() == 1 and __r.get() == 0 00857 template<typename _Tp1> 00858 __shared_ptr(std::auto_ptr<_Tp1>&& __r) 00859 : _M_ptr(__r.get()), _M_refcount() 00860 { 00861 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00862 static_assert( sizeof(_Tp1) > 0, "incomplete type" ); 00863 _Tp1* __tmp = __r.get(); 00864 _M_refcount = __shared_count<_Lp>(std::move(__r)); 00865 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); 00866 } 00867 #endif 00868 00869 /* TODO: use delegating constructor */ 00870 constexpr __shared_ptr(nullptr_t) noexcept 00871 : _M_ptr(0), _M_refcount() 00872 { } 00873 00874 template<typename _Tp1> 00875 __shared_ptr& 00876 operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 00877 { 00878 _M_ptr = __r._M_ptr; 00879 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 00880 return *this; 00881 } 00882 00883 #if _GLIBCXX_USE_DEPRECATED 00884 template<typename _Tp1> 00885 __shared_ptr& 00886 operator=(std::auto_ptr<_Tp1>&& __r) 00887 { 00888 __shared_ptr(std::move(__r)).swap(*this); 00889 return *this; 00890 } 00891 #endif 00892 00893 __shared_ptr& 00894 operator=(__shared_ptr&& __r) noexcept 00895 { 00896 __shared_ptr(std::move(__r)).swap(*this); 00897 return *this; 00898 } 00899 00900 template<class _Tp1> 00901 __shared_ptr& 00902 operator=(__shared_ptr<_Tp1, _Lp>&& __r) noexcept 00903 { 00904 __shared_ptr(std::move(__r)).swap(*this); 00905 return *this; 00906 } 00907 00908 template<typename _Tp1, typename _Del> 00909 __shared_ptr& 00910 operator=(std::unique_ptr<_Tp1, _Del>&& __r) 00911 { 00912 __shared_ptr(std::move(__r)).swap(*this); 00913 return *this; 00914 } 00915 00916 void 00917 reset() noexcept 00918 { __shared_ptr().swap(*this); } 00919 00920 template<typename _Tp1> 00921 void 00922 reset(_Tp1* __p) // _Tp1 must be complete. 00923 { 00924 // Catch self-reset errors. 00925 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 00926 __shared_ptr(__p).swap(*this); 00927 } 00928 00929 template<typename _Tp1, typename _Deleter> 00930 void 00931 reset(_Tp1* __p, _Deleter __d) 00932 { __shared_ptr(__p, __d).swap(*this); } 00933 00934 template<typename _Tp1, typename _Deleter, typename _Alloc> 00935 void 00936 reset(_Tp1* __p, _Deleter __d, _Alloc __a) 00937 { __shared_ptr(__p, __d, std::move(__a)).swap(*this); } 00938 00939 // Allow class instantiation when _Tp is [cv-qual] void. 00940 typename std::add_lvalue_reference<_Tp>::type 00941 operator*() const noexcept 00942 { 00943 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 00944 return *_M_ptr; 00945 } 00946 00947 _Tp* 00948 operator->() const noexcept 00949 { 00950 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 00951 return _M_ptr; 00952 } 00953 00954 _Tp* 00955 get() const noexcept 00956 { return _M_ptr; } 00957 00958 explicit operator bool() const // never throws 00959 { return _M_ptr == 0 ? false : true; } 00960 00961 bool 00962 unique() const noexcept 00963 { return _M_refcount._M_unique(); } 00964 00965 long 00966 use_count() const noexcept 00967 { return _M_refcount._M_get_use_count(); } 00968 00969 void 00970 swap(__shared_ptr<_Tp, _Lp>& __other) noexcept 00971 { 00972 std::swap(_M_ptr, __other._M_ptr); 00973 _M_refcount._M_swap(__other._M_refcount); 00974 } 00975 00976 template<typename _Tp1> 00977 bool 00978 owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const 00979 { return _M_refcount._M_less(__rhs._M_refcount); } 00980 00981 template<typename _Tp1> 00982 bool 00983 owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const 00984 { return _M_refcount._M_less(__rhs._M_refcount); } 00985 00986 #ifdef __GXX_RTTI 00987 protected: 00988 // This constructor is non-standard, it is used by allocate_shared. 00989 template<typename _Alloc, typename... _Args> 00990 __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 00991 _Args&&... __args) 00992 : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a, 00993 std::forward<_Args>(__args)...) 00994 { 00995 // _M_ptr needs to point to the newly constructed object. 00996 // This relies on _Sp_counted_ptr_inplace::_M_get_deleter. 00997 void* __p = _M_refcount._M_get_deleter(typeid(__tag)); 00998 _M_ptr = static_cast<_Tp*>(__p); 00999 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr); 01000 } 01001 #else 01002 template<typename _Alloc> 01003 struct _Deleter 01004 { 01005 void operator()(_Tp* __ptr) 01006 { 01007 typedef allocator_traits<_Alloc> _Alloc_traits; 01008 _Alloc_traits::destroy(_M_alloc, __ptr); 01009 _Alloc_traits::deallocate(_M_alloc, __ptr, 1); 01010 } 01011 _Alloc _M_alloc; 01012 }; 01013 01014 template<typename _Alloc, typename... _Args> 01015 __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 01016 _Args&&... __args) 01017 : _M_ptr(), _M_refcount() 01018 { 01019 typedef typename _Alloc::template rebind<_Tp>::other _Alloc2; 01020 _Deleter<_Alloc2> __del = { _Alloc2(__a) }; 01021 typedef allocator_traits<_Alloc2> __traits; 01022 _M_ptr = __traits::allocate(__del._M_alloc, 1); 01023 __try 01024 { 01025 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01026 // 2070. allocate_shared should use allocator_traits<A>::construct 01027 __traits::construct(__del._M_alloc, _M_ptr, 01028 std::forward<_Args>(__args)...); 01029 } 01030 __catch(...) 01031 { 01032 __traits::deallocate(__del._M_alloc, _M_ptr, 1); 01033 __throw_exception_again; 01034 } 01035 __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc); 01036 _M_refcount._M_swap(__count); 01037 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr); 01038 } 01039 #endif 01040 01041 template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc, 01042 typename... _Args> 01043 friend __shared_ptr<_Tp1, _Lp1> 01044 __allocate_shared(const _Alloc& __a, _Args&&... __args); 01045 01046 private: 01047 void* 01048 _M_get_deleter(const std::type_info& __ti) const noexcept 01049 { return _M_refcount._M_get_deleter(__ti); } 01050 01051 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 01052 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 01053 01054 template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 01055 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept; 01056 01057 _Tp* _M_ptr; // Contained pointer. 01058 __shared_count<_Lp> _M_refcount; // Reference counter. 01059 }; 01060 01061 01062 // 20.8.13.2.7 shared_ptr comparisons 01063 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01064 inline bool 01065 operator==(const __shared_ptr<_Tp1, _Lp>& __a, 01066 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01067 { return __a.get() == __b.get(); } 01068 01069 template<typename _Tp, _Lock_policy _Lp> 01070 inline bool 01071 operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01072 { return !__a; } 01073 01074 template<typename _Tp, _Lock_policy _Lp> 01075 inline bool 01076 operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01077 { return !__a; } 01078 01079 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01080 inline bool 01081 operator!=(const __shared_ptr<_Tp1, _Lp>& __a, 01082 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01083 { return __a.get() != __b.get(); } 01084 01085 template<typename _Tp, _Lock_policy _Lp> 01086 inline bool 01087 operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01088 { return (bool)__a; } 01089 01090 template<typename _Tp, _Lock_policy _Lp> 01091 inline bool 01092 operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01093 { return (bool)__a; } 01094 01095 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01096 inline bool 01097 operator<(const __shared_ptr<_Tp1, _Lp>& __a, 01098 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01099 { 01100 typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT; 01101 return std::less<_CT>()(__a.get(), __b.get()); 01102 } 01103 01104 template<typename _Tp, _Lock_policy _Lp> 01105 inline bool 01106 operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01107 { return std::less<_Tp*>()(__a.get(), nullptr); } 01108 01109 template<typename _Tp, _Lock_policy _Lp> 01110 inline bool 01111 operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01112 { return std::less<_Tp*>()(nullptr, __a.get()); } 01113 01114 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01115 inline bool 01116 operator<=(const __shared_ptr<_Tp1, _Lp>& __a, 01117 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01118 { return !(__b < __a); } 01119 01120 template<typename _Tp, _Lock_policy _Lp> 01121 inline bool 01122 operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01123 { return !(nullptr < __a); } 01124 01125 template<typename _Tp, _Lock_policy _Lp> 01126 inline bool 01127 operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01128 { return !(__a < nullptr); } 01129 01130 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01131 inline bool 01132 operator>(const __shared_ptr<_Tp1, _Lp>& __a, 01133 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01134 { return (__b < __a); } 01135 01136 template<typename _Tp, _Lock_policy _Lp> 01137 inline bool 01138 operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01139 { return std::less<_Tp*>()(nullptr, __a.get()); } 01140 01141 template<typename _Tp, _Lock_policy _Lp> 01142 inline bool 01143 operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01144 { return std::less<_Tp*>()(__a.get(), nullptr); } 01145 01146 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01147 inline bool 01148 operator>=(const __shared_ptr<_Tp1, _Lp>& __a, 01149 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01150 { return !(__a < __b); } 01151 01152 template<typename _Tp, _Lock_policy _Lp> 01153 inline bool 01154 operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01155 { return !(__a < nullptr); } 01156 01157 template<typename _Tp, _Lock_policy _Lp> 01158 inline bool 01159 operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01160 { return !(nullptr < __a); } 01161 01162 template<typename _Sp> 01163 struct _Sp_less : public binary_function<_Sp, _Sp, bool> 01164 { 01165 bool 01166 operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept 01167 { 01168 typedef typename _Sp::element_type element_type; 01169 return std::less<element_type*>()(__lhs.get(), __rhs.get()); 01170 } 01171 }; 01172 01173 template<typename _Tp, _Lock_policy _Lp> 01174 struct less<__shared_ptr<_Tp, _Lp>> 01175 : public _Sp_less<__shared_ptr<_Tp, _Lp>> 01176 { }; 01177 01178 // 2.2.3.8 shared_ptr specialized algorithms. 01179 template<typename _Tp, _Lock_policy _Lp> 01180 inline void 01181 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept 01182 { __a.swap(__b); } 01183 01184 // 2.2.3.9 shared_ptr casts 01185 01186 // The seemingly equivalent code: 01187 // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) 01188 // will eventually result in undefined behaviour, attempting to 01189 // delete the same object twice. 01190 /// static_pointer_cast 01191 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 01192 inline __shared_ptr<_Tp, _Lp> 01193 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01194 { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); } 01195 01196 // The seemingly equivalent code: 01197 // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) 01198 // will eventually result in undefined behaviour, attempting to 01199 // delete the same object twice. 01200 /// const_pointer_cast 01201 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 01202 inline __shared_ptr<_Tp, _Lp> 01203 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01204 { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); } 01205 01206 // The seemingly equivalent code: 01207 // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) 01208 // will eventually result in undefined behaviour, attempting to 01209 // delete the same object twice. 01210 /// dynamic_pointer_cast 01211 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 01212 inline __shared_ptr<_Tp, _Lp> 01213 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01214 { 01215 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get())) 01216 return __shared_ptr<_Tp, _Lp>(__r, __p); 01217 return __shared_ptr<_Tp, _Lp>(); 01218 } 01219 01220 01221 template<typename _Tp, _Lock_policy _Lp> 01222 class __weak_ptr 01223 { 01224 public: 01225 typedef _Tp element_type; 01226 01227 constexpr __weak_ptr() noexcept 01228 : _M_ptr(0), _M_refcount() 01229 { } 01230 01231 __weak_ptr(const __weak_ptr&) noexcept = default; 01232 __weak_ptr& operator=(const __weak_ptr&) noexcept = default; 01233 ~__weak_ptr() = default; 01234 01235 // The "obvious" converting constructor implementation: 01236 // 01237 // template<typename _Tp1> 01238 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 01239 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 01240 // { } 01241 // 01242 // has a serious problem. 01243 // 01244 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 01245 // conversion may require access to *__r._M_ptr (virtual inheritance). 01246 // 01247 // It is not possible to avoid spurious access violations since 01248 // in multithreaded programs __r._M_ptr may be invalidated at any point. 01249 template<typename _Tp1, typename = typename 01250 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 01251 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) noexcept 01252 : _M_refcount(__r._M_refcount) 01253 { _M_ptr = __r.lock().get(); } 01254 01255 template<typename _Tp1, typename = typename 01256 std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 01257 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01258 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 01259 { } 01260 01261 template<typename _Tp1> 01262 __weak_ptr& 01263 operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept 01264 { 01265 _M_ptr = __r.lock().get(); 01266 _M_refcount = __r._M_refcount; 01267 return *this; 01268 } 01269 01270 template<typename _Tp1> 01271 __weak_ptr& 01272 operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01273 { 01274 _M_ptr = __r._M_ptr; 01275 _M_refcount = __r._M_refcount; 01276 return *this; 01277 } 01278 01279 __shared_ptr<_Tp, _Lp> 01280 lock() const noexcept 01281 { 01282 #ifdef __GTHREADS 01283 // Optimization: avoid throw overhead. 01284 if (expired()) 01285 return __shared_ptr<element_type, _Lp>(); 01286 01287 __try 01288 { 01289 return __shared_ptr<element_type, _Lp>(*this); 01290 } 01291 __catch(const bad_weak_ptr&) 01292 { 01293 // Q: How can we get here? 01294 // A: Another thread may have invalidated r after the 01295 // use_count test above. 01296 return __shared_ptr<element_type, _Lp>(); 01297 } 01298 01299 #else 01300 // Optimization: avoid try/catch overhead when single threaded. 01301 return expired() ? __shared_ptr<element_type, _Lp>() 01302 : __shared_ptr<element_type, _Lp>(*this); 01303 01304 #endif 01305 } // XXX MT 01306 01307 long 01308 use_count() const noexcept 01309 { return _M_refcount._M_get_use_count(); } 01310 01311 bool 01312 expired() const noexcept 01313 { return _M_refcount._M_get_use_count() == 0; } 01314 01315 template<typename _Tp1> 01316 bool 01317 owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const 01318 { return _M_refcount._M_less(__rhs._M_refcount); } 01319 01320 template<typename _Tp1> 01321 bool 01322 owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const 01323 { return _M_refcount._M_less(__rhs._M_refcount); } 01324 01325 void 01326 reset() noexcept 01327 { __weak_ptr().swap(*this); } 01328 01329 void 01330 swap(__weak_ptr& __s) noexcept 01331 { 01332 std::swap(_M_ptr, __s._M_ptr); 01333 _M_refcount._M_swap(__s._M_refcount); 01334 } 01335 01336 private: 01337 // Used by __enable_shared_from_this. 01338 void 01339 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept 01340 { 01341 _M_ptr = __ptr; 01342 _M_refcount = __refcount; 01343 } 01344 01345 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 01346 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 01347 friend class __enable_shared_from_this<_Tp, _Lp>; 01348 friend class enable_shared_from_this<_Tp>; 01349 01350 _Tp* _M_ptr; // Contained pointer. 01351 __weak_count<_Lp> _M_refcount; // Reference counter. 01352 }; 01353 01354 // 20.8.13.3.7 weak_ptr specialized algorithms. 01355 template<typename _Tp, _Lock_policy _Lp> 01356 inline void 01357 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept 01358 { __a.swap(__b); } 01359 01360 template<typename _Tp, typename _Tp1> 01361 struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool> 01362 { 01363 bool 01364 operator()(const _Tp& __lhs, const _Tp& __rhs) const 01365 { return __lhs.owner_before(__rhs); } 01366 01367 bool 01368 operator()(const _Tp& __lhs, const _Tp1& __rhs) const 01369 { return __lhs.owner_before(__rhs); } 01370 01371 bool 01372 operator()(const _Tp1& __lhs, const _Tp& __rhs) const 01373 { return __lhs.owner_before(__rhs); } 01374 }; 01375 01376 template<typename _Tp, _Lock_policy _Lp> 01377 struct owner_less<__shared_ptr<_Tp, _Lp>> 01378 : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>> 01379 { }; 01380 01381 template<typename _Tp, _Lock_policy _Lp> 01382 struct owner_less<__weak_ptr<_Tp, _Lp>> 01383 : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>> 01384 { }; 01385 01386 01387 template<typename _Tp, _Lock_policy _Lp> 01388 class __enable_shared_from_this 01389 { 01390 protected: 01391 constexpr __enable_shared_from_this() noexcept { } 01392 01393 __enable_shared_from_this(const __enable_shared_from_this&) noexcept { } 01394 01395 __enable_shared_from_this& 01396 operator=(const __enable_shared_from_this&) noexcept 01397 { return *this; } 01398 01399 ~__enable_shared_from_this() { } 01400 01401 public: 01402 __shared_ptr<_Tp, _Lp> 01403 shared_from_this() 01404 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 01405 01406 __shared_ptr<const _Tp, _Lp> 01407 shared_from_this() const 01408 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } 01409 01410 private: 01411 template<typename _Tp1> 01412 void 01413 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept 01414 { _M_weak_this._M_assign(__p, __n); } 01415 01416 template<typename _Tp1> 01417 friend void 01418 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, 01419 const __enable_shared_from_this* __pe, 01420 const _Tp1* __px) noexcept 01421 { 01422 if (__pe != 0) 01423 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 01424 } 01425 01426 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 01427 }; 01428 01429 01430 template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args> 01431 inline __shared_ptr<_Tp, _Lp> 01432 __allocate_shared(const _Alloc& __a, _Args&&... __args) 01433 { 01434 return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a, 01435 std::forward<_Args>(__args)...); 01436 } 01437 01438 template<typename _Tp, _Lock_policy _Lp, typename... _Args> 01439 inline __shared_ptr<_Tp, _Lp> 01440 __make_shared(_Args&&... __args) 01441 { 01442 typedef typename std::remove_const<_Tp>::type _Tp_nc; 01443 return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(), 01444 std::forward<_Args>(__args)...); 01445 } 01446 01447 /// std::hash specialization for __shared_ptr. 01448 template<typename _Tp, _Lock_policy _Lp> 01449 struct hash<__shared_ptr<_Tp, _Lp>> 01450 : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>> 01451 { 01452 size_t 01453 operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept 01454 { return std::hash<_Tp*>()(__s.get()); } 01455 }; 01456 01457 _GLIBCXX_END_NAMESPACE_VERSION 01458 } // namespace 01459 01460 #endif // _SHARED_PTR_BASE_H