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 explicit __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 explicit __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 template<typename _Tp1, typename _Del>
00610 explicit __shared_ptr(const std::unique_ptr<_Tp1, _Del>&) = delete;
00611
00612
00613 template<typename _Tp1, typename _Del>
00614 explicit __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
00615 : _M_ptr(__r.get()), _M_refcount()
00616 {
00617 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00618 _Tp1* __tmp = __r.get();
00619 _M_refcount = __shared_count<_Lp>(std::move(__r));
00620 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
00621 }
00622
00623 #if _GLIBCXX_DEPRECATED
00624
00625 template<typename _Tp1>
00626 explicit __shared_ptr(std::auto_ptr<_Tp1>&& __r)
00627 : _M_ptr(__r.get()), _M_refcount()
00628 {
00629 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00630
00631 _Tp1* __tmp = __r.get();
00632 _M_refcount = __shared_count<_Lp>(std::move(__r));
00633 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
00634 }
00635 #endif
00636
00637 template<typename _Tp1>
00638 __shared_ptr&
00639 operator=(const __shared_ptr<_Tp1, _Lp>& __r)
00640 {
00641 _M_ptr = __r._M_ptr;
00642 _M_refcount = __r._M_refcount;
00643 return *this;
00644 }
00645
00646 #if _GLIBCXX_DEPRECATED
00647 template<typename _Tp1>
00648 __shared_ptr&
00649 operator=(std::auto_ptr<_Tp1>&& __r)
00650 {
00651 __shared_ptr(std::move(__r)).swap(*this);
00652 return *this;
00653 }
00654 #endif
00655
00656 __shared_ptr&
00657 operator=(__shared_ptr&& __r)
00658 {
00659 __shared_ptr(std::move(__r)).swap(*this);
00660 return *this;
00661 }
00662
00663 template<class _Tp1>
00664 __shared_ptr&
00665 operator=(__shared_ptr<_Tp1, _Lp>&& __r)
00666 {
00667 __shared_ptr(std::move(__r)).swap(*this);
00668 return *this;
00669 }
00670
00671 template<typename _Tp1, typename _Del>
00672 __shared_ptr&
00673 operator=(const std::unique_ptr<_Tp1, _Del>& __r) = delete;
00674
00675 template<typename _Tp1, typename _Del>
00676 __shared_ptr&
00677 operator=(std::unique_ptr<_Tp1, _Del>&& __r)
00678 {
00679 __shared_ptr(std::move(__r)).swap(*this);
00680 return *this;
00681 }
00682
00683 void
00684 reset()
00685 { __shared_ptr().swap(*this); }
00686
00687 template<typename _Tp1>
00688 void
00689 reset(_Tp1* __p)
00690 {
00691
00692 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
00693 __shared_ptr(__p).swap(*this);
00694 }
00695
00696 template<typename _Tp1, typename _Deleter>
00697 void
00698 reset(_Tp1* __p, _Deleter __d)
00699 { __shared_ptr(__p, __d).swap(*this); }
00700
00701 template<typename _Tp1, typename _Deleter, typename _Alloc>
00702 void
00703 reset(_Tp1* __p, _Deleter __d, const _Alloc& __a)
00704 { __shared_ptr(__p, __d, __a).swap(*this); }
00705
00706
00707 typename std::add_lvalue_reference<_Tp>::type
00708 operator*() const
00709 {
00710 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00711 return *_M_ptr;
00712 }
00713
00714 _Tp*
00715 operator->() const
00716 {
00717 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00718 return _M_ptr;
00719 }
00720
00721 _Tp*
00722 get() const
00723 { return _M_ptr; }
00724
00725 explicit operator bool() const
00726 { return _M_ptr == 0 ? false : true; }
00727
00728 bool
00729 unique() const
00730 { return _M_refcount._M_unique(); }
00731
00732 long
00733 use_count() const
00734 { return _M_refcount._M_get_use_count(); }
00735
00736 void
00737 swap(__shared_ptr<_Tp, _Lp>& __other)
00738 {
00739 std::swap(_M_ptr, __other._M_ptr);
00740 _M_refcount._M_swap(__other._M_refcount);
00741 }
00742
00743 template<typename _Tp1>
00744 bool
00745 owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const
00746 { return _M_refcount._M_less(__rhs._M_refcount); }
00747
00748 template<typename _Tp1>
00749 bool
00750 owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const
00751 { return _M_refcount._M_less(__rhs._M_refcount); }
00752
00753 #ifdef __GXX_RTTI
00754 protected:
00755
00756 template<typename _Alloc, typename... _Args>
00757 __shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
00758 : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
00759 std::forward<_Args>(__args)...)
00760 {
00761
00762
00763 void* __p = _M_refcount._M_get_deleter(typeid(__tag));
00764 _M_ptr = static_cast<_Tp*>(__p);
00765 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
00766 }
00767 #else
00768 template<typename _Alloc>
00769 struct _Deleter
00770 {
00771 void operator()(_Tp* __ptr)
00772 {
00773 _M_alloc.destroy(__ptr);
00774 _M_alloc.deallocate(__ptr, 1);
00775 }
00776 _Alloc _M_alloc;
00777 };
00778
00779 template<typename _Alloc, typename... _Args>
00780 __shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
00781 : _M_ptr(), _M_refcount()
00782 {
00783 typedef typename _Alloc::template rebind<_Tp>::other _Alloc2;
00784 _Deleter<_Alloc2> __del = { _Alloc2(__a) };
00785 _M_ptr = __del._M_alloc.allocate(1);
00786 __try
00787 {
00788 __del._M_alloc.construct(_M_ptr, std::forward<_Args>(__args)...);
00789 }
00790 __catch(...)
00791 {
00792 __del._M_alloc.deallocate(_M_ptr, 1);
00793 __throw_exception_again;
00794 }
00795 __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);
00796 _M_refcount._M_swap(__count);
00797 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
00798 }
00799 #endif
00800
00801 template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
00802 typename... _Args>
00803 friend __shared_ptr<_Tp1, _Lp1>
00804 __allocate_shared(_Alloc __a, _Args&&... __args);
00805
00806 private:
00807 void*
00808 _M_get_deleter(const std::type_info& __ti) const
00809 { return _M_refcount._M_get_deleter(__ti); }
00810
00811 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
00812 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
00813
00814 template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
00815 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
00816
00817 _Tp* _M_ptr;
00818 __shared_count<_Lp> _M_refcount;
00819 };
00820
00821
00822
00823 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
00824 inline bool
00825 operator==(const __shared_ptr<_Tp1, _Lp>& __a,
00826 const __shared_ptr<_Tp2, _Lp>& __b)
00827 { return __a.get() == __b.get(); }
00828
00829 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
00830 inline bool
00831 operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
00832 const __shared_ptr<_Tp2, _Lp>& __b)
00833 { return __a.get() != __b.get(); }
00834
00835 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
00836 inline bool
00837 operator<(const __shared_ptr<_Tp1, _Lp>& __a,
00838 const __shared_ptr<_Tp2, _Lp>& __b)
00839 { return __a.get() < __b.get(); }
00840
00841 template<typename _Sp>
00842 struct _Sp_less : public binary_function<_Sp, _Sp, bool>
00843 {
00844 bool
00845 operator()(const _Sp& __lhs, const _Sp& __rhs) const
00846 {
00847 typedef typename _Sp::element_type element_type;
00848 return std::less<element_type*>()(__lhs.get(), __rhs.get());
00849 }
00850 };
00851
00852 template<typename _Tp, _Lock_policy _Lp>
00853 struct less<__shared_ptr<_Tp, _Lp>>
00854 : public _Sp_less<__shared_ptr<_Tp, _Lp>>
00855 { };
00856
00857
00858 template<typename _Tp, _Lock_policy _Lp>
00859 inline bool
00860 operator>(const __shared_ptr<_Tp, _Lp>& __a,
00861 const __shared_ptr<_Tp, _Lp>& __b)
00862 { return __a.get() > __b.get(); }
00863
00864 template<typename _Tp, _Lock_policy _Lp>
00865 inline bool
00866 operator>=(const __shared_ptr<_Tp, _Lp>& __a,
00867 const __shared_ptr<_Tp, _Lp>& __b)
00868 { return __a.get() >= __b.get(); }
00869
00870 template<typename _Tp, _Lock_policy _Lp>
00871 inline bool
00872 operator<=(const __shared_ptr<_Tp, _Lp>& __a,
00873 const __shared_ptr<_Tp, _Lp>& __b)
00874 { return __a.get() <= __b.get(); }
00875
00876
00877 template<typename _Tp, _Lock_policy _Lp>
00878 inline void
00879 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
00880 { __a.swap(__b); }
00881
00882
00883
00884
00885
00886
00887
00888
00889 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
00890 inline __shared_ptr<_Tp, _Lp>
00891 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
00892 { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
00893
00894
00895
00896
00897
00898
00899 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
00900 inline __shared_ptr<_Tp, _Lp>
00901 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
00902 { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
00903
00904
00905
00906
00907
00908
00909 template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
00910 inline __shared_ptr<_Tp, _Lp>
00911 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
00912 {
00913 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
00914 return __shared_ptr<_Tp, _Lp>(__r, __p);
00915 return __shared_ptr<_Tp, _Lp>();
00916 }
00917
00918
00919 template<typename _Tp, _Lock_policy _Lp>
00920 class __weak_ptr
00921 {
00922 public:
00923 typedef _Tp element_type;
00924
00925 __weak_ptr() : _M_ptr(0), _M_refcount()
00926 { }
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944 template<typename _Tp1>
00945 __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
00946 : _M_refcount(__r._M_refcount)
00947 {
00948 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00949 _M_ptr = __r.lock().get();
00950 }
00951
00952 template<typename _Tp1>
00953 __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
00954 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
00955 { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
00956
00957 template<typename _Tp1>
00958 __weak_ptr&
00959 operator=(const __weak_ptr<_Tp1, _Lp>& __r)
00960 {
00961 _M_ptr = __r.lock().get();
00962 _M_refcount = __r._M_refcount;
00963 return *this;
00964 }
00965
00966 template<typename _Tp1>
00967 __weak_ptr&
00968 operator=(const __shared_ptr<_Tp1, _Lp>& __r)
00969 {
00970 _M_ptr = __r._M_ptr;
00971 _M_refcount = __r._M_refcount;
00972 return *this;
00973 }
00974
00975 __shared_ptr<_Tp, _Lp>
00976 lock() const
00977 {
00978 #ifdef __GTHREADS
00979
00980 if (expired())
00981 return __shared_ptr<element_type, _Lp>();
00982
00983 __try
00984 {
00985 return __shared_ptr<element_type, _Lp>(*this);
00986 }
00987 __catch(const bad_weak_ptr&)
00988 {
00989
00990
00991
00992 return __shared_ptr<element_type, _Lp>();
00993 }
00994
00995 #else
00996
00997 return expired() ? __shared_ptr<element_type, _Lp>()
00998 : __shared_ptr<element_type, _Lp>(*this);
00999
01000 #endif
01001 }
01002
01003 long
01004 use_count() const
01005 { return _M_refcount._M_get_use_count(); }
01006
01007 bool
01008 expired() const
01009 { return _M_refcount._M_get_use_count() == 0; }
01010
01011 template<typename _Tp1>
01012 bool
01013 owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const
01014 { return _M_refcount._M_less(__rhs._M_refcount); }
01015
01016 template<typename _Tp1>
01017 bool
01018 owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const
01019 { return _M_refcount._M_less(__rhs._M_refcount); }
01020
01021 void
01022 reset()
01023 { __weak_ptr().swap(*this); }
01024
01025 void
01026 swap(__weak_ptr& __s)
01027 {
01028 std::swap(_M_ptr, __s._M_ptr);
01029 _M_refcount._M_swap(__s._M_refcount);
01030 }
01031
01032
01033 template<typename _Tp1>
01034 bool operator<(const __weak_ptr<_Tp1, _Lp>&) const = delete;
01035
01036 template<typename _Tp1>
01037 bool operator<=(const __weak_ptr<_Tp1, _Lp>&) const = delete;
01038
01039 template<typename _Tp1>
01040 bool operator>(const __weak_ptr<_Tp1, _Lp>&) const = delete;
01041
01042 template<typename _Tp1>
01043 bool operator>=(const __weak_ptr<_Tp1, _Lp>&) const = delete;
01044
01045 private:
01046
01047 void
01048 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
01049 {
01050 _M_ptr = __ptr;
01051 _M_refcount = __refcount;
01052 }
01053
01054 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
01055 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
01056 friend class __enable_shared_from_this<_Tp, _Lp>;
01057 friend class enable_shared_from_this<_Tp>;
01058
01059 _Tp* _M_ptr;
01060 __weak_count<_Lp> _M_refcount;
01061 };
01062
01063
01064 template<typename _Tp, _Lock_policy _Lp>
01065 inline void
01066 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
01067 { __a.swap(__b); }
01068
01069 template<typename _Tp, typename _Tp1>
01070 struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
01071 {
01072 bool
01073 operator()(const _Tp& __lhs, const _Tp& __rhs) const
01074 { return __lhs.owner_before(__rhs); }
01075
01076 bool
01077 operator()(const _Tp& __lhs, const _Tp1& __rhs) const
01078 { return __lhs.owner_before(__rhs); }
01079
01080 bool
01081 operator()(const _Tp1& __lhs, const _Tp& __rhs) const
01082 { return __lhs.owner_before(__rhs); }
01083 };
01084
01085 template<typename _Tp, _Lock_policy _Lp>
01086 struct owner_less<__shared_ptr<_Tp, _Lp>>
01087 : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
01088 { };
01089
01090 template<typename _Tp, _Lock_policy _Lp>
01091 struct owner_less<__weak_ptr<_Tp, _Lp>>
01092 : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
01093 { };
01094
01095
01096 template<typename _Tp, _Lock_policy _Lp>
01097 class __enable_shared_from_this
01098 {
01099 protected:
01100 __enable_shared_from_this() { }
01101
01102 __enable_shared_from_this(const __enable_shared_from_this&) { }
01103
01104 __enable_shared_from_this&
01105 operator=(const __enable_shared_from_this&)
01106 { return *this; }
01107
01108 ~__enable_shared_from_this() { }
01109
01110 public:
01111 __shared_ptr<_Tp, _Lp>
01112 shared_from_this()
01113 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
01114
01115 __shared_ptr<const _Tp, _Lp>
01116 shared_from_this() const
01117 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
01118
01119 private:
01120 template<typename _Tp1>
01121 void
01122 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
01123 { _M_weak_this._M_assign(__p, __n); }
01124
01125 template<typename _Tp1>
01126 friend void
01127 __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
01128 const __enable_shared_from_this* __pe,
01129 const _Tp1* __px)
01130 {
01131 if (__pe != 0)
01132 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
01133 }
01134
01135 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
01136 };
01137
01138
01139 template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
01140 inline __shared_ptr<_Tp, _Lp>
01141 __allocate_shared(_Alloc __a, _Args&&... __args)
01142 {
01143 return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(),
01144 std::forward<_Alloc>(__a), std::forward<_Args>(__args)...);
01145 }
01146
01147 template<typename _Tp, _Lock_policy _Lp, typename... _Args>
01148 inline __shared_ptr<_Tp, _Lp>
01149 __make_shared(_Args&&... __args)
01150 {
01151 typedef typename std::remove_const<_Tp>::type _Tp_nc;
01152 return __allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
01153 std::forward<_Args>(__args)...);
01154 }
01155
01156 _GLIBCXX_END_NAMESPACE
01157
01158 #endif // _SHARED_PTR_BASE_H