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 #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
00064
00065
00066
00067
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()
00078 { delete _M_ptr; }
00079
00080 virtual void
00081 _M_destroy()
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;
00093 };
00094
00095
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
00104
00105
00106 struct _My_Deleter
00107 : public _My_alloc_type
00108 {
00109 _Deleter _M_del;
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
00120
00121
00122 _Sp_counted_deleter(_Ptr __p, _Deleter __d)
00123 : _Base_type(__p), _M_del(__d, _Alloc()) { }
00124
00125
00126
00127
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()
00134 { _M_del._M_del(_Base_type::_M_ptr); }
00135
00136 virtual void
00137 _M_destroy()
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;
00150 };
00151
00152
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();
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)...);
00186 _Base_type::_Base_type::_M_ptr = static_cast<_Tp*>(__p);
00187 }
00188
00189
00190 virtual void
00191 _M_destroy()
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
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)
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
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);
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);
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
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
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
00319 explicit
00320 __shared_count(const __weak_count<_Lp>& __r);
00321
00322 ~__shared_count()
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)
00330 {
00331 if (_M_pi != 0)
00332 _M_pi->_M_add_ref_copy();
00333 }
00334
00335 __shared_count&
00336 operator=(const __shared_count& __r)
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)
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
00360 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
00361
00362 bool
00363 _M_unique() const
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
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)
00416 { }
00417
00418 __weak_count(const __shared_count<_Lp>& __r)
00419 : _M_pi(__r._M_pi)
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)
00427 {
00428 if (_M_pi != 0)
00429 _M_pi->_M_weak_add_ref();
00430 }
00431
00432 ~__weak_count()
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)
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)
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)
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
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
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
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
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
00526
00527
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
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
00554
00555
00556 __shared_ptr()
00557 : _M_ptr(0), _M_refcount()
00558 { }
00559
00560
00561
00562
00563
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
00572 __enable_shared_from_this_helper(_M_refcount, __p, __p);
00573 }
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
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
00594 __enable_shared_from_this_helper(_M_refcount, __p, __p);
00595 }
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
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
00618 __enable_shared_from_this_helper(_M_refcount, __p, __p);
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
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)
00639 { }
00640
00641
00642
00643
00644
00645
00646
00647
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)
00652 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
00653
00654
00655
00656
00657
00658 __shared_ptr(__shared_ptr&& __r)
00659 : _M_ptr(__r._M_ptr), _M_refcount()
00660 {
00661 _M_refcount._M_swap(__r._M_refcount);
00662 __r._M_ptr = 0;
00663 }
00664
00665
00666
00667
00668
00669 template<typename _Tp1>
00670 __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r)
00671 : _M_ptr(__r._M_ptr), _M_refcount()
00672 {
00673 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00674 _M_refcount._M_swap(__r._M_refcount);
00675 __r._M_ptr = 0;
00676 }
00677
00678
00679
00680
00681
00682
00683
00684
00685 template<typename _Tp1>
00686 explicit
00687 __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
00688 : _M_refcount(__r._M_refcount)
00689 {
00690 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00691
00692
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
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
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
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)
00734 {
00735 _M_ptr = __r._M_ptr;
00736 _M_refcount = __r._M_refcount;
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()
00779 { __shared_ptr().swap(*this); }
00780
00781 template<typename _Tp1>
00782 void
00783 reset(_Tp1* __p)
00784 {
00785
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
00801 typename std::add_lvalue_reference<_Tp>::type
00802 operator*() const
00803 {
00804 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00805 return *_M_ptr;
00806 }
00807
00808 _Tp*
00809 operator->() const
00810 {
00811 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00812 return _M_ptr;
00813 }
00814
00815 _Tp*
00816 get() const
00817 { return _M_ptr; }
00818
00819
00820 private:
00821 typedef _Tp* __shared_ptr::*__unspecified_bool_type;
00822
00823 public:
00824 operator __unspecified_bool_type() const
00825 { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
00826
00827 bool
00828 unique() const
00829 { return _M_refcount._M_unique(); }
00830
00831 long
00832 use_count() const
00833 { return _M_refcount._M_get_use_count(); }
00834
00835 void
00836 swap(__shared_ptr<_Tp, _Lp>&& __other)
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
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
00860
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;
00883 __shared_count<_Lp> _M_refcount;
00884 };
00885
00886
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
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
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
00957
00958
00959
00960
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
00968
00969
00970
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
00978
00979
00980
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
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
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()
01016 { }
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 template<typename _Tp1>
01035 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
01036 : _M_refcount(__r._M_refcount)
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)
01045 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
01046
01047 template<typename _Tp1>
01048 __weak_ptr&
01049 operator=(const __weak_ptr<_Tp1, _Lp>& __r)
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)
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
01067 {
01068 #ifdef __GTHREADS
01069
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
01080
01081
01082 return __shared_ptr<element_type, _Lp>();
01083 }
01084
01085 #else
01086
01087 return expired() ? __shared_ptr<element_type, _Lp>()
01088 : __shared_ptr<element_type, _Lp>(*this);
01089
01090 #endif
01091 }
01092
01093 long
01094 use_count() const
01095 { return _M_refcount._M_get_use_count(); }
01096
01097 bool
01098 expired() const
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()
01113 { __weak_ptr().swap(*this); }
01114
01115 void
01116 swap(__weak_ptr& __s)
01117 {
01118 std::swap(_M_ptr, __s._M_ptr);
01119 _M_refcount._M_swap(__s._M_refcount);
01120 }
01121
01122
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
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;
01147 __weak_count<_Lp> _M_refcount;
01148 };
01149
01150
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
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
01229
01230
01231
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
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)
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
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
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
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
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
01408
01409
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)
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)
01438 {
01439 this->__weak_ptr<_Tp>::operator=(__r);
01440 return *this;
01441 }
01442
01443 shared_ptr<_Tp>
01444 lock() const
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
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
01476 template<typename _Tp>
01477 inline void
01478 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b)
01479 { __a.swap(__b); }
01480
01481
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
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
01555
01556
01557
01558
01559
01560
01561
01562
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
01573
01574
01575
01576
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
01588
01589 _GLIBCXX_END_NAMESPACE
01590
01591 #endif // _SHARED_PTR_H