49 #ifndef _SHARED_PTR_BASE_H
50 #define _SHARED_PTR_BASE_H 1
52 namespace std _GLIBCXX_VISIBILITY(default)
54 _GLIBCXX_BEGIN_NAMESPACE_VERSION
71 __throw_bad_weak_ptr()
80 using __gnu_cxx::_Lock_policy;
81 using __gnu_cxx::__default_lock_policy;
82 using __gnu_cxx::_S_single;
83 using __gnu_cxx::_S_mutex;
84 using __gnu_cxx::_S_atomic;
87 template<_Lock_policy _Lp>
92 enum { _S_need_barriers = 0 };
96 class _Mutex_base<_S_mutex>
97 :
public __gnu_cxx::__mutex
103 enum { _S_need_barriers = 1 };
106 template<_Lock_policy _Lp = __default_lock_policy>
107 class _Sp_counted_base
108 :
public _Mutex_base<_Lp>
112 : _M_use_count(1), _M_weak_count(1) { }
133 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
142 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
143 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
145 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
151 if (_Mutex_base<_Lp>::_S_need_barriers)
153 _GLIBCXX_READ_MEM_BARRIER;
154 _GLIBCXX_WRITE_MEM_BARRIER;
158 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
159 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
162 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
170 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
176 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
177 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
179 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
180 if (_Mutex_base<_Lp>::_S_need_barriers)
184 _GLIBCXX_READ_MEM_BARRIER;
185 _GLIBCXX_WRITE_MEM_BARRIER;
192 _M_get_use_count() const
196 return const_cast<const volatile _Atomic_word&
>(_M_use_count);
200 _Sp_counted_base(_Sp_counted_base
const&);
201 _Sp_counted_base& operator=(_Sp_counted_base
const&);
203 _Atomic_word _M_use_count;
204 _Atomic_word _M_weak_count;
209 _Sp_counted_base<_S_single>::
212 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
215 __throw_bad_weak_ptr();
221 _Sp_counted_base<_S_mutex>::
225 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
228 __throw_bad_weak_ptr();
234 _Sp_counted_base<_S_atomic>::
238 _Atomic_word __count;
241 __count = _M_use_count;
243 __throw_bad_weak_ptr();
248 while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
254 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
257 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
260 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
261 class __enable_shared_from_this;
263 template<
typename _Tp>
266 template<
typename _Tp>
269 template<
typename _Tp>
272 template<
typename _Tp>
273 class enable_shared_from_this;
275 template<_Lock_policy _Lp = __default_lock_policy>
278 template<_Lock_policy _Lp = __default_lock_policy>
279 class __shared_count;
283 template<
typename _Ptr, _Lock_policy _Lp>
284 class _Sp_counted_ptr :
public _Sp_counted_base<_Lp>
288 _Sp_counted_ptr(_Ptr __p)
303 _Sp_counted_ptr(
const _Sp_counted_ptr&) =
delete;
304 _Sp_counted_ptr& operator=(
const _Sp_counted_ptr&) =
delete;
312 _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() { }
316 _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() { }
320 _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() { }
323 template<
typename _Ptr,
typename _Deleter,
typename _Alloc, _Lock_policy _Lp>
324 class _Sp_counted_deleter :
public _Sp_counted_base<_Lp>
326 typedef typename _Alloc::template
327 rebind<_Sp_counted_deleter>::other _My_alloc_type;
333 :
public _My_alloc_type
336 _My_Deleter(_Deleter __d,
const _Alloc& __a)
337 : _My_alloc_type(__a), _M_del(__d) { }
342 _Sp_counted_deleter(_Ptr __p, _Deleter __d)
343 : _M_ptr(__p), _M_del(__d, _Alloc()) { }
346 _Sp_counted_deleter(_Ptr __p, _Deleter __d,
const _Alloc& __a)
347 : _M_ptr(__p), _M_del(__d, __a) { }
351 { _M_del._M_del(_M_ptr); }
356 _My_alloc_type __a(_M_del);
357 this->~_Sp_counted_deleter();
358 __a.deallocate(
this, 1);
365 return __ti ==
typeid(_Deleter) ? &_M_del._M_del : 0;
378 template<
typename _Tp>
379 struct _Sp_destroy_inplace
381 void operator()(_Tp* __p)
const {
if (__p) __p->~_Tp(); }
384 struct _Sp_make_shared_tag { };
386 template<
typename _Tp,
typename _Alloc, _Lock_policy _Lp>
387 class _Sp_counted_ptr_inplace
388 :
public _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp>
390 typedef _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp>
395 _Sp_counted_ptr_inplace(_Alloc __a)
396 : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a)
399 void* __p = &_M_storage;
401 _Base_type::_M_ptr = static_cast<_Tp*>(__p);
404 template<typename... _Args>
405 _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
406 : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a)
409 void* __p = &_M_storage;
410 ::new (__p) _Tp(std::
forward<_Args>(__args)...);
411 _Base_type::_M_ptr = static_cast<_Tp*>(__p);
418 typedef typename _Alloc::template
419 rebind<_Sp_counted_ptr_inplace>::other _My_alloc_type;
420 _My_alloc_type __a(_Base_type::_M_del);
421 this->~_Sp_counted_ptr_inplace();
422 __a.deallocate(
this, 1);
430 return __ti ==
typeid(_Sp_make_shared_tag)
431 ? static_cast<void*>(&_M_storage)
432 : _Base_type::_M_get_deleter(__ti);
439 typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type
443 template<_Lock_policy _Lp>
447 constexpr __shared_count() : _M_pi(0)
450 template<
typename _Ptr>
452 __shared_count(_Ptr __p) : _M_pi(0)
456 _M_pi =
new _Sp_counted_ptr<_Ptr, _Lp>(__p);
461 __throw_exception_again;
465 template<
typename _Ptr,
typename _Deleter>
466 __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
470 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
475 _M_pi = __a2.allocate(1);
476 ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d);
482 __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1);
483 __throw_exception_again;
487 template<
typename _Ptr,
typename _Deleter,
typename _Alloc>
488 __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
490 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
491 typedef typename _Alloc::template rebind<_Sp_cd_type>::other _Alloc2;
495 _M_pi = __a2.allocate(1);
496 ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d, __a);
502 __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1);
503 __throw_exception_again;
507 template<
typename _Tp,
typename _Alloc,
typename... _Args>
508 __shared_count(_Sp_make_shared_tag, _Tp*,
const _Alloc& __a,
512 typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
513 typedef typename _Alloc::template rebind<_Sp_cp_type>::other _Alloc2;
517 _M_pi = __a2.allocate(1);
518 ::new(static_cast<void*>(_M_pi)) _Sp_cp_type(__a,
519 std::
forward<_Args>(__args)...);
524 __a2.deallocate(static_cast<_Sp_cp_type*>(_M_pi), 1);
525 __throw_exception_again;
529 #if _GLIBCXX_USE_DEPRECATED
531 template<
typename _Tp>
534 : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get()))
539 template<
typename _Tp,
typename _Del>
542 : _M_pi(_S_create_from_up(std::move(__r)))
546 explicit __shared_count(
const __weak_count<_Lp>& __r);
554 __shared_count(
const __shared_count& __r)
558 _M_pi->_M_add_ref_copy();
562 operator=(
const __shared_count& __r)
564 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
568 __tmp->_M_add_ref_copy();
577 _M_swap(__shared_count& __r)
579 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
585 _M_get_use_count() const
586 {
return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
590 {
return this->_M_get_use_count() == 1; }
594 {
return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
597 _M_less(
const __shared_count& __rhs)
const
601 _M_less(
const __weak_count<_Lp>& __rhs)
const
606 operator==(
const __shared_count& __a,
const __shared_count& __b)
607 {
return __a._M_pi == __b._M_pi; }
610 friend class __weak_count<_Lp>;
612 template<
typename _Tp,
typename _Del>
613 static _Sp_counted_base<_Lp>*
617 return new _Sp_counted_deleter<_Tp*, _Del, std::allocator<_Tp>,
618 _Lp>(__r.get(), __r.get_deleter());
621 template<
typename _Tp,
typename _Del>
622 static _Sp_counted_base<_Lp>*
626 typedef typename std::remove_reference<_Del>::type _Del1;
628 return new _Sp_counted_deleter<_Tp*, _Del2, std::allocator<_Tp>,
629 _Lp>(__r.get(),
std::ref(__r.get_deleter()));
632 _Sp_counted_base<_Lp>* _M_pi;
636 template<_Lock_policy _Lp>
640 constexpr __weak_count() : _M_pi(0)
643 __weak_count(
const __shared_count<_Lp>& __r) : _M_pi(__r._M_pi)
646 _M_pi->_M_weak_add_ref();
649 __weak_count(
const __weak_count<_Lp>& __r) : _M_pi(__r._M_pi)
652 _M_pi->_M_weak_add_ref();
658 _M_pi->_M_weak_release();
662 operator=(
const __shared_count<_Lp>& __r)
664 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
666 __tmp->_M_weak_add_ref();
668 _M_pi->_M_weak_release();
674 operator=(
const __weak_count<_Lp>& __r)
676 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
678 __tmp->_M_weak_add_ref();
680 _M_pi->_M_weak_release();
686 _M_swap(__weak_count<_Lp>& __r)
688 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
694 _M_get_use_count() const
695 {
return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
698 _M_less(
const __weak_count& __rhs)
const
702 _M_less(
const __shared_count<_Lp>& __rhs)
const
707 operator==(
const __weak_count& __a,
const __weak_count& __b)
708 {
return __a._M_pi == __b._M_pi; }
711 friend class __shared_count<_Lp>;
713 _Sp_counted_base<_Lp>* _M_pi;
717 template<_Lock_policy _Lp>
718 inline __shared_count<_Lp>:: __shared_count(
const __weak_count<_Lp>& __r)
722 _M_pi->_M_add_ref_lock();
724 __throw_bad_weak_ptr();
731 template<_Lock_policy _Lp,
typename _Tp1,
typename _Tp2>
733 __enable_shared_from_this_helper(
const __shared_count<_Lp>&,
734 const __enable_shared_from_this<_Tp1,
738 template<
typename _Tp1,
typename _Tp2>
740 __enable_shared_from_this_helper(
const __shared_count<>&,
741 const enable_shared_from_this<_Tp1>*,
744 template<_Lock_policy _Lp>
746 __enable_shared_from_this_helper(
const __shared_count<_Lp>&, ...)
750 template<
typename _Tp, _Lock_policy _Lp>
754 typedef _Tp element_type;
756 constexpr __shared_ptr()
757 : _M_ptr(0), _M_refcount()
760 template<
typename _Tp1>
761 explicit __shared_ptr(_Tp1* __p)
762 : _M_ptr(__p), _M_refcount(__p)
764 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
765 static_assert( sizeof(_Tp1) > 0, "incomplete type" );
766 __enable_shared_from_this_helper(_M_refcount, __p, __p);
769 template<typename _Tp1, typename _Deleter>
770 __shared_ptr(_Tp1* __p, _Deleter __d)
771 : _M_ptr(__p), _M_refcount(__p, __d)
773 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
775 __enable_shared_from_this_helper(_M_refcount, __p, __p);
778 template<typename _Tp1, typename _Deleter, typename _Alloc>
779 __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
780 : _M_ptr(__p), _M_refcount(__p, __d, std::move(__a))
782 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
784 __enable_shared_from_this_helper(_M_refcount, __p, __p);
787 template<typename _Deleter>
788 __shared_ptr(nullptr_t __p, _Deleter __d)
789 : _M_ptr(0), _M_refcount(__p, __d)
792 template<
typename _Deleter,
typename _Alloc>
793 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
794 : _M_ptr(0), _M_refcount(__p, __d, std::move(__a))
797 template<
typename _Tp1>
798 __shared_ptr(
const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p)
799 : _M_ptr(__p), _M_refcount(__r._M_refcount)
802 __shared_ptr(
const __shared_ptr&) =
default;
803 __shared_ptr& operator=(
const __shared_ptr&) =
default;
805 template<
typename _Tp1,
typename =
typename
807 __shared_ptr(
const __shared_ptr<_Tp1, _Lp>& __r)
808 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
811 __shared_ptr(__shared_ptr&& __r)
812 : _M_ptr(__r._M_ptr), _M_refcount()
814 _M_refcount._M_swap(__r._M_refcount);
818 template<
typename _Tp1,
typename =
typename
820 __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r)
821 : _M_ptr(__r._M_ptr), _M_refcount()
823 _M_refcount._M_swap(__r._M_refcount);
827 template<
typename _Tp1>
828 explicit __shared_ptr(
const __weak_ptr<_Tp1, _Lp>& __r)
829 : _M_refcount(__r._M_refcount)
831 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
839 template<typename _Tp1, typename _Del>
840 __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
841 : _M_ptr(__r.get()), _M_refcount()
843 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
844 _Tp1* __tmp = __r.get();
845 _M_refcount = __shared_count<_Lp>(std::move(__r));
846 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
849 #if _GLIBCXX_USE_DEPRECATED
851 template<
typename _Tp1>
853 : _M_ptr(__r.get()), _M_refcount()
855 __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
856 static_assert( sizeof(_Tp1) > 0, "incomplete type" );
857 _Tp1* __tmp = __r.get();
858 _M_refcount = __shared_count<_Lp>(std::move(__r));
859 __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
864 constexpr __shared_ptr(nullptr_t)
865 : _M_ptr(0), _M_refcount()
868 template<
typename _Tp1>
870 operator=(
const __shared_ptr<_Tp1, _Lp>& __r)
873 _M_refcount = __r._M_refcount;
877 #if _GLIBCXX_USE_DEPRECATED
878 template<
typename _Tp1>
882 __shared_ptr(std::move(__r)).swap(*
this);
888 operator=(__shared_ptr&& __r)
890 __shared_ptr(std::move(__r)).swap(*
this);
896 operator=(__shared_ptr<_Tp1, _Lp>&& __r)
898 __shared_ptr(std::move(__r)).swap(*
this);
902 template<
typename _Tp1,
typename _Del>
906 __shared_ptr(std::move(__r)).swap(*
this);
912 { __shared_ptr().swap(*
this); }
914 template<
typename _Tp1>
919 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
920 __shared_ptr(__p).swap(*
this);
923 template<
typename _Tp1,
typename _Deleter>
925 reset(_Tp1* __p, _Deleter __d)
926 { __shared_ptr(__p, __d).swap(*
this); }
928 template<
typename _Tp1,
typename _Deleter,
typename _Alloc>
930 reset(_Tp1* __p, _Deleter __d, _Alloc __a)
931 { __shared_ptr(__p, __d, std::move(__a)).swap(*
this); }
934 typename std::add_lvalue_reference<_Tp>::type
937 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
944 _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
952 explicit operator bool() const
953 {
return _M_ptr == 0 ?
false :
true; }
957 {
return _M_refcount._M_unique(); }
961 {
return _M_refcount._M_get_use_count(); }
964 swap(__shared_ptr<_Tp, _Lp>& __other)
966 std::swap(_M_ptr, __other._M_ptr);
967 _M_refcount._M_swap(__other._M_refcount);
970 template<
typename _Tp1>
972 owner_before(__shared_ptr<_Tp1, _Lp>
const& __rhs)
const
973 {
return _M_refcount._M_less(__rhs._M_refcount); }
975 template<
typename _Tp1>
977 owner_before(__weak_ptr<_Tp1, _Lp>
const& __rhs)
const
978 {
return _M_refcount._M_less(__rhs._M_refcount); }
983 template<
typename _Alloc,
typename... _Args>
984 __shared_ptr(_Sp_make_shared_tag __tag,
const _Alloc& __a,
986 : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
987 std::
forward<_Args>(__args)...)
991 void* __p = _M_refcount._M_get_deleter(
typeid(__tag));
992 _M_ptr =
static_cast<_Tp*
>(__p);
993 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
996 template<
typename _Alloc>
999 void operator()(_Tp* __ptr)
1001 _M_alloc.destroy(__ptr);
1002 _M_alloc.deallocate(__ptr, 1);
1007 template<
typename _Alloc,
typename... _Args>
1008 __shared_ptr(_Sp_make_shared_tag __tag,
const _Alloc& __a,
1010 : _M_ptr(), _M_refcount()
1012 typedef typename _Alloc::template rebind<_Tp>::other _Alloc2;
1013 _Deleter<_Alloc2> __del = { _Alloc2(__a) };
1014 _M_ptr = __del._M_alloc.allocate(1);
1017 __del._M_alloc.construct(_M_ptr, std::forward<_Args>(__args)...);
1021 __del._M_alloc.deallocate(_M_ptr, 1);
1022 __throw_exception_again;
1024 __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);
1025 _M_refcount._M_swap(__count);
1026 __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
1030 template<
typename _Tp1, _Lock_policy _Lp1,
typename _Alloc,
1032 friend __shared_ptr<_Tp1, _Lp1>
1033 __allocate_shared(
const _Alloc& __a, _Args&&... __args);
1038 {
return _M_refcount._M_get_deleter(__ti); }
1040 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __shared_ptr;
1041 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __weak_ptr;
1043 template<
typename _Del,
typename _Tp1, _Lock_policy _Lp1>
1044 friend _Del*
get_deleter(
const __shared_ptr<_Tp1, _Lp1>&);
1047 __shared_count<_Lp> _M_refcount;
1052 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
1054 operator==(
const __shared_ptr<_Tp1, _Lp>& __a,
1055 const __shared_ptr<_Tp2, _Lp>& __b)
1056 {
return __a.get() == __b.get(); }
1058 template<
typename _Tp, _Lock_policy _Lp>
1060 operator==(
const __shared_ptr<_Tp, _Lp>& __a, nullptr_t)
1061 {
return __a.get() ==
nullptr; }
1063 template<
typename _Tp, _Lock_policy _Lp>
1065 operator==(nullptr_t,
const __shared_ptr<_Tp, _Lp>& __b)
1066 {
return nullptr == __b.get(); }
1068 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
1070 operator!=(
const __shared_ptr<_Tp1, _Lp>& __a,
1071 const __shared_ptr<_Tp2, _Lp>& __b)
1072 {
return __a.get() != __b.get(); }
1074 template<
typename _Tp, _Lock_policy _Lp>
1076 operator!=(
const __shared_ptr<_Tp, _Lp>& __a, nullptr_t)
1077 {
return __a.get() !=
nullptr; }
1079 template<
typename _Tp, _Lock_policy _Lp>
1081 operator!=(nullptr_t,
const __shared_ptr<_Tp, _Lp>& __b)
1082 {
return nullptr != __b.get(); }
1084 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
1086 operator<(const __shared_ptr<_Tp1, _Lp>& __a,
1087 const __shared_ptr<_Tp2, _Lp>& __b)
1088 {
return __a.get() < __b.get(); }
1090 template<
typename _Sp>
1091 struct _Sp_less :
public binary_function<_Sp, _Sp, bool>
1094 operator()(
const _Sp& __lhs,
const _Sp& __rhs)
const
1096 typedef typename _Sp::element_type element_type;
1101 template<
typename _Tp, _Lock_policy _Lp>
1102 struct less<__shared_ptr<_Tp, _Lp>>
1103 :
public _Sp_less<__shared_ptr<_Tp, _Lp>>
1107 template<
typename _Tp, _Lock_policy _Lp>
1109 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
1119 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
1120 inline __shared_ptr<_Tp, _Lp>
1121 static_pointer_cast(
const __shared_ptr<_Tp1, _Lp>& __r)
1122 {
return __shared_ptr<_Tp, _Lp>(__r,
static_cast<_Tp*
>(__r.get())); }
1129 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
1130 inline __shared_ptr<_Tp, _Lp>
1131 const_pointer_cast(
const __shared_ptr<_Tp1, _Lp>& __r)
1132 {
return __shared_ptr<_Tp, _Lp>(__r,
const_cast<_Tp*
>(__r.get())); }
1139 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
1140 inline __shared_ptr<_Tp, _Lp>
1141 dynamic_pointer_cast(
const __shared_ptr<_Tp1, _Lp>& __r)
1143 if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
1144 return __shared_ptr<_Tp, _Lp>(__r, __p);
1145 return __shared_ptr<_Tp, _Lp>();
1149 template<
typename _Tp, _Lock_policy _Lp>
1153 typedef _Tp element_type;
1155 constexpr __weak_ptr()
1156 : _M_ptr(0), _M_refcount()
1175 template<
typename _Tp1,
typename =
typename
1177 __weak_ptr(
const __weak_ptr<_Tp1, _Lp>& __r)
1178 : _M_refcount(__r._M_refcount)
1179 { _M_ptr = __r.lock().get(); }
1181 template<
typename _Tp1,
typename =
typename
1183 __weak_ptr(
const __shared_ptr<_Tp1, _Lp>& __r)
1184 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1187 template<
typename _Tp1>
1189 operator=(
const __weak_ptr<_Tp1, _Lp>& __r)
1191 _M_ptr = __r.lock().get();
1192 _M_refcount = __r._M_refcount;
1196 template<
typename _Tp1>
1198 operator=(
const __shared_ptr<_Tp1, _Lp>& __r)
1200 _M_ptr = __r._M_ptr;
1201 _M_refcount = __r._M_refcount;
1205 __shared_ptr<_Tp, _Lp>
1211 return __shared_ptr<element_type, _Lp>();
1215 return __shared_ptr<element_type, _Lp>(*this);
1217 __catch(
const bad_weak_ptr&)
1222 return __shared_ptr<element_type, _Lp>();
1227 return expired() ? __shared_ptr<element_type, _Lp>()
1228 : __shared_ptr<element_type, _Lp>(*
this);
1235 {
return _M_refcount._M_get_use_count(); }
1239 {
return _M_refcount._M_get_use_count() == 0; }
1241 template<
typename _Tp1>
1243 owner_before(
const __shared_ptr<_Tp1, _Lp>& __rhs)
const
1244 {
return _M_refcount._M_less(__rhs._M_refcount); }
1246 template<
typename _Tp1>
1248 owner_before(
const __weak_ptr<_Tp1, _Lp>& __rhs)
const
1249 {
return _M_refcount._M_less(__rhs._M_refcount); }
1253 { __weak_ptr().swap(*
this); }
1256 swap(__weak_ptr& __s)
1258 std::swap(_M_ptr, __s._M_ptr);
1259 _M_refcount._M_swap(__s._M_refcount);
1265 _M_assign(_Tp* __ptr,
const __shared_count<_Lp>& __refcount)
1268 _M_refcount = __refcount;
1271 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __shared_ptr;
1272 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __weak_ptr;
1273 friend class __enable_shared_from_this<_Tp, _Lp>;
1274 friend class enable_shared_from_this<_Tp>;
1277 __weak_count<_Lp> _M_refcount;
1281 template<
typename _Tp, _Lock_policy _Lp>
1283 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
1286 template<
typename _Tp,
typename _Tp1>
1287 struct _Sp_owner_less :
public binary_function<_Tp, _Tp, bool>
1290 operator()(
const _Tp& __lhs,
const _Tp& __rhs)
const
1291 {
return __lhs.owner_before(__rhs); }
1294 operator()(
const _Tp& __lhs,
const _Tp1& __rhs)
const
1295 {
return __lhs.owner_before(__rhs); }
1298 operator()(
const _Tp1& __lhs,
const _Tp& __rhs)
const
1299 {
return __lhs.owner_before(__rhs); }
1302 template<
typename _Tp, _Lock_policy _Lp>
1303 struct owner_less<__shared_ptr<_Tp, _Lp>>
1304 :
public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
1307 template<
typename _Tp, _Lock_policy _Lp>
1308 struct owner_less<__weak_ptr<_Tp, _Lp>>
1309 :
public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
1313 template<
typename _Tp, _Lock_policy _Lp>
1314 class __enable_shared_from_this
1317 constexpr __enable_shared_from_this() { }
1319 __enable_shared_from_this(
const __enable_shared_from_this&) { }
1321 __enable_shared_from_this&
1322 operator=(
const __enable_shared_from_this&)
1325 ~__enable_shared_from_this() { }
1328 __shared_ptr<_Tp, _Lp>
1330 {
return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
1332 __shared_ptr<const _Tp, _Lp>
1333 shared_from_this()
const
1334 {
return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
1337 template<
typename _Tp1>
1339 _M_weak_assign(_Tp1* __p,
const __shared_count<_Lp>& __n)
const
1340 { _M_weak_this._M_assign(__p, __n); }
1342 template<
typename _Tp1>
1344 __enable_shared_from_this_helper(
const __shared_count<_Lp>& __pn,
1345 const __enable_shared_from_this* __pe,
1349 __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1352 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
1356 template<
typename _Tp, _Lock_policy _Lp,
typename _Alloc,
typename... _Args>
1357 inline __shared_ptr<_Tp, _Lp>
1358 __allocate_shared(
const _Alloc& __a, _Args&&... __args)
1360 return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a,
1361 std::forward<_Args>(__args)...);
1364 template<
typename _Tp, _Lock_policy _Lp,
typename... _Args>
1365 inline __shared_ptr<_Tp, _Lp>
1366 __make_shared(_Args&&... __args)
1368 typedef typename std::remove_const<_Tp>::type _Tp_nc;
1370 std::forward<_Args>(__args)...);
1374 template<
typename _Tp, _Lock_policy _Lp>
1375 struct hash<__shared_ptr<_Tp, _Lp>>
1379 operator()(
const __shared_ptr<_Tp, _Lp>& __s)
const
1383 _GLIBCXX_END_NAMESPACE_VERSION
1386 #endif // _SHARED_PTR_BASE_H
A simple smart pointer providing strict ownership semantics.
Primary class template for reference_wrapper.
20.7.12.2 unique_ptr for single objects.
Exception possibly thrown by shared_ptr.
reference_wrapper< _Tp > ref(_Tp &__t)
Denotes a reference should be taken to a variable.
void lock(_L1 &__l1, _L2 &__l2, _L3 &...__l3)
Generic lock.
_Del * get_deleter(const __shared_ptr< _Tp, _Lp > &__p)
2.2.3.10 shared_ptr get_deleter (experimental)
Partial specializations for pointer types.
Primary class template hash.
bitset< _Nb > & reset()
Sets every bit to false.
virtual char const * what() const
complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
One of the comparison functors.
Base class for all library exceptions.
_Tp && forward(typename std::remove_reference< _Tp >::type &__t)
forward (as per N3143)
The standard allocator, as per [20.4].Further details: http://gcc.gnu.org/onlinedocs/libstdc++/manual...