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