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