49 #ifndef _SHARED_PTR_BASE_H
50 #define _SHARED_PTR_BASE_H 1
57 #if __cplusplus > 201703L
61 namespace std _GLIBCXX_VISIBILITY(default)
63 _GLIBCXX_BEGIN_NAMESPACE_VERSION
65 #if _GLIBCXX_USE_DEPRECATED
66 #pragma GCC diagnostic push
67 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
68 template<
typename>
class auto_ptr;
69 #pragma GCC diagnostic pop
79 virtual char const*
what()
const noexcept;
86 __throw_bad_weak_ptr()
89 using __gnu_cxx::_Lock_policy;
90 using __gnu_cxx::__default_lock_policy;
91 using __gnu_cxx::_S_single;
92 using __gnu_cxx::_S_mutex;
93 using __gnu_cxx::_S_atomic;
96 template<_Lock_policy _Lp>
101 enum { _S_need_barriers = 0 };
105 class _Mutex_base<_S_mutex>
106 :
public __gnu_cxx::__mutex
112 enum { _S_need_barriers = 1 };
115 template<_Lock_policy _Lp = __default_lock_policy>
116 class _Sp_counted_base
117 :
public _Mutex_base<_Lp>
120 _Sp_counted_base() noexcept
121 : _M_use_count(1), _M_weak_count(1) { }
124 ~_Sp_counted_base() noexcept
130 _M_dispose() noexcept = 0;
134 _M_destroy() noexcept
142 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
148 _M_add_ref_lock_nothrow();
151 _M_release() noexcept
154 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
155 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
157 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
163 if (_Mutex_base<_Lp>::_S_need_barriers)
165 __atomic_thread_fence (__ATOMIC_ACQ_REL);
169 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
170 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
173 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
180 _M_weak_add_ref() noexcept
181 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
184 _M_weak_release() noexcept
187 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
188 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
190 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
191 if (_Mutex_base<_Lp>::_S_need_barriers)
195 __atomic_thread_fence (__ATOMIC_ACQ_REL);
202 _M_get_use_count() const noexcept
206 return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
210 _Sp_counted_base(_Sp_counted_base
const&) =
delete;
211 _Sp_counted_base& operator=(_Sp_counted_base
const&) =
delete;
213 _Atomic_word _M_use_count;
214 _Atomic_word _M_weak_count;
219 _Sp_counted_base<_S_single>::
222 if (_M_use_count == 0)
223 __throw_bad_weak_ptr();
229 _Sp_counted_base<_S_mutex>::
233 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
236 __throw_bad_weak_ptr();
242 _Sp_counted_base<_S_atomic>::
246 _Atomic_word __count = _M_get_use_count();
250 __throw_bad_weak_ptr();
254 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
255 true, __ATOMIC_ACQ_REL,
261 _Sp_counted_base<_S_single>::
262 _M_add_ref_lock_nothrow()
264 if (_M_use_count == 0)
272 _Sp_counted_base<_S_mutex>::
273 _M_add_ref_lock_nothrow()
276 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
286 _Sp_counted_base<_S_atomic>::
287 _M_add_ref_lock_nothrow()
290 _Atomic_word __count = _M_get_use_count();
298 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
299 true, __ATOMIC_ACQ_REL,
306 _Sp_counted_base<_S_single>::_M_add_ref_copy()
311 _Sp_counted_base<_S_single>::_M_release() noexcept
313 if (--_M_use_count == 0)
316 if (--_M_weak_count == 0)
323 _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept
328 _Sp_counted_base<_S_single>::_M_weak_release() noexcept
330 if (--_M_weak_count == 0)
336 _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept
337 {
return _M_use_count; }
341 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
344 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
347 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
348 class __enable_shared_from_this;
350 template<
typename _Tp>
353 template<
typename _Tp>
356 template<
typename _Tp>
359 template<
typename _Tp>
360 class enable_shared_from_this;
362 template<_Lock_policy _Lp = __default_lock_policy>
365 template<_Lock_policy _Lp = __default_lock_policy>
366 class __shared_count;
370 template<
typename _Ptr, _Lock_policy _Lp>
371 class _Sp_counted_ptr final :
public _Sp_counted_base<_Lp>
375 _Sp_counted_ptr(_Ptr __p) noexcept
379 _M_dispose() noexcept
383 _M_destroy() noexcept
390 _Sp_counted_ptr(
const _Sp_counted_ptr&) =
delete;
391 _Sp_counted_ptr& operator=(
const _Sp_counted_ptr&) =
delete;
399 _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { }
403 _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { }
407 _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { }
409 template<
int _Nm,
typename _Tp,
410 bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
411 struct _Sp_ebo_helper;
414 template<
int _Nm,
typename _Tp>
415 struct _Sp_ebo_helper<_Nm, _Tp, true> :
private _Tp
417 explicit _Sp_ebo_helper(
const _Tp& __tp) : _Tp(__tp) { }
418 explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(
std::move(__tp)) { }
421 _S_get(_Sp_ebo_helper& __eboh) {
return static_cast<_Tp&
>(__eboh); }
425 template<
int _Nm,
typename _Tp>
426 struct _Sp_ebo_helper<_Nm, _Tp, false>
428 explicit _Sp_ebo_helper(
const _Tp& __tp) : _M_tp(__tp) { }
429 explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(
std::move(__tp)) { }
432 _S_get(_Sp_ebo_helper& __eboh)
433 {
return __eboh._M_tp; }
440 template<
typename _Ptr,
typename _Deleter,
typename _Alloc, _Lock_policy _Lp>
441 class _Sp_counted_deleter final :
public _Sp_counted_base<_Lp>
443 class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc>
445 typedef _Sp_ebo_helper<0, _Deleter> _Del_base;
446 typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base;
449 _Impl(_Ptr __p, _Deleter __d,
const _Alloc& __a) noexcept
450 : _M_ptr(__p), _Del_base(
std::move(__d)), _Alloc_base(__a)
453 _Deleter& _M_del() noexcept {
return _Del_base::_S_get(*
this); }
454 _Alloc& _M_alloc() noexcept {
return _Alloc_base::_S_get(*
this); }
460 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>;
463 _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
464 : _M_impl(__p,
std::move(__d), _Alloc()) { }
467 _Sp_counted_deleter(_Ptr __p, _Deleter __d,
const _Alloc& __a) noexcept
470 ~_Sp_counted_deleter() noexcept { }
473 _M_dispose() noexcept
474 { _M_impl._M_del()(_M_impl._M_ptr); }
477 _M_destroy() noexcept
479 __allocator_type __a(_M_impl._M_alloc());
480 __allocated_ptr<__allocator_type> __guard_ptr{ __a,
this };
481 this->~_Sp_counted_deleter();
490 return __ti ==
typeid(_Deleter)
504 struct _Sp_make_shared_tag
507 template<
typename _Tp,
typename _Alloc, _Lock_policy _Lp>
508 friend class _Sp_counted_ptr_inplace;
510 static const type_info&
511 _S_ti() noexcept _GLIBCXX_VISIBILITY(default)
513 alignas(type_info)
static constexpr
char __tag[
sizeof(type_info)] = { };
514 return reinterpret_cast<const type_info&
>(__tag);
517 static bool _S_eq(
const type_info&) noexcept;
520 template<typename _Alloc>
521 struct _Sp_alloc_shared_tag
526 template<
typename _Tp,
typename _Alloc, _Lock_policy _Lp>
527 class _Sp_counted_ptr_inplace final :
public _Sp_counted_base<_Lp>
529 class _Impl : _Sp_ebo_helper<0, _Alloc>
531 typedef _Sp_ebo_helper<0, _Alloc> _A_base;
534 explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { }
536 _Alloc& _M_alloc() noexcept {
return _A_base::_S_get(*
this); }
538 __gnu_cxx::__aligned_buffer<_Tp> _M_storage;
542 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
545 template<
typename... _Args>
546 _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
551 allocator_traits<_Alloc>::construct(__a, _M_ptr(),
552 std::forward<_Args>(__args)...);
555 ~_Sp_counted_ptr_inplace() noexcept { }
558 _M_dispose() noexcept
560 allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
565 _M_destroy() noexcept
567 __allocator_type __a(_M_impl._M_alloc());
568 __allocated_ptr<__allocator_type> __guard_ptr{ __a,
this };
569 this->~_Sp_counted_ptr_inplace();
573 friend class __shared_count<_Lp>;
580 auto __ptr =
const_cast<typename remove_cv<_Tp>::type*
>(_M_ptr());
585 if (&__ti == &_Sp_make_shared_tag::_S_ti()
588 __ti ==
typeid(_Sp_make_shared_tag)
590 _Sp_make_shared_tag::_S_eq(__ti)
597 _Tp* _M_ptr() noexcept {
return _M_impl._M_storage._M_ptr(); }
603 struct __sp_array_delete
605 template<
typename _Yp>
606 void operator()(_Yp* __p)
const {
delete[] __p; }
609 template<_Lock_policy _Lp>
612 template<
typename _Tp>
613 struct __not_alloc_shared_tag {
using type = void; };
615 template<
typename _Tp>
616 struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { };
619 constexpr __shared_count() noexcept : _M_pi(0)
622 template<
typename _Ptr>
624 __shared_count(_Ptr __p) : _M_pi(0)
628 _M_pi =
new _Sp_counted_ptr<_Ptr, _Lp>(__p);
633 __throw_exception_again;
637 template<
typename _Ptr>
639 : __shared_count(__p)
642 template<
typename _Ptr>
644 : __shared_count(__p, __sp_array_delete{}, allocator<void>())
647 template<
typename _Ptr,
typename _Deleter,
648 typename =
typename __not_alloc_shared_tag<_Deleter>::type>
649 __shared_count(_Ptr __p, _Deleter __d)
650 : __shared_count(__p, std::
move(__d), allocator<void>())
653 template<
typename _Ptr,
typename _Deleter,
typename _Alloc,
654 typename =
typename __not_alloc_shared_tag<_Deleter>::type>
655 __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
657 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
660 typename _Sp_cd_type::__allocator_type __a2(__a);
662 _Sp_cd_type* __mem = __guard.get();
663 ::new (__mem) _Sp_cd_type(__p, std::
move(__d), std::
move(__a));
670 __throw_exception_again;
674 template<
typename _Tp,
typename _Alloc,
typename... _Args>
675 __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a,
678 typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
679 typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
681 _Sp_cp_type* __mem = __guard.get();
682 auto __pi = ::new (__mem)
683 _Sp_cp_type(__a._M_a, std::
forward<_Args>(__args)...);
686 __p = __pi->_M_ptr();
689 #if _GLIBCXX_USE_DEPRECATED
690 #pragma GCC diagnostic push
691 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
693 template<
typename _Tp>
696 #pragma GCC diagnostic pop
700 template<
typename _Tp,
typename _Del>
706 if (__r.get() ==
nullptr)
709 using _Ptr =
typename unique_ptr<_Tp, _Del>::pointer;
710 using _Del2 =
typename conditional<is_reference<_Del>::value,
711 reference_wrapper<typename remove_reference<_Del>::type>,
714 = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
715 using _Alloc = allocator<_Sp_cd_type>;
716 using _Alloc_traits = allocator_traits<_Alloc>;
718 _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
719 _Alloc_traits::construct(__a, __mem, __r.release(),
725 explicit __shared_count(
const __weak_count<_Lp>& __r);
728 explicit __shared_count(
const __weak_count<_Lp>& __r, std::nothrow_t);
730 ~__shared_count() noexcept
732 if (_M_pi !=
nullptr)
736 __shared_count(
const __shared_count& __r) noexcept
740 _M_pi->_M_add_ref_copy();
744 operator=(
const __shared_count& __r) noexcept
746 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
750 __tmp->_M_add_ref_copy();
759 _M_swap(__shared_count& __r) noexcept
761 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
767 _M_get_use_count() const noexcept
768 {
return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
771 _M_unique() const noexcept
772 {
return this->_M_get_use_count() == 1; }
776 {
return _M_pi ? _M_pi->_M_get_deleter(__ti) :
nullptr; }
779 _M_less(
const __shared_count& __rhs)
const noexcept
783 _M_less(
const __weak_count<_Lp>& __rhs)
const noexcept
788 operator==(
const __shared_count& __a,
const __shared_count& __b) noexcept
789 {
return __a._M_pi == __b._M_pi; }
792 friend class __weak_count<_Lp>;
794 _Sp_counted_base<_Lp>* _M_pi;
798 template<_Lock_policy _Lp>
802 constexpr __weak_count() noexcept : _M_pi(
nullptr)
805 __weak_count(
const __shared_count<_Lp>& __r) noexcept
808 if (_M_pi !=
nullptr)
809 _M_pi->_M_weak_add_ref();
812 __weak_count(
const __weak_count& __r) noexcept
815 if (_M_pi !=
nullptr)
816 _M_pi->_M_weak_add_ref();
819 __weak_count(__weak_count&& __r) noexcept
821 { __r._M_pi =
nullptr; }
823 ~__weak_count() noexcept
825 if (_M_pi !=
nullptr)
826 _M_pi->_M_weak_release();
830 operator=(
const __shared_count<_Lp>& __r) noexcept
832 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
833 if (__tmp !=
nullptr)
834 __tmp->_M_weak_add_ref();
835 if (_M_pi !=
nullptr)
836 _M_pi->_M_weak_release();
842 operator=(
const __weak_count& __r) noexcept
844 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
845 if (__tmp !=
nullptr)
846 __tmp->_M_weak_add_ref();
847 if (_M_pi !=
nullptr)
848 _M_pi->_M_weak_release();
854 operator=(__weak_count&& __r) noexcept
856 if (_M_pi !=
nullptr)
857 _M_pi->_M_weak_release();
864 _M_swap(__weak_count& __r) noexcept
866 _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
872 _M_get_use_count() const noexcept
873 {
return _M_pi !=
nullptr ? _M_pi->_M_get_use_count() : 0; }
876 _M_less(
const __weak_count& __rhs)
const noexcept
880 _M_less(
const __shared_count<_Lp>& __rhs)
const noexcept
885 operator==(
const __weak_count& __a,
const __weak_count& __b) noexcept
886 {
return __a._M_pi == __b._M_pi; }
889 friend class __shared_count<_Lp>;
891 _Sp_counted_base<_Lp>* _M_pi;
895 template<_Lock_policy _Lp>
897 __shared_count<_Lp>::__shared_count(
const __weak_count<_Lp>& __r)
900 if (_M_pi !=
nullptr)
901 _M_pi->_M_add_ref_lock();
903 __throw_bad_weak_ptr();
907 template<_Lock_policy _Lp>
909 __shared_count<_Lp>::
910 __shared_count(
const __weak_count<_Lp>& __r, std::nothrow_t)
913 if (_M_pi !=
nullptr)
914 if (!_M_pi->_M_add_ref_lock_nothrow())
918 #define __cpp_lib_shared_ptr_arrays 201611L
924 template<
typename _Yp_ptr,
typename _Tp_ptr>
925 struct __sp_compatible_with
929 template<
typename _Yp,
typename _Tp>
930 struct __sp_compatible_with<_Yp*, _Tp*>
931 : is_convertible<_Yp*, _Tp*>::type
934 template<
typename _Up,
size_t _Nm>
935 struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]>
939 template<
typename _Up,
size_t _Nm>
940 struct __sp_compatible_with<_Up(*)[_Nm],
const _Up(*)[]>
944 template<
typename _Up,
size_t _Nm>
945 struct __sp_compatible_with<_Up(*)[_Nm],
volatile _Up(*)[]>
949 template<
typename _Up,
size_t _Nm>
950 struct __sp_compatible_with<_Up(*)[_Nm],
const volatile _Up(*)[]>
955 template<
typename _Up,
size_t _Nm,
typename _Yp,
typename =
void>
956 struct __sp_is_constructible_arrN
960 template<
typename _Up,
size_t _Nm,
typename _Yp>
961 struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
962 : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
966 template<
typename _Up,
typename _Yp,
typename =
void>
967 struct __sp_is_constructible_arr
971 template<
typename _Up,
typename _Yp>
972 struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
973 : is_convertible<_Yp(*)[], _Up(*)[]>::type
977 template<
typename _Tp,
typename _Yp>
978 struct __sp_is_constructible;
981 template<
typename _Up,
size_t _Nm,
typename _Yp>
982 struct __sp_is_constructible<_Up[_Nm], _Yp>
983 : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
987 template<
typename _Up,
typename _Yp>
988 struct __sp_is_constructible<_Up[], _Yp>
989 : __sp_is_constructible_arr<_Up, _Yp>::type
993 template<
typename _Tp,
typename _Yp>
994 struct __sp_is_constructible
995 : is_convertible<_Yp*, _Tp*>::type
1000 template<
typename _Tp, _Lock_policy _Lp,
1001 bool = is_array<_Tp>::value,
bool = is_void<_Tp>::value>
1002 class __shared_ptr_access
1005 using element_type = _Tp;
1010 __glibcxx_assert(_M_get() !=
nullptr);
1015 operator->() const noexcept
1017 _GLIBCXX_DEBUG_PEDASSERT(_M_get() !=
nullptr);
1023 _M_get() const noexcept
1024 {
return static_cast<const __shared_ptr<_Tp, _Lp>*
>(
this)->
get(); }
1028 template<
typename _Tp, _Lock_policy _Lp>
1029 class __shared_ptr_access<_Tp, _Lp, false, true>
1032 using element_type = _Tp;
1035 operator->() const noexcept
1037 auto __ptr =
static_cast<const __shared_ptr<_Tp, _Lp>*
>(
this)->
get();
1038 _GLIBCXX_DEBUG_PEDASSERT(__ptr !=
nullptr);
1044 template<
typename _Tp, _Lock_policy _Lp>
1045 class __shared_ptr_access<_Tp, _Lp, true, false>
1048 using element_type =
typename remove_extent<_Tp>::type;
1050 #if __cplusplus <= 201402L
1051 [[__deprecated__(
"shared_ptr<T[]>::operator* is absent from C++17")]]
1055 __glibcxx_assert(_M_get() !=
nullptr);
1059 [[__deprecated__(
"shared_ptr<T[]>::operator-> is absent from C++17")]]
1061 operator->() const noexcept
1063 _GLIBCXX_DEBUG_PEDASSERT(_M_get() !=
nullptr);
1069 operator[](ptrdiff_t __i)
const
1071 __glibcxx_assert(_M_get() !=
nullptr);
1072 __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value);
1073 return _M_get()[__i];
1078 _M_get() const noexcept
1079 {
return static_cast<const __shared_ptr<_Tp, _Lp>*
>(
this)->
get(); }
1082 template<
typename _Tp, _Lock_policy _Lp>
1084 :
public __shared_ptr_access<_Tp, _Lp>
1087 using element_type =
typename remove_extent<_Tp>::type;
1091 template<
typename _Yp>
1093 =
typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type;
1096 template<
typename _Yp,
typename _Res =
void>
1097 using _Compatible =
typename
1098 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
1101 template<
typename _Yp>
1102 using _Assignable = _Compatible<_Yp, __shared_ptr&>;
1105 template<
typename _Yp,
typename _Del,
typename _Res = void,
1106 typename _Ptr =
typename unique_ptr<_Yp, _Del>::pointer>
1107 using _UniqCompatible =
typename enable_if<__and_<
1108 __sp_compatible_with<_Yp*, _Tp*>, is_convertible<_Ptr, element_type*>
1109 >::value, _Res>::type;
1112 template<
typename _Yp,
typename _Del>
1113 using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>;
1117 #if __cplusplus > 201402L
1118 using weak_type = __weak_ptr<_Tp, _Lp>;
1121 constexpr __shared_ptr() noexcept
1122 : _M_ptr(0), _M_refcount()
1125 template<
typename _Yp,
typename = _SafeConv<_Yp>>
1127 __shared_ptr(_Yp* __p)
1128 : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type())
1130 static_assert( !is_void<_Yp>::value,
"incomplete type" );
1131 static_assert(
sizeof(_Yp) > 0,
"incomplete type" );
1132 _M_enable_shared_from_this_with(__p);
1135 template<
typename _Yp,
typename _Deleter,
typename = _SafeConv<_Yp>>
1136 __shared_ptr(_Yp* __p, _Deleter __d)
1137 : _M_ptr(__p), _M_refcount(__p, std::
move(__d))
1139 static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1140 "deleter expression d(p) is well-formed");
1141 _M_enable_shared_from_this_with(__p);
1144 template<
typename _Yp,
typename _Deleter,
typename _Alloc,
1145 typename = _SafeConv<_Yp>>
1146 __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
1147 : _M_ptr(__p), _M_refcount(__p, std::
move(__d), std::
move(__a))
1149 static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1150 "deleter expression d(p) is well-formed");
1151 _M_enable_shared_from_this_with(__p);
1154 template<
typename _Deleter>
1155 __shared_ptr(nullptr_t __p, _Deleter __d)
1156 : _M_ptr(0), _M_refcount(__p, std::
move(__d))
1159 template<
typename _Deleter,
typename _Alloc>
1160 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
1161 : _M_ptr(0), _M_refcount(__p, std::
move(__d), std::
move(__a))
1165 template<
typename _Yp>
1166 __shared_ptr(
const __shared_ptr<_Yp, _Lp>& __r,
1167 element_type* __p) noexcept
1168 : _M_ptr(__p), _M_refcount(__r._M_refcount)
1172 template<
typename _Yp>
1173 __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r,
1174 element_type* __p) noexcept
1175 : _M_ptr(__p), _M_refcount()
1177 _M_refcount._M_swap(__r._M_refcount);
1181 __shared_ptr(
const __shared_ptr&) noexcept = default;
1182 __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
1183 ~__shared_ptr() = default;
1185 template<typename _Yp, typename = _Compatible<_Yp>>
1186 __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1187 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1190 __shared_ptr(__shared_ptr&& __r) noexcept
1191 : _M_ptr(__r._M_ptr), _M_refcount()
1193 _M_refcount._M_swap(__r._M_refcount);
1197 template<
typename _Yp,
typename = _Compatible<_Yp>>
1198 __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1199 : _M_ptr(__r._M_ptr), _M_refcount()
1201 _M_refcount._M_swap(__r._M_refcount);
1205 template<
typename _Yp,
typename = _Compatible<_Yp>>
1206 explicit __shared_ptr(
const __weak_ptr<_Yp, _Lp>& __r)
1207 : _M_refcount(__r._M_refcount)
1211 _M_ptr = __r._M_ptr;
1215 template<
typename _Yp,
typename _Del,
1216 typename = _UniqCompatible<_Yp, _Del>>
1217 __shared_ptr(unique_ptr<_Yp, _Del>&& __r)
1218 : _M_ptr(__r.get()), _M_refcount()
1220 auto __raw = __to_address(__r.get());
1221 _M_refcount = __shared_count<_Lp>(
std::move(__r));
1222 _M_enable_shared_from_this_with(__raw);
1225 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
1228 template<
typename _Tp1,
typename _Del,
1229 typename enable_if<__and_<
1230 __not_<is_array<_Tp>>, is_array<_Tp1>,
1231 is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*>
1232 >::value,
bool>::type =
true>
1233 __shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete)
1234 : _M_ptr(__r.get()), _M_refcount()
1236 auto __raw = __to_address(__r.get());
1237 _M_refcount = __shared_count<_Lp>(
std::move(__r));
1238 _M_enable_shared_from_this_with(__raw);
1243 #if _GLIBCXX_USE_DEPRECATED
1244 #pragma GCC diagnostic push
1245 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1247 template<
typename _Yp,
typename = _Compatible<_Yp>>
1248 __shared_ptr(auto_ptr<_Yp>&& __r);
1249 #pragma GCC diagnostic pop
1252 constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
1254 template<
typename _Yp>
1256 operator=(
const __shared_ptr<_Yp, _Lp>& __r) noexcept
1258 _M_ptr = __r._M_ptr;
1259 _M_refcount = __r._M_refcount;
1263 #if _GLIBCXX_USE_DEPRECATED
1264 #pragma GCC diagnostic push
1265 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1266 template<
typename _Yp>
1268 operator=(auto_ptr<_Yp>&& __r)
1270 __shared_ptr(
std::move(__r)).swap(*
this);
1273 #pragma GCC diagnostic pop
1277 operator=(__shared_ptr&& __r) noexcept
1279 __shared_ptr(
std::move(__r)).swap(*
this);
1285 operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1287 __shared_ptr(
std::move(__r)).swap(*
this);
1291 template<
typename _Yp,
typename _Del>
1292 _UniqAssignable<_Yp, _Del>
1293 operator=(unique_ptr<_Yp, _Del>&& __r)
1295 __shared_ptr(
std::move(__r)).swap(*
this);
1301 { __shared_ptr().swap(*
this); }
1303 template<
typename _Yp>
1308 __glibcxx_assert(__p == 0 || __p != _M_ptr);
1309 __shared_ptr(__p).swap(*
this);
1312 template<
typename _Yp,
typename _Deleter>
1314 reset(_Yp* __p, _Deleter __d)
1315 { __shared_ptr(__p,
std::move(__d)).swap(*
this); }
1317 template<
typename _Yp,
typename _Deleter,
typename _Alloc>
1319 reset(_Yp* __p, _Deleter __d, _Alloc __a)
1324 get()
const noexcept
1328 explicit operator bool() const
1329 {
return _M_ptr == 0 ?
false :
true; }
1333 unique() const noexcept
1334 {
return _M_refcount._M_unique(); }
1338 use_count() const noexcept
1339 {
return _M_refcount._M_get_use_count(); }
1343 swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
1345 std::swap(_M_ptr, __other._M_ptr);
1346 _M_refcount._M_swap(__other._M_refcount);
1356 template<
typename _Tp1>
1358 owner_before(__shared_ptr<_Tp1, _Lp>
const& __rhs)
const noexcept
1359 {
return _M_refcount._M_less(__rhs._M_refcount); }
1361 template<
typename _Tp1>
1363 owner_before(__weak_ptr<_Tp1, _Lp>
const& __rhs)
const noexcept
1364 {
return _M_refcount._M_less(__rhs._M_refcount); }
1369 template<
typename _Alloc,
typename... _Args>
1370 __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
1371 : _M_ptr(), _M_refcount(_M_ptr, __tag, std::
forward<_Args>(__args)...)
1372 { _M_enable_shared_from_this_with(_M_ptr); }
1374 template<
typename _Tp1, _Lock_policy _Lp1,
typename _Alloc,
1376 friend __shared_ptr<_Tp1, _Lp1>
1377 __allocate_shared(
const _Alloc& __a, _Args&&... __args);
1381 __shared_ptr(
const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t)
1382 : _M_refcount(__r._M_refcount, std::nothrow)
1384 _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr :
nullptr;
1387 friend class __weak_ptr<_Tp, _Lp>;
1391 template<
typename _Yp>
1392 using __esft_base_t = decltype(__enable_shared_from_this_base(
1393 std::declval<
const __shared_count<_Lp>&>(),
1394 std::declval<_Yp*>()));
1397 template<
typename _Yp,
typename =
void>
1398 struct __has_esft_base
1401 template<
typename _Yp>
1402 struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
1403 : __not_<is_array<_Tp>> { };
1405 template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1406 typename enable_if<__has_esft_base<_Yp2>::value>::type
1407 _M_enable_shared_from_this_with(_Yp* __p) noexcept
1409 if (
auto __base = __enable_shared_from_this_base(_M_refcount, __p))
1410 __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount);
1413 template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1414 typename enable_if<!__has_esft_base<_Yp2>::value>::type
1415 _M_enable_shared_from_this_with(_Yp*) noexcept
1420 {
return _M_refcount._M_get_deleter(__ti); }
1422 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __shared_ptr;
1423 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __weak_ptr;
1425 template<
typename _Del,
typename _Tp1, _Lock_policy _Lp1>
1426 friend _Del* get_deleter(
const __shared_ptr<_Tp1, _Lp1>&) noexcept;
1428 template<typename _Del, typename _Tp1>
1429 friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept;
1431 element_type* _M_ptr;
1432 __shared_count<_Lp> _M_refcount;
1437 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1439 operator==(const __shared_ptr<_Tp1, _Lp>& __a,
1440 const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1441 {
return __a.get() == __b.get(); }
1443 template<
typename _Tp, _Lock_policy _Lp>
1445 operator==(
const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1448 #ifdef __cpp_lib_three_way_comparison
1449 template<
typename _Tp,
typename _Up, _Lock_policy _Lp>
1450 inline strong_ordering
1451 operator<=>(
const __shared_ptr<_Tp, _Lp>& __a,
1452 const __shared_ptr<_Up, _Lp>& __b) noexcept
1453 {
return compare_three_way()(__a.get(), __b.get()); }
1455 template<
typename _Tp, _Lock_policy _Lp>
1456 inline strong_ordering
1457 operator<=>(
const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1459 using pointer =
typename __shared_ptr<_Tp, _Lp>::element_type*;
1460 return compare_three_way()(__a.get(),
static_cast<pointer
>(
nullptr));
1463 template<
typename _Tp, _Lock_policy _Lp>
1465 operator==(nullptr_t,
const __shared_ptr<_Tp, _Lp>& __a) noexcept
1468 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
1470 operator!=(
const __shared_ptr<_Tp1, _Lp>& __a,
1471 const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1472 {
return __a.get() != __b.get(); }
1474 template<
typename _Tp, _Lock_policy _Lp>
1476 operator!=(
const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1477 {
return (
bool)__a; }
1479 template<
typename _Tp, _Lock_policy _Lp>
1481 operator!=(nullptr_t,
const __shared_ptr<_Tp, _Lp>& __a) noexcept
1482 {
return (
bool)__a; }
1484 template<
typename _Tp,
typename _Up, _Lock_policy _Lp>
1486 operator<(const __shared_ptr<_Tp, _Lp>& __a,
1487 const __shared_ptr<_Up, _Lp>& __b) noexcept
1489 using _Tp_elt =
typename __shared_ptr<_Tp, _Lp>::element_type;
1490 using _Up_elt =
typename __shared_ptr<_Up, _Lp>::element_type;
1491 using _Vp =
typename common_type<_Tp_elt*, _Up_elt*>::type;
1492 return less<_Vp>()(__a.get(), __b.get());
1495 template<
typename _Tp, _Lock_policy _Lp>
1497 operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1499 using _Tp_elt =
typename __shared_ptr<_Tp, _Lp>::element_type;
1500 return less<_Tp_elt*>()(__a.get(),
nullptr);
1503 template<
typename _Tp, _Lock_policy _Lp>
1505 operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1507 using _Tp_elt =
typename __shared_ptr<_Tp, _Lp>::element_type;
1508 return less<_Tp_elt*>()(
nullptr, __a.get());
1511 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
1513 operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
1514 const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1515 {
return !(__b < __a); }
1517 template<
typename _Tp, _Lock_policy _Lp>
1519 operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1520 {
return !(
nullptr < __a); }
1522 template<
typename _Tp, _Lock_policy _Lp>
1524 operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1525 {
return !(__a <
nullptr); }
1527 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
1529 operator>(
const __shared_ptr<_Tp1, _Lp>& __a,
1530 const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1531 {
return (__b < __a); }
1533 template<
typename _Tp, _Lock_policy _Lp>
1535 operator>(
const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1536 {
return nullptr < __a; }
1538 template<
typename _Tp, _Lock_policy _Lp>
1540 operator>(nullptr_t,
const __shared_ptr<_Tp, _Lp>& __a) noexcept
1541 {
return __a <
nullptr; }
1543 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
1545 operator>=(
const __shared_ptr<_Tp1, _Lp>& __a,
1546 const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1547 {
return !(__a < __b); }
1549 template<
typename _Tp, _Lock_policy _Lp>
1551 operator>=(
const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1552 {
return !(__a <
nullptr); }
1554 template<
typename _Tp, _Lock_policy _Lp>
1556 operator>=(nullptr_t,
const __shared_ptr<_Tp, _Lp>& __a) noexcept
1557 {
return !(
nullptr < __a); }
1558 #endif // three-way comparison
1561 template<
typename _Tp, _Lock_policy _Lp>
1563 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
1573 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
1574 inline __shared_ptr<_Tp, _Lp>
1577 using _Sp = __shared_ptr<_Tp, _Lp>;
1578 return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
1586 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
1587 inline __shared_ptr<_Tp, _Lp>
1590 using _Sp = __shared_ptr<_Tp, _Lp>;
1591 return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
1599 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
1600 inline __shared_ptr<_Tp, _Lp>
1603 using _Sp = __shared_ptr<_Tp, _Lp>;
1604 if (
auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
1605 return _Sp(__r, __p);
1609 #if __cplusplus > 201402L
1610 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
1611 inline __shared_ptr<_Tp, _Lp>
1612 reinterpret_pointer_cast(
const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1614 using _Sp = __shared_ptr<_Tp, _Lp>;
1615 return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
1619 template<
typename _Tp, _Lock_policy _Lp>
1622 template<
typename _Yp,
typename _Res =
void>
1623 using _Compatible =
typename
1624 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
1627 template<
typename _Yp>
1628 using _Assignable = _Compatible<_Yp, __weak_ptr&>;
1631 using element_type =
typename remove_extent<_Tp>::type;
1633 constexpr __weak_ptr() noexcept
1634 : _M_ptr(
nullptr), _M_refcount()
1637 __weak_ptr(
const __weak_ptr&) noexcept = default;
1639 ~__weak_ptr() = default;
1655 template<typename _Yp, typename = _Compatible<_Yp>>
1656 __weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept
1657 : _M_refcount(__r._M_refcount)
1658 { _M_ptr = __r.lock().get(); }
1660 template<
typename _Yp,
typename = _Compatible<_Yp>>
1661 __weak_ptr(
const __shared_ptr<_Yp, _Lp>& __r) noexcept
1662 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1665 __weak_ptr(__weak_ptr&& __r) noexcept
1666 : _M_ptr(__r._M_ptr), _M_refcount(std::
move(__r._M_refcount))
1667 { __r._M_ptr =
nullptr; }
1669 template<
typename _Yp,
typename = _Compatible<_Yp>>
1670 __weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept
1671 : _M_ptr(__r.
lock().get()), _M_refcount(std::
move(__r._M_refcount))
1672 { __r._M_ptr =
nullptr; }
1675 operator=(
const __weak_ptr& __r) noexcept =
default;
1677 template<
typename _Yp>
1679 operator=(
const __weak_ptr<_Yp, _Lp>& __r) noexcept
1681 _M_ptr = __r.lock().get();
1682 _M_refcount = __r._M_refcount;
1686 template<
typename _Yp>
1688 operator=(
const __shared_ptr<_Yp, _Lp>& __r) noexcept
1690 _M_ptr = __r._M_ptr;
1691 _M_refcount = __r._M_refcount;
1696 operator=(__weak_ptr&& __r) noexcept
1698 _M_ptr = __r._M_ptr;
1699 _M_refcount =
std::move(__r._M_refcount);
1700 __r._M_ptr =
nullptr;
1704 template<
typename _Yp>
1706 operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept
1708 _M_ptr = __r.lock().get();
1709 _M_refcount =
std::move(__r._M_refcount);
1710 __r._M_ptr =
nullptr;
1714 __shared_ptr<_Tp, _Lp>
1715 lock() const noexcept
1716 {
return __shared_ptr<element_type, _Lp>(*
this, std::nothrow); }
1719 use_count() const noexcept
1720 {
return _M_refcount._M_get_use_count(); }
1723 expired() const noexcept
1724 {
return _M_refcount._M_get_use_count() == 0; }
1726 template<
typename _Tp1>
1728 owner_before(
const __shared_ptr<_Tp1, _Lp>& __rhs)
const noexcept
1729 {
return _M_refcount._M_less(__rhs._M_refcount); }
1731 template<
typename _Tp1>
1733 owner_before(
const __weak_ptr<_Tp1, _Lp>& __rhs)
const noexcept
1734 {
return _M_refcount._M_less(__rhs._M_refcount); }
1738 { __weak_ptr().swap(*
this); }
1741 swap(__weak_ptr& __s) noexcept
1743 std::swap(_M_ptr, __s._M_ptr);
1744 _M_refcount._M_swap(__s._M_refcount);
1750 _M_assign(_Tp* __ptr,
const __shared_count<_Lp>& __refcount) noexcept
1752 if (use_count() == 0)
1755 _M_refcount = __refcount;
1759 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __shared_ptr;
1760 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __weak_ptr;
1761 friend class __enable_shared_from_this<_Tp, _Lp>;
1762 friend class enable_shared_from_this<_Tp>;
1764 element_type* _M_ptr;
1765 __weak_count<_Lp> _M_refcount;
1769 template<
typename _Tp, _Lock_policy _Lp>
1771 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
1774 template<
typename _Tp,
typename _Tp1>
1775 struct _Sp_owner_less :
public binary_function<_Tp, _Tp, bool>
1778 operator()(
const _Tp& __lhs,
const _Tp& __rhs)
const noexcept
1779 {
return __lhs.owner_before(__rhs); }
1782 operator()(
const _Tp& __lhs,
const _Tp1& __rhs)
const noexcept
1783 {
return __lhs.owner_before(__rhs); }
1786 operator()(
const _Tp1& __lhs,
const _Tp& __rhs)
const noexcept
1787 {
return __lhs.owner_before(__rhs); }
1791 struct _Sp_owner_less<void, void>
1793 template<
typename _Tp,
typename _Up>
1795 operator()(
const _Tp& __lhs,
const _Up& __rhs)
const noexcept
1796 -> decltype(__lhs.owner_before(__rhs))
1797 {
return __lhs.owner_before(__rhs); }
1799 using is_transparent = void;
1802 template<
typename _Tp, _Lock_policy _Lp>
1803 struct owner_less<__shared_ptr<_Tp, _Lp>>
1804 :
public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
1807 template<
typename _Tp, _Lock_policy _Lp>
1808 struct owner_less<__weak_ptr<_Tp, _Lp>>
1809 :
public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
1813 template<
typename _Tp, _Lock_policy _Lp>
1814 class __enable_shared_from_this
1817 constexpr __enable_shared_from_this() noexcept { }
1819 __enable_shared_from_this(
const __enable_shared_from_this&) noexcept { }
1821 __enable_shared_from_this&
1822 operator=(
const __enable_shared_from_this&) noexcept
1825 ~__enable_shared_from_this() { }
1828 __shared_ptr<_Tp, _Lp>
1830 {
return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
1832 __shared_ptr<const _Tp, _Lp>
1833 shared_from_this()
const
1834 {
return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
1836 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1837 __weak_ptr<_Tp, _Lp>
1838 weak_from_this() noexcept
1839 {
return this->_M_weak_this; }
1841 __weak_ptr<const _Tp, _Lp>
1842 weak_from_this() const noexcept
1843 {
return this->_M_weak_this; }
1847 template<
typename _Tp1>
1849 _M_weak_assign(_Tp1* __p,
const __shared_count<_Lp>& __n)
const noexcept
1850 { _M_weak_this._M_assign(__p, __n); }
1852 friend const __enable_shared_from_this*
1853 __enable_shared_from_this_base(
const __shared_count<_Lp>&,
1854 const __enable_shared_from_this* __p)
1857 template<
typename, _Lock_policy>
1858 friend class __shared_ptr;
1860 mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
1863 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy,
1864 typename _Alloc,
typename... _Args>
1865 inline __shared_ptr<_Tp, _Lp>
1866 __allocate_shared(
const _Alloc& __a, _Args&&... __args)
1868 return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a},
1869 std::forward<_Args>(__args)...);
1872 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy,
1874 inline __shared_ptr<_Tp, _Lp>
1875 __make_shared(_Args&&... __args)
1877 typedef typename std::remove_const<_Tp>::type _Tp_nc;
1879 std::forward<_Args>(__args)...);
1883 template<
typename _Tp, _Lock_policy _Lp>
1884 struct hash<__shared_ptr<_Tp, _Lp>>
1885 :
public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
1888 operator()(
const __shared_ptr<_Tp, _Lp>& __s)
const noexcept
1895 _GLIBCXX_END_NAMESPACE_VERSION
1898 #endif // _SHARED_PTR_BASE_H
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
__shared_ptr< _Tp, _Lp > dynamic_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
dynamic_pointer_cast
__allocated_ptr< _Alloc > __allocate_guarded(_Alloc &__a)
Allocate space for a single object using __a.
void lock(_L1 &__l1, _L2 &__l2, _L3 &...__l3)
Generic lock.
__shared_ptr< _Tp, _Lp > const_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
const_pointer_cast
virtual char const * what() const noexcept
A simple smart pointer providing strict ownership semantics.
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
The standard allocator, as per [20.4].
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
constexpr _Iterator __base(_Iterator __it)
__shared_ptr< _Tp, _Lp > static_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
static_pointer_cast
Primary class template hash.
One of the comparison functors.
Base class for all library exceptions.
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Exception possibly thrown by shared_ptr.
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
20.7.1.2 unique_ptr for single objects.