00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #ifndef _BOOST_SHARED_PTR_H
00055 #define _BOOST_SHARED_PTR_H 1
00056
00057 namespace std
00058 {
00059 _GLIBCXX_BEGIN_NAMESPACE(tr1)
00060
00061 class bad_weak_ptr : public std::exception
00062 {
00063 public:
00064 virtual char const*
00065 what() const throw()
00066 { return "tr1::bad_weak_ptr"; }
00067 };
00068
00069
00070 inline void
00071 __throw_bad_weak_ptr()
00072 {
00073 #if __EXCEPTIONS
00074 throw bad_weak_ptr();
00075 #else
00076 std::abort();
00077 #endif
00078 }
00079
00080 using __gnu_cxx::_Lock_policy;
00081 using __gnu_cxx::__default_lock_policy;
00082 using __gnu_cxx::_S_single;
00083 using __gnu_cxx::_S_mutex;
00084 using __gnu_cxx::_S_atomic;
00085
00086 template<typename _Tp>
00087 struct _Sp_deleter
00088 {
00089 typedef void result_type;
00090 typedef _Tp* argument_type;
00091
00092 void
00093 operator()(_Tp* __p) const
00094 { delete __p; }
00095 };
00096
00097
00098 template<_Lock_policy _Lp>
00099 class _Mutex_base
00100 { };
00101
00102 template<>
00103 class _Mutex_base<_S_mutex>
00104 : public __gnu_cxx::__mutex
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()
00113 : _M_use_count(1), _M_weak_count(1) { }
00114
00115 virtual
00116 ~_Sp_counted_base()
00117 { }
00118
00119
00120
00121 virtual void
00122 _M_dispose() = 0;
00123
00124
00125 virtual void
00126 _M_destroy()
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()
00141 {
00142 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count,
00143 -1) == 1)
00144 {
00145 _M_dispose();
00146 #ifdef __GTHREADS
00147 _GLIBCXX_READ_MEM_BARRIER;
00148 _GLIBCXX_WRITE_MEM_BARRIER;
00149 #endif
00150 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
00151 -1) == 1)
00152 _M_destroy();
00153 }
00154 }
00155
00156 void
00157 _M_weak_add_ref()
00158 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
00159
00160 void
00161 _M_weak_release()
00162 {
00163 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
00164 {
00165 #ifdef __GTHREADS
00166 _GLIBCXX_READ_MEM_BARRIER;
00167 _GLIBCXX_WRITE_MEM_BARRIER;
00168 #endif
00169 _M_destroy();
00170 }
00171 }
00172
00173 long
00174 _M_get_use_count() const
00175 { return _M_use_count; }
00176
00177 private:
00178 _Sp_counted_base(_Sp_counted_base const&);
00179 _Sp_counted_base& operator=(_Sp_counted_base const&);
00180
00181 _Atomic_word _M_use_count;
00182 _Atomic_word _M_weak_count;
00183 };
00184
00185 template<>
00186 inline void
00187 _Sp_counted_base<_S_single>::
00188 _M_add_ref_lock()
00189 {
00190 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
00191 {
00192 _M_use_count = 0;
00193 __throw_bad_weak_ptr();
00194 }
00195 }
00196
00197 #ifdef __GTHREADS
00198 template<>
00199 inline void
00200 _Sp_counted_base<_S_mutex>::
00201 _M_add_ref_lock()
00202 {
00203 __gnu_cxx::__scoped_lock sentry(*this);
00204 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
00205 {
00206 _M_use_count = 0;
00207 __throw_bad_weak_ptr();
00208 }
00209 }
00210 #endif
00211
00212 template<>
00213 inline void
00214 _Sp_counted_base<_S_atomic>::
00215 _M_add_ref_lock()
00216 {
00217
00218 _Atomic_word __count;
00219 do
00220 {
00221 __count = _M_use_count;
00222 if (__count == 0)
00223 __throw_bad_weak_ptr();
00224
00225
00226
00227 }
00228 while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
00229 __count + 1));
00230 }
00231
00232 template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
00233 class _Sp_counted_base_impl
00234 : public _Sp_counted_base<_Lp>
00235 {
00236 public:
00237
00238
00239
00240
00241 _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
00242 : _M_ptr(__p), _M_del(__d) { }
00243
00244 virtual void
00245 _M_dispose()
00246 { _M_del(_M_ptr); }
00247
00248 virtual void*
00249 _M_get_deleter(const std::type_info& __ti)
00250 { return __ti == typeid(_Deleter) ? &_M_del : 0; }
00251
00252 private:
00253 _Sp_counted_base_impl(const _Sp_counted_base_impl&);
00254 _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
00255
00256 _Ptr _M_ptr;
00257 _Deleter _M_del;
00258 };
00259
00260 template<_Lock_policy _Lp = __default_lock_policy>
00261 class __weak_count;
00262
00263 template<_Lock_policy _Lp = __default_lock_policy>
00264 class __shared_count
00265 {
00266 public:
00267 __shared_count()
00268 : _M_pi(0)
00269 { }
00270
00271 template<typename _Ptr, typename _Deleter>
00272 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
00273 {
00274 try
00275 {
00276 _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
00277 }
00278 catch(...)
00279 {
00280 __d(__p);
00281 __throw_exception_again;
00282 }
00283 }
00284
00285
00286 template<typename _Tp>
00287 explicit
00288 __shared_count(std::auto_ptr<_Tp>& __r)
00289 : _M_pi(new _Sp_counted_base_impl<_Tp*,
00290 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
00291 { __r.release(); }
00292
00293
00294 explicit
00295 __shared_count(const __weak_count<_Lp>& __r);
00296
00297 ~__shared_count()
00298 {
00299 if (_M_pi != 0)
00300 _M_pi->_M_release();
00301 }
00302
00303 __shared_count(const __shared_count& __r)
00304 : _M_pi(__r._M_pi)
00305 {
00306 if (_M_pi != 0)
00307 _M_pi->_M_add_ref_copy();
00308 }
00309
00310 __shared_count&
00311 operator=(const __shared_count& __r)
00312 {
00313 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00314 if (__tmp != _M_pi)
00315 {
00316 if (__tmp != 0)
00317 __tmp->_M_add_ref_copy();
00318 if (_M_pi != 0)
00319 _M_pi->_M_release();
00320 _M_pi = __tmp;
00321 }
00322 return *this;
00323 }
00324
00325 void
00326 _M_swap(__shared_count& __r)
00327 {
00328 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00329 __r._M_pi = _M_pi;
00330 _M_pi = __tmp;
00331 }
00332
00333 long
00334 _M_get_use_count() const
00335 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
00336
00337 bool
00338 _M_unique() const
00339 { return this->_M_get_use_count() == 1; }
00340
00341 friend inline bool
00342 operator==(const __shared_count& __a, const __shared_count& __b)
00343 { return __a._M_pi == __b._M_pi; }
00344
00345 friend inline bool
00346 operator<(const __shared_count& __a, const __shared_count& __b)
00347 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
00348
00349 void*
00350 _M_get_deleter(const std::type_info& __ti) const
00351 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
00352
00353 private:
00354 friend class __weak_count<_Lp>;
00355
00356 _Sp_counted_base<_Lp>* _M_pi;
00357 };
00358
00359 template<_Lock_policy _Lp>
00360 class __weak_count
00361 {
00362 public:
00363 __weak_count()
00364 : _M_pi(0)
00365 { }
00366
00367 __weak_count(const __shared_count<_Lp>& __r)
00368 : _M_pi(__r._M_pi)
00369 {
00370 if (_M_pi != 0)
00371 _M_pi->_M_weak_add_ref();
00372 }
00373
00374 __weak_count(const __weak_count<_Lp>& __r)
00375 : _M_pi(__r._M_pi)
00376 {
00377 if (_M_pi != 0)
00378 _M_pi->_M_weak_add_ref();
00379 }
00380
00381 ~__weak_count()
00382 {
00383 if (_M_pi != 0)
00384 _M_pi->_M_weak_release();
00385 }
00386
00387 __weak_count<_Lp>&
00388 operator=(const __shared_count<_Lp>& __r)
00389 {
00390 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00391 if (__tmp != 0)
00392 __tmp->_M_weak_add_ref();
00393 if (_M_pi != 0)
00394 _M_pi->_M_weak_release();
00395 _M_pi = __tmp;
00396 return *this;
00397 }
00398
00399 __weak_count<_Lp>&
00400 operator=(const __weak_count<_Lp>& __r)
00401 {
00402 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00403 if (__tmp != 0)
00404 __tmp->_M_weak_add_ref();
00405 if (_M_pi != 0)
00406 _M_pi->_M_weak_release();
00407 _M_pi = __tmp;
00408 return *this;
00409 }
00410
00411 void
00412 _M_swap(__weak_count<_Lp>& __r)
00413 {
00414 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00415 __r._M_pi = _M_pi;
00416 _M_pi = __tmp;
00417 }
00418
00419 long
00420 _M_get_use_count() const
00421 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
00422
00423 friend inline bool
00424 operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
00425 { return __a._M_pi == __b._M_pi; }
00426
00427 friend inline bool
00428 operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
00429 { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
00430
00431 private:
00432 friend class __shared_count<_Lp>;
00433
00434 _Sp_counted_base<_Lp>* _M_pi;
00435 };
00436
00437 template<_Lock_policy _Lp>
00438 inline
00439 __shared_count<_Lp>::
00440 __shared_count(const __weak_count<_Lp>& __r)
00441 : _M_pi(__r._M_pi)
00442 {
00443 if (_M_pi != 0)
00444 _M_pi->_M_add_ref_lock();
00445 else
00446 __throw_bad_weak_ptr();
00447 }
00448
00449
00450
00451 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
00452 class __shared_ptr;
00453
00454 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
00455 class __weak_ptr;
00456
00457 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
00458 class __enable_shared_from_this;
00459
00460 template<typename _Tp>
00461 class shared_ptr;
00462
00463 template<typename _Tp>
00464 class weak_ptr;
00465
00466 template<typename _Tp>
00467 class enable_shared_from_this;
00468
00469
00470
00471
00472 template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
00473 void
00474 __enable_shared_from_this_helper(const __shared_count<_Lp>&,
00475 const __enable_shared_from_this<_Tp1,
00476 _Lp>*, const _Tp2*);
00477
00478
00479 template<typename _Tp1, typename _Tp2>
00480 void
00481 __enable_shared_from_this_helper(const __shared_count<>&,
00482 const enable_shared_from_this<_Tp1>*,
00483 const _Tp2*);
00484
00485 template<_Lock_policy _Lp>
00486 inline void
00487 __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
00488 { }
00489
00490
00491 struct __static_cast_tag { };
00492 struct __const_cast_tag { };
00493 struct __dynamic_cast_tag { };
00494
00495
00496
00497
00498
00499
00500
00501
00502 template<typename _Tp, _Lock_policy _Lp>
00503 class __shared_ptr
00504 {
00505 public:
00506 typedef _Tp element_type;
00507
00508
00509
00510
00511 __shared_ptr()
00512 : _M_ptr(0), _M_refcount()
00513 { }
00514
00515
00516
00517
00518
00519
00520 template<typename _Tp1>
00521 explicit
00522 __shared_ptr(_Tp1* __p)
00523 : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
00524 {
00525 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00526
00527 __enable_shared_from_this_helper(_M_refcount, __p, __p);
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 template<typename _Tp1, typename _Deleter>
00543 __shared_ptr(_Tp1* __p, _Deleter __d)
00544 : _M_ptr(__p), _M_refcount(__p, __d)
00545 {
00546 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00547
00548 __enable_shared_from_this_helper(_M_refcount, __p, __p);
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 template<typename _Tp1>
00561 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
00562 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
00563 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
00564
00565
00566
00567
00568
00569
00570
00571
00572 template<typename _Tp1>
00573 explicit
00574 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
00575 : _M_refcount(__r._M_refcount)
00576 {
00577 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00578
00579
00580 _M_ptr = __r._M_ptr;
00581 }
00582
00583
00584
00585
00586 template<typename _Tp1>
00587 explicit
00588 __shared_ptr(std::auto_ptr<_Tp1>& __r)
00589 : _M_ptr(__r.get()), _M_refcount()
00590 {
00591
00592
00593 _Tp1* __tmp = __r.get();
00594 _M_refcount = __shared_count<_Lp>(__r);
00595 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
00596 }
00597
00598 template<typename _Tp1>
00599 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
00600 : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
00601 _M_refcount(__r._M_refcount)
00602 { }
00603
00604 template<typename _Tp1>
00605 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
00606 : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
00607 _M_refcount(__r._M_refcount)
00608 { }
00609
00610 template<typename _Tp1>
00611 __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
00612 : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
00613 _M_refcount(__r._M_refcount)
00614 {
00615 if (_M_ptr == 0)
00616 _M_refcount = __shared_count<_Lp>();
00617 }
00618
00619 template<typename _Tp1>
00620 __shared_ptr&
00621 operator=(const __shared_ptr<_Tp1, _Lp>& __r)
00622 {
00623 _M_ptr = __r._M_ptr;
00624 _M_refcount = __r._M_refcount;
00625 return *this;
00626 }
00627
00628 template<typename _Tp1>
00629 __shared_ptr&
00630 operator=(std::auto_ptr<_Tp1>& __r)
00631 {
00632 __shared_ptr(__r).swap(*this);
00633 return *this;
00634 }
00635
00636 void
00637 reset()
00638 { __shared_ptr().swap(*this); }
00639
00640 template<typename _Tp1>
00641 void
00642 reset(_Tp1* __p)
00643 {
00644
00645 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
00646 __shared_ptr(__p).swap(*this);
00647 }
00648
00649 template<typename _Tp1, typename _Deleter>
00650 void
00651 reset(_Tp1* __p, _Deleter __d)
00652 { __shared_ptr(__p, __d).swap(*this); }
00653
00654
00655 typename add_reference<_Tp>::type
00656 operator*() const
00657 {
00658 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00659 return *_M_ptr;
00660 }
00661
00662 _Tp*
00663 operator->() const
00664 {
00665 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00666 return _M_ptr;
00667 }
00668
00669 _Tp*
00670 get() const
00671 { return _M_ptr; }
00672
00673
00674 private:
00675 typedef _Tp* __shared_ptr::*__unspecified_bool_type;
00676
00677 public:
00678 operator __unspecified_bool_type() const
00679 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
00680
00681 bool
00682 unique() const
00683 { return _M_refcount._M_unique(); }
00684
00685 long
00686 use_count() const
00687 { return _M_refcount._M_get_use_count(); }
00688
00689 void
00690 swap(__shared_ptr<_Tp, _Lp>& __other)
00691 {
00692 std::swap(_M_ptr, __other._M_ptr);
00693 _M_refcount._M_swap(__other._M_refcount);
00694 }
00695
00696 private:
00697 void*
00698 _M_get_deleter(const std::type_info& __ti) const
00699 { return _M_refcount._M_get_deleter(__ti); }
00700
00701 template<typename _Tp1, _Lock_policy _Lp1>
00702 bool
00703 _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
00704 { return _M_refcount < __rhs._M_refcount; }
00705
00706 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
00707 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
00708
00709 template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
00710 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
00711
00712
00713 template<typename _Tp1>
00714 friend inline bool
00715 operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
00716 { return __a.get() == __b.get(); }
00717
00718 template<typename _Tp1>
00719 friend inline bool
00720 operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
00721 { return __a.get() != __b.get(); }
00722
00723 template<typename _Tp1>
00724 friend inline bool
00725 operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
00726 { return __a._M_less(__b); }
00727
00728 _Tp* _M_ptr;
00729 __shared_count<_Lp> _M_refcount;
00730 };
00731
00732
00733 template<typename _Tp, _Lock_policy _Lp>
00734 inline void
00735 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
00736 { __a.swap(__b); }
00737
00738
00739
00740
00741
00742
00743
00744 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
00745 __shared_ptr<_Tp, _Lp>
00746 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
00747 { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
00748
00749
00750
00751
00752
00753
00754 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
00755 __shared_ptr<_Tp, _Lp>
00756 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
00757 { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
00758
00759
00760
00761
00762
00763
00764 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
00765 __shared_ptr<_Tp, _Lp>
00766 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
00767 { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
00768
00769
00770 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
00771 std::basic_ostream<_Ch, _Tr>&
00772 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
00773 const __shared_ptr<_Tp, _Lp>& __p)
00774 {
00775 __os << __p.get();
00776 return __os;
00777 }
00778
00779
00780 template<typename _Del, typename _Tp, _Lock_policy _Lp>
00781 inline _Del*
00782 get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
00783 { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
00784
00785
00786 template<typename _Tp, _Lock_policy _Lp>
00787 class __weak_ptr
00788 {
00789 public:
00790 typedef _Tp element_type;
00791
00792 __weak_ptr()
00793 : _M_ptr(0), _M_refcount()
00794 { }
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812 template<typename _Tp1>
00813 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
00814 : _M_refcount(__r._M_refcount)
00815 {
00816 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00817 _M_ptr = __r.lock().get();
00818 }
00819
00820 template<typename _Tp1>
00821 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
00822 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
00823 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
00824
00825 template<typename _Tp1>
00826 __weak_ptr&
00827 operator=(const __weak_ptr<_Tp1, _Lp>& __r)
00828 {
00829 _M_ptr = __r.lock().get();
00830 _M_refcount = __r._M_refcount;
00831 return *this;
00832 }
00833
00834 template<typename _Tp1>
00835 __weak_ptr&
00836 operator=(const __shared_ptr<_Tp1, _Lp>& __r)
00837 {
00838 _M_ptr = __r._M_ptr;
00839 _M_refcount = __r._M_refcount;
00840 return *this;
00841 }
00842
00843 __shared_ptr<_Tp, _Lp>
00844 lock() const
00845 {
00846 #ifdef __GTHREADS
00847
00848 if (expired())
00849 return __shared_ptr<element_type, _Lp>();
00850
00851 try
00852 {
00853 return __shared_ptr<element_type, _Lp>(*this);
00854 }
00855 catch(const bad_weak_ptr&)
00856 {
00857
00858
00859
00860 return __shared_ptr<element_type, _Lp>();
00861 }
00862
00863 #else
00864
00865 return expired() ? __shared_ptr<element_type, _Lp>()
00866 : __shared_ptr<element_type, _Lp>(*this);
00867
00868 #endif
00869 }
00870
00871 long
00872 use_count() const
00873 { return _M_refcount._M_get_use_count(); }
00874
00875 bool
00876 expired() const
00877 { return _M_refcount._M_get_use_count() == 0; }
00878
00879 void
00880 reset()
00881 { __weak_ptr().swap(*this); }
00882
00883 void
00884 swap(__weak_ptr& __s)
00885 {
00886 std::swap(_M_ptr, __s._M_ptr);
00887 _M_refcount._M_swap(__s._M_refcount);
00888 }
00889
00890 private:
00891
00892 void
00893 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
00894 {
00895 _M_ptr = __ptr;
00896 _M_refcount = __refcount;
00897 }
00898
00899 template<typename _Tp1>
00900 bool
00901 _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
00902 { return _M_refcount < __rhs._M_refcount; }
00903
00904 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
00905 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
00906 friend class __enable_shared_from_this<_Tp, _Lp>;
00907 friend class enable_shared_from_this<_Tp>;
00908
00909
00910 template<typename _Tp1>
00911 friend inline bool
00912 operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
00913 { return __lhs._M_less(__rhs); }
00914
00915 _Tp* _M_ptr;
00916 __weak_count<_Lp> _M_refcount;
00917 };
00918
00919
00920 template<typename _Tp, _Lock_policy _Lp>
00921 inline void
00922 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
00923 { __a.swap(__b); }
00924
00925
00926 template<typename _Tp, _Lock_policy _Lp>
00927 class __enable_shared_from_this
00928 {
00929 protected:
00930 __enable_shared_from_this() { }
00931
00932 __enable_shared_from_this(const __enable_shared_from_this&) { }
00933
00934 __enable_shared_from_this&
00935 operator=(const __enable_shared_from_this&)
00936 { return *this; }
00937
00938 ~__enable_shared_from_this() { }
00939
00940 public:
00941 __shared_ptr<_Tp, _Lp>
00942 shared_from_this()
00943 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
00944
00945 __shared_ptr<const _Tp, _Lp>
00946 shared_from_this() const
00947 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
00948
00949 private:
00950 template<typename _Tp1>
00951 void
00952 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
00953 { _M_weak_this._M_assign(__p, __n); }
00954
00955 template<typename _Tp1>
00956 friend void
00957 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
00958 const __enable_shared_from_this* __pe,
00959 const _Tp1* __px)
00960 {
00961 if (__pe != 0)
00962 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
00963 }
00964
00965 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
00966 };
00967
00968
00969
00970
00971 template<typename _Tp>
00972 class shared_ptr
00973 : public __shared_ptr<_Tp>
00974 {
00975 public:
00976 shared_ptr()
00977 : __shared_ptr<_Tp>() { }
00978
00979 template<typename _Tp1>
00980 explicit
00981 shared_ptr(_Tp1* __p)
00982 : __shared_ptr<_Tp>(__p) { }
00983
00984 template<typename _Tp1, typename _Deleter>
00985 shared_ptr(_Tp1* __p, _Deleter __d)
00986 : __shared_ptr<_Tp>(__p, __d) { }
00987
00988 template<typename _Tp1>
00989 shared_ptr(const shared_ptr<_Tp1>& __r)
00990 : __shared_ptr<_Tp>(__r) { }
00991
00992 template<typename _Tp1>
00993 explicit
00994 shared_ptr(const weak_ptr<_Tp1>& __r)
00995 : __shared_ptr<_Tp>(__r) { }
00996
00997 template<typename _Tp1>
00998 explicit
00999 shared_ptr(std::auto_ptr<_Tp1>& __r)
01000 : __shared_ptr<_Tp>(__r) { }
01001
01002 template<typename _Tp1>
01003 shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
01004 : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
01005
01006 template<typename _Tp1>
01007 shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
01008 : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
01009
01010 template<typename _Tp1>
01011 shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
01012 : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
01013
01014 template<typename _Tp1>
01015 shared_ptr&
01016 operator=(const shared_ptr<_Tp1>& __r)
01017 {
01018 this->__shared_ptr<_Tp>::operator=(__r);
01019 return *this;
01020 }
01021
01022 template<typename _Tp1>
01023 shared_ptr&
01024 operator=(std::auto_ptr<_Tp1>& __r)
01025 {
01026 this->__shared_ptr<_Tp>::operator=(__r);
01027 return *this;
01028 }
01029 };
01030
01031 template<typename _Tp, typename _Tp1>
01032 shared_ptr<_Tp>
01033 static_pointer_cast(const shared_ptr<_Tp1>& __r)
01034 { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
01035
01036 template<typename _Tp, typename _Tp1>
01037 shared_ptr<_Tp>
01038 const_pointer_cast(const shared_ptr<_Tp1>& __r)
01039 { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
01040
01041 template<typename _Tp, typename _Tp1>
01042 shared_ptr<_Tp>
01043 dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
01044 { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
01045
01046
01047
01048
01049 template<typename _Tp>
01050 class weak_ptr
01051 : public __weak_ptr<_Tp>
01052 {
01053 public:
01054 weak_ptr()
01055 : __weak_ptr<_Tp>() { }
01056
01057 template<typename _Tp1>
01058 weak_ptr(const weak_ptr<_Tp1>& __r)
01059 : __weak_ptr<_Tp>(__r) { }
01060
01061 template<typename _Tp1>
01062 weak_ptr(const shared_ptr<_Tp1>& __r)
01063 : __weak_ptr<_Tp>(__r) { }
01064
01065 template<typename _Tp1>
01066 weak_ptr&
01067 operator=(const weak_ptr<_Tp1>& __r)
01068 {
01069 this->__weak_ptr<_Tp>::operator=(__r);
01070 return *this;
01071 }
01072
01073 template<typename _Tp1>
01074 weak_ptr&
01075 operator=(const shared_ptr<_Tp1>& __r)
01076 {
01077 this->__weak_ptr<_Tp>::operator=(__r);
01078 return *this;
01079 }
01080
01081 shared_ptr<_Tp>
01082 lock() const
01083 {
01084 #ifdef __GTHREADS
01085 if (this->expired())
01086 return shared_ptr<_Tp>();
01087
01088 try
01089 {
01090 return shared_ptr<_Tp>(*this);
01091 }
01092 catch(const bad_weak_ptr&)
01093 {
01094 return shared_ptr<_Tp>();
01095 }
01096 #else
01097 return this->expired() ? shared_ptr<_Tp>()
01098 : shared_ptr<_Tp>(*this);
01099 #endif
01100 }
01101 };
01102
01103
01104 template<typename _Tp>
01105 class enable_shared_from_this
01106 {
01107 protected:
01108 enable_shared_from_this() { }
01109
01110 enable_shared_from_this(const enable_shared_from_this&) { }
01111
01112 enable_shared_from_this&
01113 operator=(const enable_shared_from_this&)
01114 { return *this; }
01115
01116 ~enable_shared_from_this() { }
01117
01118 public:
01119 shared_ptr<_Tp>
01120 shared_from_this()
01121 { return shared_ptr<_Tp>(this->_M_weak_this); }
01122
01123 shared_ptr<const _Tp>
01124 shared_from_this() const
01125 { return shared_ptr<const _Tp>(this->_M_weak_this); }
01126
01127 private:
01128 template<typename _Tp1>
01129 void
01130 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
01131 { _M_weak_this._M_assign(__p, __n); }
01132
01133 template<typename _Tp1>
01134 friend void
01135 __enable_shared_from_this_helper(const __shared_count<>& __pn,
01136 const enable_shared_from_this* __pe,
01137 const _Tp1* __px)
01138 {
01139 if (__pe != 0)
01140 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
01141 }
01142
01143 mutable weak_ptr<_Tp> _M_weak_this;
01144 };
01145
01146 _GLIBCXX_END_NAMESPACE
01147 }
01148
01149 #endif