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