libstdc++
|
00001 // <tr1/shared_ptr.h> -*- 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 tr1/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 _TR1_SHARED_PTR_H 00050 #define _TR1_SHARED_PTR_H 1 00051 00052 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X) 00053 # error TR1 header cannot be included from C++0x header 00054 #endif 00055 00056 namespace std 00057 { 00058 namespace tr1 00059 { 00060 00061 template<typename _Ptr, typename _Deleter, _Lock_policy _Lp> 00062 class _Sp_counted_base_impl 00063 : public _Sp_counted_base<_Lp> 00064 { 00065 public: 00066 /** 00067 * @brief 00068 * @pre __d(__p) must not throw. 00069 */ 00070 _Sp_counted_base_impl(_Ptr __p, _Deleter __d) 00071 : _M_ptr(__p), _M_del(__d) { } 00072 00073 virtual void 00074 _M_dispose() // nothrow 00075 { _M_del(_M_ptr); } 00076 00077 virtual void* 00078 _M_get_deleter(const std::type_info& __ti) 00079 { return __ti == typeid(_Deleter) ? &_M_del : 0; } 00080 00081 private: 00082 _Sp_counted_base_impl(const _Sp_counted_base_impl&); 00083 _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&); 00084 00085 _Ptr _M_ptr; // copy constructor must not throw 00086 _Deleter _M_del; // copy constructor must not throw 00087 }; 00088 00089 template<_Lock_policy _Lp = __default_lock_policy> 00090 class __weak_count; 00091 00092 template<typename _Tp> 00093 struct _Sp_deleter 00094 { 00095 typedef void result_type; 00096 typedef _Tp* argument_type; 00097 void operator()(_Tp* __p) const { delete __p; } 00098 }; 00099 00100 template<_Lock_policy _Lp = __default_lock_policy> 00101 class __shared_count 00102 { 00103 public: 00104 __shared_count() 00105 : _M_pi(0) // nothrow 00106 { } 00107 00108 template<typename _Ptr> 00109 __shared_count(_Ptr __p) : _M_pi(0) 00110 { 00111 __try 00112 { 00113 typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp; 00114 _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>( 00115 __p, _Sp_deleter<_Tp>()); 00116 } 00117 __catch(...) 00118 { 00119 delete __p; 00120 __throw_exception_again; 00121 } 00122 } 00123 00124 template<typename _Ptr, typename _Deleter> 00125 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) 00126 { 00127 __try 00128 { 00129 _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d); 00130 } 00131 __catch(...) 00132 { 00133 __d(__p); // Call _Deleter on __p. 00134 __throw_exception_again; 00135 } 00136 } 00137 00138 // Special case for auto_ptr<_Tp> to provide the strong guarantee. 00139 template<typename _Tp> 00140 explicit 00141 __shared_count(std::auto_ptr<_Tp>& __r) 00142 : _M_pi(new _Sp_counted_base_impl<_Tp*, 00143 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>())) 00144 { __r.release(); } 00145 00146 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 00147 explicit 00148 __shared_count(const __weak_count<_Lp>& __r); 00149 00150 ~__shared_count() // nothrow 00151 { 00152 if (_M_pi != 0) 00153 _M_pi->_M_release(); 00154 } 00155 00156 __shared_count(const __shared_count& __r) 00157 : _M_pi(__r._M_pi) // nothrow 00158 { 00159 if (_M_pi != 0) 00160 _M_pi->_M_add_ref_copy(); 00161 } 00162 00163 __shared_count& 00164 operator=(const __shared_count& __r) // nothrow 00165 { 00166 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00167 if (__tmp != _M_pi) 00168 { 00169 if (__tmp != 0) 00170 __tmp->_M_add_ref_copy(); 00171 if (_M_pi != 0) 00172 _M_pi->_M_release(); 00173 _M_pi = __tmp; 00174 } 00175 return *this; 00176 } 00177 00178 void 00179 _M_swap(__shared_count& __r) // nothrow 00180 { 00181 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00182 __r._M_pi = _M_pi; 00183 _M_pi = __tmp; 00184 } 00185 00186 long 00187 _M_get_use_count() const // nothrow 00188 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 00189 00190 bool 00191 _M_unique() const // nothrow 00192 { return this->_M_get_use_count() == 1; } 00193 00194 friend inline bool 00195 operator==(const __shared_count& __a, const __shared_count& __b) 00196 { return __a._M_pi == __b._M_pi; } 00197 00198 friend inline bool 00199 operator<(const __shared_count& __a, const __shared_count& __b) 00200 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } 00201 00202 void* 00203 _M_get_deleter(const std::type_info& __ti) const 00204 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; } 00205 00206 private: 00207 friend class __weak_count<_Lp>; 00208 00209 _Sp_counted_base<_Lp>* _M_pi; 00210 }; 00211 00212 00213 template<_Lock_policy _Lp> 00214 class __weak_count 00215 { 00216 public: 00217 __weak_count() 00218 : _M_pi(0) // nothrow 00219 { } 00220 00221 __weak_count(const __shared_count<_Lp>& __r) 00222 : _M_pi(__r._M_pi) // nothrow 00223 { 00224 if (_M_pi != 0) 00225 _M_pi->_M_weak_add_ref(); 00226 } 00227 00228 __weak_count(const __weak_count<_Lp>& __r) 00229 : _M_pi(__r._M_pi) // nothrow 00230 { 00231 if (_M_pi != 0) 00232 _M_pi->_M_weak_add_ref(); 00233 } 00234 00235 ~__weak_count() // nothrow 00236 { 00237 if (_M_pi != 0) 00238 _M_pi->_M_weak_release(); 00239 } 00240 00241 __weak_count<_Lp>& 00242 operator=(const __shared_count<_Lp>& __r) // nothrow 00243 { 00244 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00245 if (__tmp != 0) 00246 __tmp->_M_weak_add_ref(); 00247 if (_M_pi != 0) 00248 _M_pi->_M_weak_release(); 00249 _M_pi = __tmp; 00250 return *this; 00251 } 00252 00253 __weak_count<_Lp>& 00254 operator=(const __weak_count<_Lp>& __r) // nothrow 00255 { 00256 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00257 if (__tmp != 0) 00258 __tmp->_M_weak_add_ref(); 00259 if (_M_pi != 0) 00260 _M_pi->_M_weak_release(); 00261 _M_pi = __tmp; 00262 return *this; 00263 } 00264 00265 void 00266 _M_swap(__weak_count<_Lp>& __r) // nothrow 00267 { 00268 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00269 __r._M_pi = _M_pi; 00270 _M_pi = __tmp; 00271 } 00272 00273 long 00274 _M_get_use_count() const // nothrow 00275 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 00276 00277 friend inline bool 00278 operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) 00279 { return __a._M_pi == __b._M_pi; } 00280 00281 friend inline bool 00282 operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) 00283 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } 00284 00285 private: 00286 friend class __shared_count<_Lp>; 00287 00288 _Sp_counted_base<_Lp>* _M_pi; 00289 }; 00290 00291 // now that __weak_count is defined we can define this constructor: 00292 template<_Lock_policy _Lp> 00293 inline 00294 __shared_count<_Lp>:: 00295 __shared_count(const __weak_count<_Lp>& __r) 00296 : _M_pi(__r._M_pi) 00297 { 00298 if (_M_pi != 0) 00299 _M_pi->_M_add_ref_lock(); 00300 else 00301 __throw_bad_weak_ptr(); 00302 } 00303 00304 // Forward declarations. 00305 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 00306 class __shared_ptr; 00307 00308 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 00309 class __weak_ptr; 00310 00311 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 00312 class __enable_shared_from_this; 00313 00314 template<typename _Tp> 00315 class shared_ptr; 00316 00317 template<typename _Tp> 00318 class weak_ptr; 00319 00320 template<typename _Tp> 00321 class enable_shared_from_this; 00322 00323 // Support for enable_shared_from_this. 00324 00325 // Friend of __enable_shared_from_this. 00326 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> 00327 void 00328 __enable_shared_from_this_helper(const __shared_count<_Lp>&, 00329 const __enable_shared_from_this<_Tp1, 00330 _Lp>*, const _Tp2*); 00331 00332 // Friend of enable_shared_from_this. 00333 template<typename _Tp1, typename _Tp2> 00334 void 00335 __enable_shared_from_this_helper(const __shared_count<>&, 00336 const enable_shared_from_this<_Tp1>*, 00337 const _Tp2*); 00338 00339 template<_Lock_policy _Lp> 00340 inline void 00341 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) 00342 { } 00343 00344 00345 struct __static_cast_tag { }; 00346 struct __const_cast_tag { }; 00347 struct __dynamic_cast_tag { }; 00348 00349 /** 00350 * @class __shared_ptr 00351 * 00352 * A smart pointer with reference-counted copy semantics. 00353 * The object pointed to is deleted when the last shared_ptr pointing to 00354 * it is destroyed or reset. 00355 */ 00356 template<typename _Tp, _Lock_policy _Lp> 00357 class __shared_ptr 00358 { 00359 public: 00360 typedef _Tp element_type; 00361 00362 /** @brief Construct an empty %__shared_ptr. 00363 * @post use_count()==0 && get()==0 00364 */ 00365 __shared_ptr() 00366 : _M_ptr(0), _M_refcount() // never throws 00367 { } 00368 00369 /** @brief Construct a %__shared_ptr that owns the pointer @a __p. 00370 * @param __p A pointer that is convertible to element_type*. 00371 * @post use_count() == 1 && get() == __p 00372 * @throw std::bad_alloc, in which case @c delete @a __p is called. 00373 */ 00374 template<typename _Tp1> 00375 explicit 00376 __shared_ptr(_Tp1* __p) 00377 : _M_ptr(__p), _M_refcount(__p) 00378 { 00379 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00380 // __glibcxx_function_requires(_CompleteConcept<_Tp1*>) 00381 __enable_shared_from_this_helper(_M_refcount, __p, __p); 00382 } 00383 00384 // 00385 // Requirements: _Deleter's copy constructor and destructor must 00386 // not throw 00387 // 00388 // __shared_ptr will release __p by calling __d(__p) 00389 // 00390 /** @brief Construct a %__shared_ptr that owns the pointer @a __p 00391 * and the deleter @a __d. 00392 * @param __p A pointer. 00393 * @param __d A deleter. 00394 * @post use_count() == 1 && get() == __p 00395 * @throw std::bad_alloc, in which case @a __d(__p) is called. 00396 */ 00397 template<typename _Tp1, typename _Deleter> 00398 __shared_ptr(_Tp1* __p, _Deleter __d) 00399 : _M_ptr(__p), _M_refcount(__p, __d) 00400 { 00401 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00402 // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 00403 __enable_shared_from_this_helper(_M_refcount, __p, __p); 00404 } 00405 00406 // generated copy constructor, assignment, destructor are fine. 00407 00408 /** @brief If @a __r is empty, constructs an empty %__shared_ptr; 00409 * otherwise construct a %__shared_ptr that shares ownership 00410 * with @a __r. 00411 * @param __r A %__shared_ptr. 00412 * @post get() == __r.get() && use_count() == __r.use_count() 00413 */ 00414 template<typename _Tp1> 00415 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 00416 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 00417 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 00418 00419 /** @brief Constructs a %__shared_ptr that shares ownership with @a __r 00420 * and stores a copy of the pointer stored in @a __r. 00421 * @param __r A weak_ptr. 00422 * @post use_count() == __r.use_count() 00423 * @throw bad_weak_ptr when __r.expired(), 00424 * in which case the constructor has no effect. 00425 */ 00426 template<typename _Tp1> 00427 explicit 00428 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 00429 : _M_refcount(__r._M_refcount) // may throw 00430 { 00431 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00432 // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount) 00433 // did not throw. 00434 _M_ptr = __r._M_ptr; 00435 } 00436 00437 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED 00438 /** 00439 * @post use_count() == 1 and __r.get() == 0 00440 */ 00441 template<typename _Tp1> 00442 explicit 00443 __shared_ptr(std::auto_ptr<_Tp1>& __r) 00444 : _M_ptr(__r.get()), _M_refcount() 00445 { 00446 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00447 // TODO requires _Tp1 is complete, delete __r.release() well-formed 00448 _Tp1* __tmp = __r.get(); 00449 _M_refcount = __shared_count<_Lp>(__r); 00450 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); 00451 } 00452 00453 #endif 00454 00455 template<typename _Tp1> 00456 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag) 00457 : _M_ptr(static_cast<element_type*>(__r._M_ptr)), 00458 _M_refcount(__r._M_refcount) 00459 { } 00460 00461 template<typename _Tp1> 00462 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag) 00463 : _M_ptr(const_cast<element_type*>(__r._M_ptr)), 00464 _M_refcount(__r._M_refcount) 00465 { } 00466 00467 template<typename _Tp1> 00468 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag) 00469 : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)), 00470 _M_refcount(__r._M_refcount) 00471 { 00472 if (_M_ptr == 0) // need to allocate new counter -- the cast failed 00473 _M_refcount = __shared_count<_Lp>(); 00474 } 00475 00476 template<typename _Tp1> 00477 __shared_ptr& 00478 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 00479 { 00480 _M_ptr = __r._M_ptr; 00481 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 00482 return *this; 00483 } 00484 00485 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED 00486 template<typename _Tp1> 00487 __shared_ptr& 00488 operator=(std::auto_ptr<_Tp1>& __r) 00489 { 00490 __shared_ptr(__r).swap(*this); 00491 return *this; 00492 } 00493 #endif 00494 00495 void 00496 reset() // never throws 00497 { __shared_ptr().swap(*this); } 00498 00499 template<typename _Tp1> 00500 void 00501 reset(_Tp1* __p) // _Tp1 must be complete. 00502 { 00503 // Catch self-reset errors. 00504 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 00505 __shared_ptr(__p).swap(*this); 00506 } 00507 00508 template<typename _Tp1, typename _Deleter> 00509 void 00510 reset(_Tp1* __p, _Deleter __d) 00511 { __shared_ptr(__p, __d).swap(*this); } 00512 00513 // Allow class instantiation when _Tp is [cv-qual] void. 00514 typename std::tr1::add_reference<_Tp>::type 00515 operator*() const // never throws 00516 { 00517 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 00518 return *_M_ptr; 00519 } 00520 00521 _Tp* 00522 operator->() const // never throws 00523 { 00524 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 00525 return _M_ptr; 00526 } 00527 00528 _Tp* 00529 get() const // never throws 00530 { return _M_ptr; } 00531 00532 // Implicit conversion to "bool" 00533 private: 00534 typedef _Tp* __shared_ptr::*__unspecified_bool_type; 00535 00536 public: 00537 operator __unspecified_bool_type() const // never throws 00538 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; } 00539 00540 bool 00541 unique() const // never throws 00542 { return _M_refcount._M_unique(); } 00543 00544 long 00545 use_count() const // never throws 00546 { return _M_refcount._M_get_use_count(); } 00547 00548 void 00549 swap(__shared_ptr<_Tp, _Lp>& __other) // never throws 00550 { 00551 std::swap(_M_ptr, __other._M_ptr); 00552 _M_refcount._M_swap(__other._M_refcount); 00553 } 00554 00555 private: 00556 void* 00557 _M_get_deleter(const std::type_info& __ti) const 00558 { return _M_refcount._M_get_deleter(__ti); } 00559 00560 template<typename _Tp1, _Lock_policy _Lp1> 00561 bool 00562 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const 00563 { return _M_refcount < __rhs._M_refcount; } 00564 00565 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 00566 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 00567 00568 template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 00569 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&); 00570 00571 // Friends injected into enclosing namespace and found by ADL: 00572 template<typename _Tp1> 00573 friend inline bool 00574 operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 00575 { return __a.get() == __b.get(); } 00576 00577 template<typename _Tp1> 00578 friend inline bool 00579 operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 00580 { return __a.get() != __b.get(); } 00581 00582 template<typename _Tp1> 00583 friend inline bool 00584 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 00585 { return __a._M_less(__b); } 00586 00587 _Tp* _M_ptr; // Contained pointer. 00588 __shared_count<_Lp> _M_refcount; // Reference counter. 00589 }; 00590 00591 // 2.2.3.8 shared_ptr specialized algorithms. 00592 template<typename _Tp, _Lock_policy _Lp> 00593 inline void 00594 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) 00595 { __a.swap(__b); } 00596 00597 // 2.2.3.9 shared_ptr casts 00598 /** @warning The seemingly equivalent 00599 * <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code> 00600 * will eventually result in undefined behaviour, 00601 * attempting to delete the same object twice. 00602 */ 00603 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 00604 inline __shared_ptr<_Tp, _Lp> 00605 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 00606 { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); } 00607 00608 /** @warning The seemingly equivalent 00609 * <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code> 00610 * will eventually result in undefined behaviour, 00611 * attempting to delete the same object twice. 00612 */ 00613 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 00614 inline __shared_ptr<_Tp, _Lp> 00615 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 00616 { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); } 00617 00618 /** @warning The seemingly equivalent 00619 * <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code> 00620 * will eventually result in undefined behaviour, 00621 * attempting to delete the same object twice. 00622 */ 00623 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 00624 inline __shared_ptr<_Tp, _Lp> 00625 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 00626 { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); } 00627 00628 // 2.2.3.7 shared_ptr I/O 00629 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> 00630 std::basic_ostream<_Ch, _Tr>& 00631 operator<<(std::basic_ostream<_Ch, _Tr>& __os, 00632 const __shared_ptr<_Tp, _Lp>& __p) 00633 { 00634 __os << __p.get(); 00635 return __os; 00636 } 00637 00638 // 2.2.3.10 shared_ptr get_deleter (experimental) 00639 template<typename _Del, typename _Tp, _Lock_policy _Lp> 00640 inline _Del* 00641 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) 00642 { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); } 00643 00644 00645 template<typename _Tp, _Lock_policy _Lp> 00646 class __weak_ptr 00647 { 00648 public: 00649 typedef _Tp element_type; 00650 00651 __weak_ptr() 00652 : _M_ptr(0), _M_refcount() // never throws 00653 { } 00654 00655 // Generated copy constructor, assignment, destructor are fine. 00656 00657 // The "obvious" converting constructor implementation: 00658 // 00659 // template<typename _Tp1> 00660 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 00661 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 00662 // { } 00663 // 00664 // has a serious problem. 00665 // 00666 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 00667 // conversion may require access to *__r._M_ptr (virtual inheritance). 00668 // 00669 // It is not possible to avoid spurious access violations since 00670 // in multithreaded programs __r._M_ptr may be invalidated at any point. 00671 template<typename _Tp1> 00672 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 00673 : _M_refcount(__r._M_refcount) // never throws 00674 { 00675 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 00676 _M_ptr = __r.lock().get(); 00677 } 00678 00679 template<typename _Tp1> 00680 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 00681 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 00682 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 00683 00684 template<typename _Tp1> 00685 __weak_ptr& 00686 operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws 00687 { 00688 _M_ptr = __r.lock().get(); 00689 _M_refcount = __r._M_refcount; 00690 return *this; 00691 } 00692 00693 template<typename _Tp1> 00694 __weak_ptr& 00695 operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 00696 { 00697 _M_ptr = __r._M_ptr; 00698 _M_refcount = __r._M_refcount; 00699 return *this; 00700 } 00701 00702 __shared_ptr<_Tp, _Lp> 00703 lock() const // never throws 00704 { 00705 #ifdef __GTHREADS 00706 // Optimization: avoid throw overhead. 00707 if (expired()) 00708 return __shared_ptr<element_type, _Lp>(); 00709 00710 __try 00711 { 00712 return __shared_ptr<element_type, _Lp>(*this); 00713 } 00714 __catch(const bad_weak_ptr&) 00715 { 00716 // Q: How can we get here? 00717 // A: Another thread may have invalidated r after the 00718 // use_count test above. 00719 return __shared_ptr<element_type, _Lp>(); 00720 } 00721 00722 #else 00723 // Optimization: avoid try/catch overhead when single threaded. 00724 return expired() ? __shared_ptr<element_type, _Lp>() 00725 : __shared_ptr<element_type, _Lp>(*this); 00726 00727 #endif 00728 } // XXX MT 00729 00730 long 00731 use_count() const // never throws 00732 { return _M_refcount._M_get_use_count(); } 00733 00734 bool 00735 expired() const // never throws 00736 { return _M_refcount._M_get_use_count() == 0; } 00737 00738 void 00739 reset() // never throws 00740 { __weak_ptr().swap(*this); } 00741 00742 void 00743 swap(__weak_ptr& __s) // never throws 00744 { 00745 std::swap(_M_ptr, __s._M_ptr); 00746 _M_refcount._M_swap(__s._M_refcount); 00747 } 00748 00749 private: 00750 // Used by __enable_shared_from_this. 00751 void 00752 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) 00753 { 00754 _M_ptr = __ptr; 00755 _M_refcount = __refcount; 00756 } 00757 00758 template<typename _Tp1> 00759 bool 00760 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const 00761 { return _M_refcount < __rhs._M_refcount; } 00762 00763 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 00764 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 00765 friend class __enable_shared_from_this<_Tp, _Lp>; 00766 friend class enable_shared_from_this<_Tp>; 00767 00768 // Friend injected into namespace and found by ADL. 00769 template<typename _Tp1> 00770 friend inline bool 00771 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs) 00772 { return __lhs._M_less(__rhs); } 00773 00774 _Tp* _M_ptr; // Contained pointer. 00775 __weak_count<_Lp> _M_refcount; // Reference counter. 00776 }; 00777 00778 // 2.2.4.7 weak_ptr specialized algorithms. 00779 template<typename _Tp, _Lock_policy _Lp> 00780 inline void 00781 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) 00782 { __a.swap(__b); } 00783 00784 00785 template<typename _Tp, _Lock_policy _Lp> 00786 class __enable_shared_from_this 00787 { 00788 protected: 00789 __enable_shared_from_this() { } 00790 00791 __enable_shared_from_this(const __enable_shared_from_this&) { } 00792 00793 __enable_shared_from_this& 00794 operator=(const __enable_shared_from_this&) 00795 { return *this; } 00796 00797 ~__enable_shared_from_this() { } 00798 00799 public: 00800 __shared_ptr<_Tp, _Lp> 00801 shared_from_this() 00802 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 00803 00804 __shared_ptr<const _Tp, _Lp> 00805 shared_from_this() const 00806 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } 00807 00808 private: 00809 template<typename _Tp1> 00810 void 00811 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const 00812 { _M_weak_this._M_assign(__p, __n); } 00813 00814 template<typename _Tp1> 00815 friend void 00816 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, 00817 const __enable_shared_from_this* __pe, 00818 const _Tp1* __px) 00819 { 00820 if (__pe != 0) 00821 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 00822 } 00823 00824 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 00825 }; 00826 00827 00828 /// shared_ptr 00829 // The actual shared_ptr, with forwarding constructors and 00830 // assignment operators. 00831 template<typename _Tp> 00832 class shared_ptr 00833 : public __shared_ptr<_Tp> 00834 { 00835 public: 00836 shared_ptr() 00837 : __shared_ptr<_Tp>() { } 00838 00839 template<typename _Tp1> 00840 explicit 00841 shared_ptr(_Tp1* __p) 00842 : __shared_ptr<_Tp>(__p) { } 00843 00844 template<typename _Tp1, typename _Deleter> 00845 shared_ptr(_Tp1* __p, _Deleter __d) 00846 : __shared_ptr<_Tp>(__p, __d) { } 00847 00848 template<typename _Tp1> 00849 shared_ptr(const shared_ptr<_Tp1>& __r) 00850 : __shared_ptr<_Tp>(__r) { } 00851 00852 template<typename _Tp1> 00853 explicit 00854 shared_ptr(const weak_ptr<_Tp1>& __r) 00855 : __shared_ptr<_Tp>(__r) { } 00856 00857 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED 00858 template<typename _Tp1> 00859 explicit 00860 shared_ptr(std::auto_ptr<_Tp1>& __r) 00861 : __shared_ptr<_Tp>(__r) { } 00862 #endif 00863 00864 template<typename _Tp1> 00865 shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag) 00866 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { } 00867 00868 template<typename _Tp1> 00869 shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag) 00870 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { } 00871 00872 template<typename _Tp1> 00873 shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag) 00874 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { } 00875 00876 template<typename _Tp1> 00877 shared_ptr& 00878 operator=(const shared_ptr<_Tp1>& __r) // never throws 00879 { 00880 this->__shared_ptr<_Tp>::operator=(__r); 00881 return *this; 00882 } 00883 00884 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED 00885 template<typename _Tp1> 00886 shared_ptr& 00887 operator=(std::auto_ptr<_Tp1>& __r) 00888 { 00889 this->__shared_ptr<_Tp>::operator=(__r); 00890 return *this; 00891 } 00892 #endif 00893 }; 00894 00895 // 2.2.3.8 shared_ptr specialized algorithms. 00896 template<typename _Tp> 00897 inline void 00898 swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b) 00899 { __a.swap(__b); } 00900 00901 template<typename _Tp, typename _Tp1> 00902 inline shared_ptr<_Tp> 00903 static_pointer_cast(const shared_ptr<_Tp1>& __r) 00904 { return shared_ptr<_Tp>(__r, __static_cast_tag()); } 00905 00906 template<typename _Tp, typename _Tp1> 00907 inline shared_ptr<_Tp> 00908 const_pointer_cast(const shared_ptr<_Tp1>& __r) 00909 { return shared_ptr<_Tp>(__r, __const_cast_tag()); } 00910 00911 template<typename _Tp, typename _Tp1> 00912 inline shared_ptr<_Tp> 00913 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) 00914 { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); } 00915 00916 00917 /// weak_ptr 00918 // The actual weak_ptr, with forwarding constructors and 00919 // assignment operators. 00920 template<typename _Tp> 00921 class weak_ptr 00922 : public __weak_ptr<_Tp> 00923 { 00924 public: 00925 weak_ptr() 00926 : __weak_ptr<_Tp>() { } 00927 00928 template<typename _Tp1> 00929 weak_ptr(const weak_ptr<_Tp1>& __r) 00930 : __weak_ptr<_Tp>(__r) { } 00931 00932 template<typename _Tp1> 00933 weak_ptr(const shared_ptr<_Tp1>& __r) 00934 : __weak_ptr<_Tp>(__r) { } 00935 00936 template<typename _Tp1> 00937 weak_ptr& 00938 operator=(const weak_ptr<_Tp1>& __r) // never throws 00939 { 00940 this->__weak_ptr<_Tp>::operator=(__r); 00941 return *this; 00942 } 00943 00944 template<typename _Tp1> 00945 weak_ptr& 00946 operator=(const shared_ptr<_Tp1>& __r) // never throws 00947 { 00948 this->__weak_ptr<_Tp>::operator=(__r); 00949 return *this; 00950 } 00951 00952 shared_ptr<_Tp> 00953 lock() const // never throws 00954 { 00955 #ifdef __GTHREADS 00956 if (this->expired()) 00957 return shared_ptr<_Tp>(); 00958 00959 __try 00960 { 00961 return shared_ptr<_Tp>(*this); 00962 } 00963 __catch(const bad_weak_ptr&) 00964 { 00965 return shared_ptr<_Tp>(); 00966 } 00967 #else 00968 return this->expired() ? shared_ptr<_Tp>() 00969 : shared_ptr<_Tp>(*this); 00970 #endif 00971 } 00972 }; 00973 00974 /// enable_shared_from_this 00975 template<typename _Tp> 00976 class enable_shared_from_this 00977 { 00978 protected: 00979 enable_shared_from_this() { } 00980 00981 enable_shared_from_this(const enable_shared_from_this&) { } 00982 00983 enable_shared_from_this& 00984 operator=(const enable_shared_from_this&) 00985 { return *this; } 00986 00987 ~enable_shared_from_this() { } 00988 00989 public: 00990 shared_ptr<_Tp> 00991 shared_from_this() 00992 { return shared_ptr<_Tp>(this->_M_weak_this); } 00993 00994 shared_ptr<const _Tp> 00995 shared_from_this() const 00996 { return shared_ptr<const _Tp>(this->_M_weak_this); } 00997 00998 private: 00999 template<typename _Tp1> 01000 void 01001 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const 01002 { _M_weak_this._M_assign(__p, __n); } 01003 01004 template<typename _Tp1> 01005 friend void 01006 __enable_shared_from_this_helper(const __shared_count<>& __pn, 01007 const enable_shared_from_this* __pe, 01008 const _Tp1* __px) 01009 { 01010 if (__pe != 0) 01011 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 01012 } 01013 01014 mutable weak_ptr<_Tp> _M_weak_this; 01015 }; 01016 01017 } 01018 } 01019 01020 #endif // _TR1_SHARED_PTR_H