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