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