49#ifndef _SHARED_PTR_BASE_H
50#define _SHARED_PTR_BASE_H 1
63#if __cplusplus >= 202002L
73#if _GLIBCXX_USE_DEPRECATED
74#pragma GCC diagnostic push
75#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
77#pragma GCC diagnostic pop
87 virtual char const*
what() const noexcept;
104 template<_Lock_policy _Lp>
123 template<_Lock_policy _Lp = __default_lock_policy>
181 __atomic_thread_fence (__ATOMIC_ACQ_REL);
195 __attribute__((__noinline__))
208 [[__unlikely__]] __builtin_trap();
224 __atomic_thread_fence (__ATOMIC_ACQ_REL);
235 auto __count = __atomic_load_n(&
_M_use_count, __ATOMIC_RELAXED);
247#pragma GCC diagnostic push
248#pragma GCC diagnostic ignored "-Wignored-attributes"
251#pragma GCC diagnostic pop
277 =
sizeof(long) >
sizeof(
_Atomic_word) ? -1 : __max_atomic_word;
279 if (__count == __max) [[__unlikely__]]
360 while (!__atomic_compare_exchange_n(&
_M_use_count, &__count, __count + 1,
361 true, __ATOMIC_ACQ_REL,
394#pragma GCC diagnostic push
395#pragma GCC diagnostic ignored "-Wc++17-extensions"
398 constexpr bool __lock_free
399 = __atomic_always_lock_free(
sizeof(
long long), 0)
401 constexpr bool __double_word
405 constexpr bool __aligned = __alignof(
long long) <=
alignof(
void*);
406 if constexpr (__lock_free && __double_word && __aligned)
408 constexpr int __wordbits = __CHAR_BIT__ *
sizeof(
_Atomic_word);
409 constexpr int __shiftbits = __double_word ? __wordbits : 0;
410 constexpr long long __unique_ref = 1LL + (1LL << __shiftbits);
411 auto __both_counts =
reinterpret_cast<long long*
>(&
_M_use_count);
414 if (__atomic_load_n(__both_counts, __ATOMIC_ACQUIRE) == __unique_ref)
440#pragma GCC diagnostic pop
444 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
447 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
450 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
453 template<
typename _Tp>
456 template<
typename _Tp>
459 template<
typename _Tp>
462 template<
typename _Tp>
465 template<_Lock_policy _Lp = __default_lock_policy>
468 template<_Lock_policy _Lp = __default_lock_policy>
471#ifdef __glibcxx_atomic_shared_ptr
477 template<
typename _Ptr, _Lock_policy _Lp>
521 template<
int _Nm,
typename _Tp,
522 bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
526 template<
int _Nm,
typename _Tp>
537 template<
int _Nm,
typename _Tp>
545 {
return __eboh._M_tp; }
552 template<
typename _Ptr,
typename _Deleter,
typename _Alloc, _Lock_policy _Lp>
561 _Impl(_Ptr __p, _Deleter __d,
const _Alloc& __a) noexcept
565 _Deleter&
_M_del() noexcept {
return _Del_base::_S_get(*
this); }
566 _Alloc&
_M_alloc() noexcept {
return _Alloc_base::_S_get(*
this); }
582#pragma GCC diagnostic push
583#pragma GCC diagnostic ignored "-Wfree-nonheap-object"
586#pragma GCC diagnostic pop
596 __allocated_ptr<__allocator_type> __guard_ptr{ __a,
this };
606 return __ti ==
typeid(_Deleter)
615#ifdef __glibcxx_out_ptr
616 template<
typename,
typename,
typename...>
friend class out_ptr_t;
626 template<
typename _Tp,
typename _Alloc, _Lock_policy _Lp>
633 return reinterpret_cast<const type_info&
>(__tag);
639 template<
typename _Alloc>
645 template<
typename _Tp,
typename _Alloc, _Lock_policy _Lp>
655 _Alloc&
_M_alloc() noexcept {
return _A_base::_S_get(*
this); }
664 template<
typename... _Args>
674#pragma GCC diagnostic push
675#pragma GCC diagnostic ignored "-Warray-bounds"
677#pragma GCC diagnostic pop
690 __allocated_ptr<__allocator_type> __guard_ptr{ __a,
this };
724#ifdef __glibcxx_smart_ptr_for_overwrite
725 struct _Sp_overwrite_tag { };
731 template<
typename _Tp,
typename _Alloc, _Lock_policy _Lp>
732 requires is_same_v<typename _Alloc::value_type, _Sp_overwrite_tag>
733 class _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> final
735 template<typename _Tp, template<typename> class _Alloc,
_Lock_policy _Lp>
736 class _Sp_counted_ptr_inplace<_Tp, _Alloc<_Sp_overwrite_tag>, _Lp> final
738 :
public _Sp_counted_base<_Lp>
740 [[no_unique_address]] _Alloc _M_alloc;
743 remove_cv_t<_Tp> _M_obj;
747 friend class __shared_count<_Lp>;
752 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
754 _Sp_counted_ptr_inplace(
const _Alloc& __a)
757 ::new((
void*)_M_ptr()) _Tp;
760 ~_Sp_counted_ptr_inplace() noexcept { }
763 _M_dispose() noexcept
770 _M_destroy() noexcept
772 using pointer =
typename allocator_traits<__allocator_type>::pointer;
773 __allocator_type __a(_M_alloc);
774 auto __p = pointer_traits<pointer>::pointer_to(*
this);
775 __allocated_ptr<__allocator_type> __guard_ptr{ __a, __p };
776 this->~_Sp_counted_ptr_inplace();
780 _M_get_deleter(
const std::type_info&)
noexcept override
785#if __glibcxx_shared_ptr_arrays >= 201707L
786 struct _Sp_overwrite_tag;
789 template<
typename _Alloc>
790 struct _Sp_counted_array_base
792 [[no_unique_address]] _Alloc _M_alloc{};
794 bool _M_overwrite =
false;
796 typename allocator_traits<_Alloc>::pointer
797 _M_alloc_array(
size_t __tail)
799 return allocator_traits<_Alloc>::allocate(_M_alloc, _M_n + __tail);
803 _M_dealloc_array(
typename allocator_traits<_Alloc>::pointer __p,
806 allocator_traits<_Alloc>::deallocate(_M_alloc, __p, _M_n + __tail);
810 template<
typename _Init>
812 _M_init(
typename allocator_traits<_Alloc>::value_type* __p,
815 using _Tp = remove_pointer_t<_Init>;
816 using _Up =
typename allocator_traits<_Alloc>::value_type;
818 if constexpr (is_same_v<_Init, _Sp_overwrite_tag>)
823 else if (__init ==
nullptr)
824 std::__uninitialized_default_n_a(__p, _M_n, _M_alloc);
825 else if constexpr (!is_array_v<_Tp>)
826 std::__uninitialized_fill_n_a(__p, _M_n, *__init, _M_alloc);
829#pragma GCC diagnostic push
830#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
833 using value_type = _Up;
835 using pointer =
const _Up*;
836 using reference =
const _Up&;
837 using iterator_category = forward_iterator_tag;
843 _Iter& operator++() { ++_M_pos;
return *
this; }
844 _Iter operator++(
int) {
auto __i(*
this); ++_M_pos;
return __i; }
846 reference
operator*()
const {
return _M_p[_M_pos % _M_len]; }
847 pointer operator->()
const {
return _M_p + (_M_pos % _M_len); }
850 {
return _M_pos == __i._M_pos; }
852#pragma GCC diagnostic pop
854 _Iter __first{_S_first_elem(__init),
sizeof(_Tp) /
sizeof(_Up)};
855 _Iter __last = __first;
856 __last._M_pos = _M_n;
864 _M_dispose_array(
typename allocator_traits<_Alloc>::value_type* __p)
872 allocator_traits<_Alloc>::destroy(_M_alloc, __p + __n);
877 template<
typename _Tp>
879 _S_first_elem(_Tp* __p) {
return __p; }
881 template<
typename _Tp,
size_t _Nm>
883 _S_first_elem(_Tp (*__p)[_Nm]) {
return _S_first_elem(*__p); }
888 template<
typename _Alloc, _Lock_policy _Lp>
889 class _Sp_counted_array final
890 :
public _Sp_counted_base<_Lp>, _Sp_counted_array_base<_Alloc>
892 using pointer =
typename allocator_traits<_Alloc>::pointer;
894 pointer _M_alloc_ptr;
898 friend class __shared_count<_Lp>;
901 _Sp_counted_array(
const _Sp_counted_array_base<_Alloc>& __a,
902 pointer __p) noexcept
903 : _Sp_counted_array_base<_Alloc>(__a), _M_alloc_ptr(__p)
906 ~_Sp_counted_array() =
default;
909 _M_dispose() noexcept
912 this->_M_dispose_array(_M_ptr());
917 _M_destroy() noexcept
919 _Sp_counted_array_base<_Alloc> __a = *
this;
920 pointer __p = _M_alloc_ptr;
921 this->~_Sp_counted_array();
922 __a._M_dealloc_array(__p, _S_tail());
927 static constexpr size_t
931 using _Tp =
typename allocator_traits<_Alloc>::value_type;
934 size_t __bytes =
sizeof(_Sp_counted_array);
937 if constexpr (
alignof(_Tp) <
alignof(_Sp_counted_array))
938 __bytes +=
alignof(_Sp_counted_array) -
alignof(_Tp);
940 return (__bytes +
sizeof(_Tp) - 1) /
sizeof(_Tp);
944 _M_get_deleter(
const std::type_info&)
noexcept override
952 template<
typename _Yp>
956 template<_Lock_policy _Lp>
960 template<
typename _Tp>
963 template<
typename _Tp>
966#if __glibcxx_shared_ptr_arrays >= 201707L
967 template<
typename _Alloc>
975 template<
typename _Ptr>
990 template<
typename _Ptr>
995 template<
typename _Ptr>
1000 template<
typename _Ptr,
typename _Deleter,
1001 typename =
typename __not_alloc_shared_tag<_Deleter>::type>
1006 template<
typename _Ptr,
typename _Deleter,
typename _Alloc,
1007 typename =
typename __not_alloc_shared_tag<_Deleter>::type>
1013 typename _Sp_cd_type::__allocator_type __a2(__a);
1014 auto __guard = std::__allocate_guarded(__a2);
1015 _Sp_cd_type* __mem = __guard.get();
1027 template<
typename _Tp,
typename _Alloc,
typename... _Args>
1031 using _Tp2 = __remove_cv_t<_Tp>;
1033 typename _Sp_cp_type::__allocator_type __a2(__a.
_M_a);
1034 auto __guard = std::__allocate_guarded(__a2);
1035 _Sp_cp_type* __mem = __guard.get();
1036 auto __pi = ::new (__mem)
1040 __p = __pi->_M_ptr();
1043#if __glibcxx_shared_ptr_arrays >= 201707L
1044 template<
typename _Tp,
typename _Alloc,
typename _Init>
1045 __shared_count(_Tp*& __p,
const _Sp_counted_array_base<_Alloc>& __a,
1049 static_assert(is_same_v<_Up, typename _Alloc::value_type>);
1051 using _Sp_ca_type = _Sp_counted_array<_Alloc, _Lp>;
1052 const size_t __tail = _Sp_ca_type::_S_tail();
1054 struct _Guarded_ptr : _Sp_counted_array_base<_Alloc>
1058 _Guarded_ptr(_Sp_counted_array_base<_Alloc> __a)
1059 : _Sp_counted_array_base<_Alloc>(__a),
1060 _M_ptr(this->_M_alloc_array(_Sp_ca_type::_S_tail()))
1066 this->_M_dealloc_array(_M_ptr, _Sp_ca_type::_S_tail());
1072 __guard._M_init(__raw, __init);
1074 void* __c = __raw + __a._M_n;
1075 if constexpr (
alignof(_Up) <
alignof(_Sp_ca_type))
1077 size_t __space =
sizeof(_Up) * __tail;
1078 __c =
std::align(
alignof(_Sp_ca_type),
sizeof(_Sp_ca_type),
1081 auto __pi = ::new(__c) _Sp_ca_type(__guard,
__guard._M_ptr);
1084 __p =
reinterpret_cast<_Tp*
>(__raw);
1088#if _GLIBCXX_USE_DEPRECATED
1089#pragma GCC diagnostic push
1090#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1092 template<
typename _Tp>
1094 __shared_count(std::auto_ptr<_Tp>&& __r);
1095#pragma GCC diagnostic pop
1099 template<
typename _Tp,
typename _Del>
1105 if (__r.get() ==
nullptr)
1117 _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
1121 _Alloc_traits::construct(__a, __mem, __r.release(),
1135 if (
_M_pi !=
nullptr)
1136 _M_pi->_M_release();
1142 if (
_M_pi !=
nullptr)
1143 _M_pi->_M_add_ref_copy();
1152 if (__tmp !=
nullptr)
1154 if (
_M_pi !=
nullptr)
1155 _M_pi->_M_release();
1171 {
return _M_pi ?
_M_pi->_M_get_use_count() : 0; }
1179 {
return _M_pi ?
_M_pi->_M_get_deleter(__ti) :
nullptr; }
1189#ifdef __glibcxx_smart_ptr_owner_equality
1191 _M_owner_hash() const noexcept
1198 {
return __a._M_pi == __b._M_pi; }
1202#ifdef __glibcxx_atomic_shared_ptr
1203 template<
typename>
friend class _Sp_atomic;
1205#ifdef __glibcxx_out_ptr
1206 template<
typename,
typename,
typename...>
friend class out_ptr_t;
1213 template<_Lock_policy _Lp>
1223 if (
_M_pi !=
nullptr)
1224 _M_pi->_M_weak_add_ref();
1230 if (
_M_pi !=
nullptr)
1231 _M_pi->_M_weak_add_ref();
1236 { __r._M_pi =
nullptr; }
1240 if (
_M_pi !=
nullptr)
1241 _M_pi->_M_weak_release();
1248 if (__tmp !=
nullptr)
1250 if (
_M_pi !=
nullptr)
1251 _M_pi->_M_weak_release();
1260 if (__tmp !=
nullptr)
1262 if (
_M_pi !=
nullptr)
1263 _M_pi->_M_weak_release();
1271 if (
_M_pi !=
nullptr)
1272 _M_pi->_M_weak_release();
1274 __r._M_pi =
nullptr;
1288 {
return _M_pi !=
nullptr ?
_M_pi->_M_get_use_count() : 0; }
1298#ifdef __glibcxx_smart_ptr_owner_equality
1300 _M_owner_hash() const noexcept
1307 {
return __a._M_pi == __b._M_pi; }
1311#ifdef __glibcxx_atomic_shared_ptr
1312 template<
typename>
friend class _Sp_atomic;
1319 template<_Lock_policy _Lp>
1324 if (
_M_pi ==
nullptr || !
_M_pi->_M_add_ref_lock_nothrow())
1329 template<_Lock_policy _Lp>
1335 if (
_M_pi && !
_M_pi->_M_add_ref_lock_nothrow())
1343 template<
typename _Yp_ptr,
typename _Tp_ptr>
1348 template<
typename _Yp,
typename _Tp>
1350 : is_convertible<_Yp*, _Tp*>::type
1353 template<
typename _Up,
size_t _Nm>
1358 template<
typename _Up,
size_t _Nm>
1363 template<
typename _Up,
size_t _Nm>
1368 template<
typename _Up,
size_t _Nm>
1374 template<
typename _Up,
size_t _Nm,
typename _Yp,
typename =
void>
1379 template<
typename _Up,
size_t _Nm,
typename _Yp>
1385 template<
typename _Up,
typename _Yp,
typename =
void>
1390 template<
typename _Up,
typename _Yp>
1396 template<
typename _Tp,
typename _Yp>
1400 template<
typename _Up,
size_t _Nm,
typename _Yp>
1406 template<
typename _Up,
typename _Yp>
1412 template<
typename _Tp,
typename _Yp>
1418 template<
typename _Tp>
1419 [[__gnu__::__always_inline__]]
1428 template<
typename _Tp, _Lock_policy _Lp,
1429 bool = is_array<_Tp>::value,
bool = is_void<_Tp>::value>
1453 template<
typename _Tp, _Lock_policy _Lp>
1469 template<
typename _Tp, _Lock_policy _Lp>
1475#if __cplusplus <= 201402L
1476 [[__deprecated__(
"shared_ptr<T[]>::operator* is absent from C++17")]]
1481 [[__deprecated__(
"shared_ptr<T[]>::operator-> is absent from C++17")]]
1490#pragma GCC diagnostic push
1491#pragma GCC diagnostic ignored "-Wc++17-extensions"
1499#pragma GCC diagnostic pop
1507 template<
typename _Tp, _Lock_policy _Lp>
1516 template<
typename _Yp>
1521 template<
typename _Yp,
typename _Res =
void>
1526 template<
typename _Yp>
1530 template<
typename _Yp,
typename _Del,
typename _Res = void,
1539 template<
typename _Yp,
typename _Del>
1544#if __cplusplus > 201402L
1552 template<
typename _Yp,
typename = _SafeConv<_Yp>>
1558 static_assert(
sizeof(_Yp) > 0,
"incomplete type" );
1562 template<
typename _Yp,
typename _Deleter,
typename = _SafeConv<_Yp>>
1566 static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1567 "deleter expression d(p) is well-formed");
1571 template<
typename _Yp,
typename _Deleter,
typename _Alloc,
1576 static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1577 "deleter expression d(p) is well-formed");
1581 template<
typename _Deleter>
1586 template<
typename _Deleter,
typename _Alloc>
1592 template<
typename _Yp>
1599 template<
typename _Yp>
1605 __r._M_ptr =
nullptr;
1612 template<
typename _Yp,
typename = _Compatible<_Yp>>
1621 __r._M_ptr =
nullptr;
1624 template<
typename _Yp,
typename = _Compatible<_Yp>>
1629 __r._M_ptr =
nullptr;
1632 template<
typename _Yp,
typename = _Compatible<_Yp>>
1642 template<
typename _Yp,
typename _Del,
1647 auto __raw = std::__to_address(__r.get());
1652#if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
1655 template<
typename _Tp1,
typename _Del,
1659 >::value,
bool>
::type =
true>
1663 auto __raw = std::__to_address(__r.get());
1670#if _GLIBCXX_USE_DEPRECATED
1671#pragma GCC diagnostic push
1672#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1674 template<
typename _Yp,
typename = _Compatible<_Yp>>
1676#pragma GCC diagnostic pop
1681 template<
typename _Yp>
1690#if _GLIBCXX_USE_DEPRECATED
1691#pragma GCC diagnostic push
1692#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1693 template<
typename _Yp>
1700#pragma GCC diagnostic pop
1718 template<
typename _Yp,
typename _Del>
1730 template<
typename _Yp>
1739 template<
typename _Yp,
typename _Deleter>
1741 reset(_Yp* __p, _Deleter __d)
1744 template<
typename _Yp,
typename _Deleter,
typename _Alloc>
1746 reset(_Yp* __p, _Deleter __d, _Alloc __a)
1751 get() const noexcept
1755 explicit operator bool() const noexcept
1756 {
return _M_ptr !=
nullptr; }
1783 template<
typename _Tp1>
1786 {
return _M_refcount._M_less(__rhs._M_refcount); }
1788 template<
typename _Tp1>
1791 {
return _M_refcount._M_less(__rhs._M_refcount); }
1794#ifdef __glibcxx_smart_ptr_owner_equality
1795 size_t owner_hash() const noexcept {
return _M_refcount._M_owner_hash(); }
1797 template<
typename _Tp1>
1802 template<
typename _Tp1>
1810 template<
typename _Alloc,
typename... _Args>
1815 template<
typename _Tp1,
_Lock_policy _Lp1,
typename _Alloc,
1820#if __glibcxx_shared_ptr_arrays >= 201707L
1822 template<
typename _Alloc,
typename _Init = const remove_extent_t<_Tp>*>
1823 __shared_ptr(
const _Sp_counted_array_base<_Alloc>& __a,
1824 _Init __init =
nullptr)
1841 template<
typename _Yp>
1842 using __esft_base_t =
decltype(__enable_shared_from_this_base(
1847 template<
typename _Yp,
typename =
void>
1851 template<
typename _Yp>
1853 :
__not_<is_array<_Tp>> { };
1855 template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1859 if (
auto __base = __enable_shared_from_this_base(
_M_refcount, __p))
1860 __base->_M_weak_assign(
const_cast<_Yp2*
>(__p),
_M_refcount);
1863 template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1873 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __weak_ptr;
1875 template<
typename _Del,
typename _Tp1, _Lock_policy _Lp1>
1878 template<
typename _Del,
typename _Tp1>
1881#ifdef __glibcxx_atomic_shared_ptr
1882 friend _Sp_atomic<shared_ptr<_Tp>>;
1884#ifdef __glibcxx_out_ptr
1885 template<
typename,
typename,
typename...>
friend class out_ptr_t;
1894 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
1898 {
return __a.get() == __b.get(); }
1900 template<
typename _Tp, _Lock_policy _Lp>
1905#ifdef __cpp_lib_three_way_comparison
1906 template<
typename _Tp,
typename _Up, _Lock_policy _Lp>
1912 template<
typename _Tp, _Lock_policy _Lp>
1920 template<
typename _Tp, _Lock_policy _Lp>
1922 operator==(
nullptr_t,
const __shared_ptr<_Tp, _Lp>& __a)
noexcept
1925 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
1929 {
return __a.get() != __b.get(); }
1931 template<
typename _Tp, _Lock_policy _Lp>
1934 {
return (
bool)__a; }
1936 template<
typename _Tp, _Lock_policy _Lp>
1939 {
return (
bool)__a; }
1941 template<
typename _Tp,
typename _Up, _Lock_policy _Lp>
1949 return less<_Vp>()(__a.get(), __b.get());
1952 template<
typename _Tp, _Lock_policy _Lp>
1960 template<
typename _Tp, _Lock_policy _Lp>
1968 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
1972 {
return !(__b < __a); }
1974 template<
typename _Tp, _Lock_policy _Lp>
1977 {
return !(
nullptr < __a); }
1979 template<
typename _Tp, _Lock_policy _Lp>
1982 {
return !(__a <
nullptr); }
1984 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
1988 {
return (__b < __a); }
1990 template<
typename _Tp, _Lock_policy _Lp>
1993 {
return nullptr < __a; }
1995 template<
typename _Tp, _Lock_policy _Lp>
1998 {
return __a <
nullptr; }
2000 template<
typename _Tp1,
typename _Tp2, _Lock_policy _Lp>
2004 {
return !(__a < __b); }
2006 template<
typename _Tp, _Lock_policy _Lp>
2009 {
return !(__a <
nullptr); }
2011 template<
typename _Tp, _Lock_policy _Lp>
2014 {
return !(
nullptr < __a); }
2018 template<
typename _Tp, _Lock_policy _Lp>
2030 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
2031 inline __shared_ptr<_Tp, _Lp>
2035 return _Sp(__r,
static_cast<typename _Sp::element_type*
>(__r.get()));
2043 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
2044 inline __shared_ptr<_Tp, _Lp>
2048 return _Sp(__r,
const_cast<typename _Sp::element_type*
>(__r.get()));
2056 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
2057 inline __shared_ptr<_Tp, _Lp>
2061 if (
auto* __p =
dynamic_cast<typename _Sp::element_type*
>(__r.get()))
2062 return _Sp(__r, __p);
2066#if __cplusplus > 201402L
2067 template<
typename _Tp,
typename _Tp1, _Lock_policy _Lp>
2068 inline __shared_ptr<_Tp, _Lp>
2072 return _Sp(__r,
reinterpret_cast<typename _Sp::element_type*
>(__r.get()));
2076 template<
typename _Tp, _Lock_policy _Lp>
2083 template<
typename _Yp,
typename _Res =
void>
2088 template<
typename _Yp>
2091#pragma GCC diagnostic push
2092#pragma GCC diagnostic ignored "-Wc++17-extensions"
2094 template<
typename _Yp>
2111 else if constexpr (__and_<is_scalar<_At>,
is_scalar<_Bt>>::value)
2113#if _GLIBCXX_USE_BUILTIN_TRAIT(__builtin_is_virtual_base_of)
2117 else if constexpr (!__builtin_is_virtual_base_of(_Tp, _Yp))
2124 return __r.
lock().get();
2126#pragma GCC diagnostic pop
2151 template<
typename _Yp,
typename = _Compatible<_Yp>>
2156 template<
typename _Yp,
typename = _Compatible<_Yp>>
2163 { __r._M_ptr =
nullptr; }
2165 template<
typename _Yp,
typename = _Compatible<_Yp>>
2168 { __r._M_ptr =
nullptr; }
2173 template<
typename _Yp>
2182 template<
typename _Yp>
2198 template<
typename _Yp>
2204 __r._M_ptr =
nullptr;
2220 template<
typename _Tp1>
2223 {
return _M_refcount._M_less(__rhs._M_refcount); }
2225 template<
typename _Tp1>
2228 {
return _M_refcount._M_less(__rhs._M_refcount); }
2230#ifdef __glibcxx_smart_ptr_owner_equality
2231 size_t owner_hash() const noexcept {
return _M_refcount._M_owner_hash(); }
2233 template<
typename _Tp1>
2235 owner_equal(
const __shared_ptr<_Tp1, _Lp> & __rhs)
const noexcept
2236 {
return _M_refcount == __rhs._M_refcount; }
2238 template<
typename _Tp1>
2241 {
return _M_refcount == __rhs._M_refcount; }
2268 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __weak_ptr;
2271#ifdef __glibcxx_atomic_shared_ptr
2272 friend _Sp_atomic<weak_ptr<_Tp>>;
2280 template<
typename _Tp, _Lock_policy _Lp>
2285#pragma GCC diagnostic push
2286#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2287 template<
typename _Tp,
typename _Tp1>
2292 {
return __lhs.owner_before(__rhs); }
2296 {
return __lhs.owner_before(__rhs); }
2300 {
return __lhs.owner_before(__rhs); }
2302#pragma GCC diagnostic pop
2307 template<
typename _Tp,
typename _Up>
2310 ->
decltype(__lhs.owner_before(__rhs))
2311 {
return __lhs.owner_before(__rhs); }
2316 template<
typename _Tp, _Lock_policy _Lp>
2318 :
public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
2321 template<
typename _Tp, _Lock_policy _Lp>
2323 :
public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
2327 template<
typename _Tp, _Lock_policy _Lp>
2350#if __cplusplus > 201402L || !defined(__STRICT_ANSI__)
2361 template<
typename _Tp1>
2371 template<
typename, _Lock_policy>
2378 typename _Alloc,
typename... _Args>
2399 template<
typename _Tp, _Lock_policy _Lp>
2401 :
public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
#define __throw_exception_again
decltype(nullptr) nullptr_t
__PTRDIFF_TYPE__ ptrdiff_t
#define _GLIBCXX_VISIBILITY(V)
#define __glibcxx_assert(cond)
#define _GLIBCXX_END_NAMESPACE_VERSION
#define _GLIBCXX_BEGIN_NAMESPACE_VERSION
#define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A)
#define _GLIBCXX_THROW_OR_ABORT(_EXC)
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A)
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
Default-initializes objects in the range [first,first+count).
void * align(size_t __align, size_t __size, void *&__ptr, size_t &__space) noexcept
Fit aligned storage in buffer.
constexpr _Tp * to_address(_Tp *__ptr) noexcept
Obtain address referenced by a pointer to an object.
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
typename __conditional< _Cond >::template type< _If, _Else > __conditional_t
static constexpr size_t value
typename remove_all_extents< _Tp >::type remove_all_extents_t
Alias template for remove_all_extents.
__bool_constant< false > false_type
The type used as a compile-time boolean with false value.
__remove_extent(_Tp) type
__remove_reference(_Tp) type
typename __make_unsigned_selector< _Tp >::__type type
typename enable_if< _Cond, _Tp >::type __enable_if_t
auto declval() noexcept -> decltype(__declval< _Tp >(0))
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
constexpr bool operator>(const reverse_iterator< _IteratorL > &__x, const reverse_iterator< _IteratorR > &__y)
constexpr bool operator<(const reverse_iterator< _IteratorL > &__x, const reverse_iterator< _IteratorR > &__y)
constexpr bool operator<=(const reverse_iterator< _IteratorL > &__x, const reverse_iterator< _IteratorR > &__y)
constexpr bool operator>=(const reverse_iterator< _IteratorL > &__x, const reverse_iterator< _IteratorR > &__y)
constexpr __detail::__synth3way_t< _Tp > operator<=>(const array< _Tp, _Nm > &__a, const array< _Tp, _Nm > &__b)
decltype(nullptr) nullptr_t
__shared_ptr< _Tp, _Lp > reinterpret_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
_Tp * __shared_ptr_deref(_Tp *__p)
__shared_ptr< _Tp, _Lp > __make_shared(_Args &&... __args)
__shared_ptr< _Tp, _Lp > __allocate_shared(const _Alloc &__a, _Args &&... __args)
__PTRDIFF_TYPE__ ptrdiff_t
__shared_ptr< _Tp, _Lp > dynamic_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
dynamic_pointer_cast
constexpr _Tp & get(array< _Tp, _Nm > &__arr) noexcept
const _Lock_policy __default_lock_policy
bool operator!=(const fpos< _StateT > &__lhs, const fpos< _StateT > &__rhs)
constexpr bool operator==(const array< _Tp, _Nm > &__one, const array< _Tp, _Nm > &__two)
::_Deque_iterator< _OTp, _OTp &, _OTp * > __uninitialized_copy_a(::_Deque_iterator< _ITp, _IRef, _IPtr > __first, ::_Deque_iterator< _ITp, _IRef, _IPtr > __last, ::_Deque_iterator< _OTp, _OTp &, _OTp * > __result, allocator< _Tp > &)
constexpr _ForwardIterator destroy_n(_ForwardIterator __first, _Size __count)
constexpr __enable_if_t< __array_traits< _Tp, _Nm >::_Is_swappable::value > swap(array< _Tp, _Nm > &__one, array< _Tp, _Nm > &__two) noexcept(noexcept(__one.swap(__two)))
__shared_ptr< _Tp, _Lp > static_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
static_pointer_cast
__shared_ptr< _Tp, _Lp > const_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
const_pointer_cast
void __throw_bad_weak_ptr()
ISO C++ entities toplevel namespace is std.
const _Lock_policy __default_lock_policy
_Atomic_word __exchange_and_add_dispatch(_Atomic_word *__mem, int __val)
_Atomic_word __exchange_and_add_single(_Atomic_word *__mem, int __val)
void __atomic_add_single(_Atomic_word *__mem, int __val)
__extension__ typedef int __guard
Primary class template hash.
Primary class template for reference_wrapper.
Define a member typedef type only if a boolean constant is true.
A simple smart pointer providing strict ownership semantics.
__detected_or_t< value_type *, __pointer, _Alloc > pointer
The allocator's pointer type.
static constexpr void construct(_Alloc &__a, _Tp *__p, _Args &&... __args) noexcept(_S_nothrow_construct< _Tp, _Args... >())
Construct an object of type _Tp.
static constexpr void destroy(_Alloc &__a, _Tp *__p) noexcept(_S_nothrow_destroy< _Tp >())
Destroy an object of type _Tp.
Uniform interface to all allocator types.
The standard allocator, as per C++03 [20.4.1].
Base class for all library exceptions.
A smart pointer with reference-counted copy semantics.
A non-owning observer for a pointer owned by a shared_ptr.
Primary template owner_less.
Base class allowing use of the member function shared_from_this.
virtual char const * what() const noexcept
Exception possibly thrown by shared_ptr.
void _M_weak_release() noexcept
_Atomic_word _M_weak_count
make_unsigned< _Atomic_word >::type _Unsigned_count_type
void _M_release() noexcept
void _M_release_last_use_cold() noexcept
bool _M_add_ref_lock_nothrow() noexcept
virtual ~_Sp_counted_base() noexcept
virtual void _M_destroy() noexcept
long _M_get_use_count() const noexcept
_Sp_counted_base() noexcept
long _M_get_use_count() const noexcept
virtual void _M_dispose() noexcept=0
_Atomic_word _M_use_count
_Sp_counted_base & operator=(_Sp_counted_base const &)=delete
_Sp_counted_base(_Sp_counted_base const &)=delete
virtual void * _M_get_deleter(const std::type_info &) noexcept=0
void _M_weak_release() noexcept
void _M_weak_add_ref() noexcept
void _M_release_last_use() noexcept
static void _S_chk(_Atomic_word __count)
_UniqCompatible< _Yp, _Del, __shared_ptr & > _UniqAssignable
__enable_if_t< __and_< __sp_compatible_with< _Yp *, _Tp * >, is_convertible< _Ptr, element_type * >, is_move_constructible< _Del > >::value, _Res > _UniqCompatible
__shared_count< _Lp > _M_refcount
__shared_ptr(std::auto_ptr< _Tp1 > &&__r)
element_type * get() const noexcept
bool unique() const noexcept
Return true if use_count() == 1.
long use_count() const noexcept
If *this owns a pointer, return the number of owners, otherwise zero.
enable_if< __has_esft_base< _Yp2 >::value >::type _M_enable_shared_from_this_with(_Yp *__p) noexcept
decltype(__enable_shared_from_this_base( std::declval< const __shared_count< _Lp > & >(), std::declval< _Yp * >())) __esft_base_t
void swap(__shared_ptr< _Tp, _Lp > &__other) noexcept
Exchange both the owned pointer and the stored pointer.
typename remove_extent< _Tp >::type element_type
void * _M_get_deleter(const std::type_info &__ti) const noexcept
friend class __shared_ptr
friend _Del * get_deleter(const __shared_ptr< _Tp1, _Lp1 > &) noexcept
__weak_ptr< _Tp, _Lp > weak_type
typename enable_if< __sp_is_constructible< _Tp, _Yp >::value >::type _SafeConv
typename enable_if< __sp_compatible_with< _Yp *, _Tp * >::value, _Res >::type _Compatible
friend __shared_ptr< _Tp1, _Lp1 > __allocate_shared(const _Alloc &__a, _Args &&... __args)
__shared_ptr & operator=(const __shared_ptr &) noexcept=default
_Compatible< _Yp, __shared_ptr & > _Assignable
bool owner_before(__shared_ptr< _Tp1, _Lp > const &__rhs) const noexcept
Define an ordering based on ownership.
void _M_assign(_Tp *__ptr, const __shared_count< _Lp > &__refcount) noexcept
bool expired() const noexcept
__weak_ptr(const __shared_ptr< _Yp, _Lp > &__r) noexcept
__weak_ptr & operator=(__weak_ptr &&__r) noexcept
long use_count() const noexcept
_Assignable< _Yp > operator=(const __shared_ptr< _Yp, _Lp > &__r) noexcept
__weak_ptr & operator=(const __weak_ptr &__r) noexcept=default
__weak_count< _Lp > _M_refcount
bool owner_before(const __weak_ptr< _Tp1, _Lp > &__rhs) const noexcept
typename remove_extent< _Tp >::type element_type
bool owner_before(const __shared_ptr< _Tp1, _Lp > &__rhs) const noexcept
typename enable_if< __sp_compatible_with< _Yp *, _Tp * >::value, _Res >::type _Compatible
_Compatible< _Yp, __weak_ptr & > _Assignable
static element_type * _S_safe_upcast(const __weak_ptr< _Yp, _Lp > &__r)
__weak_ptr(const __weak_ptr &) noexcept=default
constexpr __weak_ptr() noexcept
__weak_ptr(const __weak_ptr< _Yp, _Lp > &__r) noexcept
_Assignable< _Yp > operator=(const __weak_ptr< _Yp, _Lp > &__r) noexcept
friend class __shared_ptr
__shared_ptr< _Tp, _Lp > lock() const noexcept
__weak_ptr(__weak_ptr &&__r) noexcept
__weak_ptr(__weak_ptr< _Yp, _Lp > &&__r) noexcept
_Assignable< _Yp > operator=(__weak_ptr< _Yp, _Lp > &&__r) noexcept
void swap(__weak_ptr &__s) noexcept
constexpr __enable_shared_from_this() noexcept
friend const __enable_shared_from_this * __enable_shared_from_this_base(const __shared_count< _Lp > &, const __enable_shared_from_this *__p)
__enable_shared_from_this & operator=(const __enable_shared_from_this &) noexcept
__weak_ptr< const _Tp, _Lp > weak_from_this() const noexcept
void _M_weak_assign(_Tp1 *__p, const __shared_count< _Lp > &__n) const noexcept
__enable_shared_from_this(const __enable_shared_from_this &) noexcept
__weak_ptr< _Tp, _Lp > weak_from_this() noexcept
friend class __shared_ptr
__shared_ptr< _Tp, _Lp > shared_from_this()
~__enable_shared_from_this()
__weak_ptr< _Tp, _Lp > _M_weak_this
__shared_ptr< const _Tp, _Lp > shared_from_this() const
__weak_count(const __shared_count< _Lp > &__r) noexcept
friend bool operator==(const __weak_count &__a, const __weak_count &__b) noexcept
bool _M_less(const __shared_count< _Lp > &__rhs) const noexcept
_Sp_counted_base< _Lp > * _M_pi
bool _M_less(const __weak_count &__rhs) const noexcept
long _M_get_use_count() const noexcept
__weak_count(__weak_count &&__r) noexcept
__weak_count(const __weak_count &__r) noexcept
void _M_swap(__weak_count &__r) noexcept
constexpr __weak_count() noexcept
__weak_count & operator=(__weak_count &&__r) noexcept
__weak_count & operator=(const __shared_count< _Lp > &__r) noexcept
__weak_count & operator=(const __weak_count &__r) noexcept
__shared_count(_Ptr __p, _Deleter __d)
__shared_count(const __shared_count &__r) noexcept
bool _M_unique() const noexcept
void * _M_get_deleter(const std::type_info &__ti) const noexcept
friend bool operator==(const __shared_count &__a, const __shared_count &__b) noexcept
__shared_count(_Ptr __p, false_type)
_Sp_counted_base< _Lp > * _M_pi
__shared_count & operator=(const __shared_count &__r) noexcept
void _M_swap(__shared_count &__r) noexcept
__shared_count(std::unique_ptr< _Tp, _Del > &&__r)
__shared_count(_Ptr __p, _Deleter __d, _Alloc __a)
long _M_get_use_count() const noexcept
constexpr __shared_count() noexcept
bool _M_less(const __weak_count< _Lp > &__rhs) const noexcept
__shared_count(_Ptr __p, true_type)
__shared_count(_Tp *&__p, _Sp_alloc_shared_tag< _Alloc > __a, _Args &&... __args)
~__shared_count() noexcept
bool _M_less(const __shared_count &__rhs) const noexcept
_Sp_counted_ptr(_Ptr __p) noexcept
virtual void * _M_get_deleter(const std::type_info &) noexcept
virtual void _M_destroy() noexcept
virtual void _M_dispose() noexcept
_Sp_counted_ptr(const _Sp_counted_ptr &)=delete
_Sp_counted_ptr & operator=(const _Sp_counted_ptr &)=delete
static _Tp & _S_get(_Sp_ebo_helper &__eboh)
_Sp_ebo_helper(_Tp &&__tp)
_Sp_ebo_helper(const _Tp &__tp)
_Sp_ebo_helper(const _Tp &__tp)
static _Tp & _S_get(_Sp_ebo_helper &__eboh)
_Sp_ebo_helper(_Tp &&__tp)
__alloc_rebind< _Alloc, _Sp_counted_deleter > __allocator_type
_Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc &__a) noexcept
_Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
virtual void _M_dispose() noexcept
~_Sp_counted_deleter() noexcept
virtual void * _M_get_deleter(const type_info &__ti) noexcept
virtual void _M_destroy() noexcept
_Sp_ebo_helper< 1, _Alloc > _Alloc_base
_Deleter & _M_del() noexcept
_Sp_ebo_helper< 0, _Deleter > _Del_base
_Impl(_Ptr __p, _Deleter __d, const _Alloc &__a) noexcept
_Alloc & _M_alloc() noexcept
static bool _S_eq(const type_info &) noexcept
friend class _Sp_counted_ptr_inplace
static const type_info & _S_ti() noexcept
__alloc_rebind< _Alloc, _Sp_counted_ptr_inplace > __allocator_type
~_Sp_counted_ptr_inplace() noexcept
__remove_cv_t< _Tp > * _M_ptr() noexcept
virtual void _M_destroy() noexcept
virtual void * _M_get_deleter(const std::type_info &__ti) noexcept override
_Sp_counted_ptr_inplace(_Alloc __a, _Args &&... __args)
virtual void _M_dispose() noexcept
_Impl(_Alloc __a) noexcept
_Alloc & _M_alloc() noexcept
_Sp_ebo_helper< 0, _Alloc > _A_base
__gnu_cxx::__aligned_buffer< __remove_cv_t< _Tp > > _M_storage
void operator()(_Yp *__p) const
element_type * _M_get() const noexcept
element_type * operator->() const noexcept
element_type & operator*() const noexcept
element_type * operator->() const noexcept
element_type & operator[](ptrdiff_t __i) const noexcept
element_type * _M_get() const noexcept
typename remove_extent< _Tp >::type element_type
bool operator()(const _Tp &__lhs, const _Tp &__rhs) const noexcept
bool operator()(const _Tp1 &__lhs, const _Tp &__rhs) const noexcept
bool operator()(const _Tp &__lhs, const _Tp1 &__rhs) const noexcept
auto operator()(const _Tp &__lhs, const _Up &__rhs) const noexcept -> decltype(__lhs.owner_before(__rhs))
size_t operator()(const __shared_ptr< _Tp, _Lp > &__s) const noexcept
One of the comparison functors.
typename __uniq_ptr_impl< _Tp, _Dp >::pointer pointer
A move-only smart pointer that manages unique ownership of a resource.