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