50#define _SHARED_PTR_H 1
55namespace std _GLIBCXX_VISIBILITY(default)
57_GLIBCXX_BEGIN_NAMESPACE_VERSION
68 template<
typename _Ch,
typename _Tr,
typename _Tp, _Lock_policy _Lp>
71 const __shared_ptr<_Tp, _Lp>& __p)
77 template<
typename _Del,
typename _Tp, _Lock_policy _Lp>
79 get_deleter(
const __shared_ptr<_Tp, _Lp>& __p)
noexcept
82 return static_cast<_Del*
>(__p._M_get_deleter(
typeid(_Del)));
92 template<
typename _Del,
typename _Tp>
97 return static_cast<_Del*
>(__p._M_get_deleter(
typeid(_Del)));
106#if __cpp_concepts && __glibcxx_type_trait_variable_templates
107 template<
typename _Tp>
108 requires (!is_array_v<_Tp>)
109 using _NonArray = _Tp;
111 template<
typename _Tp>
112 using _NonArray = __enable_if_t<!is_array<_Tp>::value, _Tp>;
115#if __glibcxx_shared_ptr_arrays >= 201707L
118 template<
typename _Tp>
119 requires is_array_v<_Tp> && (extent_v<_Tp> == 0)
120 using _UnboundedArray = _Tp;
122 template<
typename _Tp>
123 using _UnboundedArray
124 = __enable_if_t<__is_array_unknown_bounds<_Tp>::value, _Tp>;
129 template<
typename _Tp>
130 requires (extent_v<_Tp> != 0)
131 using _BoundedArray = _Tp;
133 template<
typename _Tp>
135 = __enable_if_t<__is_array_known_bounds<_Tp>::value, _Tp>;
138#if __glibcxx_smart_ptr_for_overwrite
141 template<
typename _Tp>
142 requires (!is_array_v<_Tp>) || (extent_v<_Tp> != 0)
143 using _NotUnboundedArray = _Tp;
145 template<
typename _Tp>
146 using _NotUnboundedArray
147 = __enable_if_t<!__is_array_unknown_bounds<_Tp>::value, _Tp>;
174 template<
typename _Tp>
177 template<
typename... _Args>
178 using _Constructible =
typename enable_if<
182 template<
typename _Arg>
192#ifdef __glibcxx_shared_ptr_weak_type
195 using weak_type = weak_ptr<_Tp>;
211 template<
typename _Yp,
typename = _Constructible<_Yp*>>
228 template<
typename _Yp,
typename _Deleter,
229 typename = _Constructible<_Yp*, _Deleter>>
231 : __shared_ptr<_Tp>(__p,
std::
move(__d)) { }
246 template<
typename _Deleter>
248 : __shared_ptr<_Tp>(__p,
std::
move(__d)) { }
265 template<
typename _Yp,
typename _Deleter,
typename _Alloc,
266 typename = _Constructible<_Yp*, _Deleter, _Alloc>>
285 template<
typename _Deleter,
typename _Alloc>
309 template<
typename _Yp>
311 : __shared_ptr<_Tp>(__r, __p) { }
313#if __cplusplus > 201703L
337 template<
typename _Yp>
339 : __shared_ptr<_Tp>(
std::move(__r), __p) { }
348 template<
typename _Yp,
349 typename = _Constructible<const shared_ptr<_Yp>&>>
351 : __shared_ptr<_Tp>(__r) { }
366 template<
typename _Yp,
typename = _Constructible<shared_ptr<_Yp>>>
378 template<
typename _Yp,
typename = _Constructible<const weak_ptr<_Yp>&>>
380 : __shared_ptr<_Tp>(__r) { }
382#if _GLIBCXX_USE_DEPRECATED
383#pragma GCC diagnostic push
384#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
385 template<
typename _Yp,
typename = _Constructible<auto_ptr<_Yp>>>
387#pragma GCC diagnostic pop
392 template<
typename _Yp,
typename _Del,
393 typename = _Constructible<unique_ptr<_Yp, _Del>>>
395 : __shared_ptr<_Tp>(
std::
move(__r)) { }
397#if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
401 template<
typename _Yp,
typename _Del,
402 _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
404 : __shared_ptr<_Tp>(
std::
move(__r), __sp_array_delete()) { }
415 template<
typename _Yp>
416 _Assignable<const shared_ptr<_Yp>&>
419 this->__shared_ptr<_Tp>::operator=(__r);
423#if _GLIBCXX_USE_DEPRECATED
424#pragma GCC diagnostic push
425#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
426 template<
typename _Yp>
427 _Assignable<auto_ptr<_Yp>>
428 operator=(auto_ptr<_Yp>&& __r)
430 this->__shared_ptr<_Tp>::operator=(
std::move(__r));
433#pragma GCC diagnostic pop
439 this->__shared_ptr<_Tp>::operator=(
std::move(__r));
444 _Assignable<shared_ptr<_Yp>>
447 this->__shared_ptr<_Tp>::operator=(
std::move(__r));
451 template<
typename _Yp,
typename _Del>
452 _Assignable<unique_ptr<_Yp, _Del>>
453 operator=(unique_ptr<_Yp, _Del>&& __r)
455 this->__shared_ptr<_Tp>::operator=(
std::move(__r));
461 template<
typename _Alloc,
typename... _Args>
462 shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
463 : __shared_ptr<_Tp>(__tag, std::
forward<_Args>(__args)...)
466 template<
typename _Yp,
typename _Alloc,
typename... _Args>
468 allocate_shared(
const _Alloc&, _Args&&...);
470 template<
typename _Yp,
typename... _Args>
472 make_shared(_Args&&...);
474#if __glibcxx_shared_ptr_arrays >= 201707L
476 template<
typename _Alloc,
typename _Init = const remove_extent_t<_Tp>*>
477 shared_ptr(
const _Sp_counted_array_base<_Alloc>& __a,
478 _Init __init =
nullptr)
479 : __shared_ptr<_Tp>(__a, __init)
482 template<
typename _Yp,
typename _Alloc>
484 allocate_shared(
const _Alloc&,
size_t);
486 template<
typename _Yp>
490 template<
typename _Yp,
typename _Alloc>
494 template<
typename _Yp>
498 template<
typename _Yp,
typename _Alloc>
500 allocate_shared(
const _Alloc&);
502 template<
typename _Yp>
506 template<
typename _Yp,
typename _Alloc>
510 template<
typename _Yp>
514#if __glibcxx_smart_ptr_for_overwrite
515 template<
typename _Yp,
typename _Alloc>
517 allocate_shared_for_overwrite(
const _Alloc&);
519 template<
typename _Yp>
521 make_shared_for_overwrite();
523 template<
typename _Yp,
typename _Alloc>
525 allocate_shared_for_overwrite(
const _Alloc&,
size_t);
527 template<
typename _Yp>
529 make_shared_for_overwrite(
size_t);
534 shared_ptr(
const weak_ptr<_Tp>& __r, std::nothrow_t) noexcept
535 : __shared_ptr<_Tp>(__r, std::nothrow) { }
537 friend class weak_ptr<_Tp>;
540#if __cpp_deduction_guides >= 201606
541 template<
typename _Tp>
543 template<
typename _Tp,
typename _Del>
552 template<
typename _Tp,
typename _Up>
553 _GLIBCXX_NODISCARD
inline bool
555 {
return __a.get() == __b.get(); }
558 template<
typename _Tp>
559 _GLIBCXX_NODISCARD
inline bool
563#ifdef __cpp_lib_three_way_comparison
564 template<
typename _Tp,
typename _Up>
565 inline strong_ordering
568 {
return compare_three_way()(__a.get(), __b.get()); }
570 template<
typename _Tp>
571 inline strong_ordering
572 operator<=>(
const shared_ptr<_Tp>& __a, nullptr_t)
noexcept
575 return compare_three_way()(__a.get(),
static_cast<pointer
>(
nullptr));
579 template<
typename _Tp>
580 _GLIBCXX_NODISCARD
inline bool
585 template<
typename _Tp,
typename _Up>
586 _GLIBCXX_NODISCARD
inline bool
588 {
return __a.get() != __b.get(); }
591 template<
typename _Tp>
592 _GLIBCXX_NODISCARD
inline bool
594 {
return (
bool)__a; }
597 template<
typename _Tp>
598 _GLIBCXX_NODISCARD
inline bool
600 {
return (
bool)__a; }
603 template<
typename _Tp,
typename _Up>
604 _GLIBCXX_NODISCARD
inline bool
610 return less<_Vp>()(__a.get(), __b.get());
614 template<
typename _Tp>
615 _GLIBCXX_NODISCARD
inline bool
623 template<
typename _Tp>
624 _GLIBCXX_NODISCARD
inline bool
632 template<
typename _Tp,
typename _Up>
633 _GLIBCXX_NODISCARD
inline bool
635 {
return !(__b < __a); }
638 template<
typename _Tp>
639 _GLIBCXX_NODISCARD
inline bool
641 {
return !(
nullptr < __a); }
644 template<
typename _Tp>
645 _GLIBCXX_NODISCARD
inline bool
647 {
return !(__a <
nullptr); }
650 template<
typename _Tp,
typename _Up>
651 _GLIBCXX_NODISCARD
inline bool
653 {
return (__b < __a); }
656 template<
typename _Tp>
657 _GLIBCXX_NODISCARD
inline bool
659 {
return nullptr < __a; }
662 template<
typename _Tp>
663 _GLIBCXX_NODISCARD
inline bool
665 {
return __a <
nullptr; }
668 template<
typename _Tp,
typename _Up>
669 _GLIBCXX_NODISCARD
inline bool
671 {
return !(__a < __b); }
674 template<
typename _Tp>
675 _GLIBCXX_NODISCARD
inline bool
677 {
return !(__a <
nullptr); }
680 template<
typename _Tp>
681 _GLIBCXX_NODISCARD
inline bool
683 {
return !(
nullptr < __a); }
689 template<
typename _Tp>
697 template<
typename _Tp,
typename _Up>
702 return _Sp(__r,
static_cast<typename _Sp::element_type*
>(__r.get()));
706 template<
typename _Tp,
typename _Up>
711 return _Sp(__r,
const_cast<typename _Sp::element_type*
>(__r.get()));
715 template<
typename _Tp,
typename _Up>
720 if (
auto* __p =
dynamic_cast<typename _Sp::element_type*
>(__r.get()))
721 return _Sp(__r, __p);
725#if __cplusplus >= 201703L
728 template<
typename _Tp,
typename _Up>
733 return _Sp(__r,
reinterpret_cast<typename _Sp::element_type*
>(__r.get()));
736#if __cplusplus > 201703L
742 template<
typename _Tp,
typename _Up>
748 static_cast<typename _Sp::element_type*
>(__r.get()));
753 template<
typename _Tp,
typename _Up>
759 const_cast<typename _Sp::element_type*
>(__r.get()));
764 template<
typename _Tp,
typename _Up>
769 if (
auto* __p =
dynamic_cast<typename _Sp::element_type*
>(__r.get()))
776 template<
typename _Tp,
typename _Up>
782 reinterpret_cast<typename _Sp::element_type*
>(__r.get()));
809 template<
typename _Tp>
810 class weak_ptr :
public __weak_ptr<_Tp>
812 template<
typename _Arg>
813 using _Constructible =
typename enable_if<
817 template<
typename _Arg>
823 constexpr weak_ptr()
noexcept =
default;
825 template<
typename _Yp,
826 typename = _Constructible<const shared_ptr<_Yp>&>>
828 : __weak_ptr<_Tp>(__r) { }
830 weak_ptr(
const weak_ptr&)
noexcept =
default;
832 template<
typename _Yp,
typename = _Constructible<const weak_ptr<_Yp>&>>
833 weak_ptr(
const weak_ptr<_Yp>& __r) noexcept
834 : __weak_ptr<_Tp>(__r) { }
836 weak_ptr(weak_ptr&&)
noexcept =
default;
838 template<
typename _Yp,
typename = _Constructible<weak_ptr<_Yp>>>
839 weak_ptr(weak_ptr<_Yp>&& __r) noexcept
843 operator=(
const weak_ptr& __r)
noexcept =
default;
845 template<
typename _Yp>
846 _Assignable<const weak_ptr<_Yp>&>
847 operator=(
const weak_ptr<_Yp>& __r)
noexcept
849 this->__weak_ptr<_Tp>::operator=(__r);
853 template<
typename _Yp>
854 _Assignable<const shared_ptr<_Yp>&>
857 this->__weak_ptr<_Tp>::operator=(__r);
862 operator=(weak_ptr&& __r)
noexcept =
default;
864 template<
typename _Yp>
865 _Assignable<weak_ptr<_Yp>>
866 operator=(weak_ptr<_Yp>&& __r)
noexcept
868 this->__weak_ptr<_Tp>::operator=(
std::move(__r));
873 lock()
const noexcept
877#if __cpp_deduction_guides >= 201606
878 template<
typename _Tp>
885 template<
typename _Tp>
887 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b)
noexcept
892 template<
typename _Tp =
void>
901 template<
typename _Tp>
903 :
public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
907 template<
typename _Tp>
909 :
public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
912#ifdef __glibcxx_smart_ptr_owner_equality
921 template<
typename _Tp>
924 {
return __s.owner_hash(); }
926 template<
typename _Tp>
928 operator()(
const weak_ptr<_Tp>& __s)
const noexcept
929 {
return __s.owner_hash(); }
931 using is_transparent = void;
942 template<
typename _Tp1,
typename _Tp2>
944 operator()(
const shared_ptr<_Tp1>& __lhs,
945 const shared_ptr<_Tp2>& __rhs)
const noexcept
946 {
return __lhs.owner_equal(__rhs); }
948 template<
typename _Tp1,
typename _Tp2>
950 operator()(
const shared_ptr<_Tp1>& __lhs,
951 const weak_ptr<_Tp2>& __rhs)
const noexcept
952 {
return __lhs.owner_equal(__rhs); }
954 template<
typename _Tp1,
typename _Tp2>
956 operator()(
const weak_ptr<_Tp1>& __lhs,
957 const shared_ptr<_Tp2>& __rhs)
const noexcept
958 {
return __lhs.owner_equal(__rhs); }
960 template<
typename _Tp1,
typename _Tp2>
962 operator()(
const weak_ptr<_Tp1>& __lhs,
963 const weak_ptr<_Tp2>& __rhs)
const noexcept
964 {
return __lhs.owner_equal(__rhs); }
966 using is_transparent = void;
975 template<
typename _Tp>
976 class enable_shared_from_this
979 constexpr enable_shared_from_this()
noexcept { }
981 enable_shared_from_this(
const enable_shared_from_this&)
noexcept { }
983 enable_shared_from_this&
984 operator=(
const enable_shared_from_this&)
noexcept
987 ~enable_shared_from_this() { }
995 shared_from_this()
const
998#ifdef __glibcxx_enable_shared_from_this
1004 weak_from_this()
noexcept
1005 {
return this->_M_weak_this; }
1008 weak_from_this()
const noexcept
1009 {
return this->_M_weak_this; }
1014 template<
typename _Tp1>
1016 _M_weak_assign(_Tp1* __p,
const __shared_count<>& __n)
const noexcept
1017 { _M_weak_this._M_assign(__p, __n); }
1020 friend const enable_shared_from_this*
1021 __enable_shared_from_this_base(
const __shared_count<>&,
1022 const enable_shared_from_this* __p)
1025 template<
typename, _Lock_policy>
1026 friend class __shared_ptr;
1044 template<
typename _Tp,
typename _Alloc,
typename... _Args>
1059 template<
typename _Tp,
typename... _Args>
1069#if __glibcxx_shared_ptr_arrays >= 201707L
1071 template<
typename _Tp,
typename _Alloc = allocator<
void>>
1073 __make_shared_arr_tag(
size_t __n,
const _Alloc& __a = _Alloc()) noexcept
1076 using _UpAlloc = __alloc_rebind<_Alloc, _Up>;
1078 if (__builtin_mul_overflow(__s, __n, &__n))
1079 std::__throw_bad_array_new_length();
1080 return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};
1084 template<
typename _Tp,
typename _Alloc>
1091 template<
typename _Tp>
1098 template<
typename _Tp,
typename _Alloc>
1107 template<
typename _Tp>
1116 template<
typename _Tp,
typename _Alloc = allocator<
void>>
1118 __make_shared_arrN_tag(
const _Alloc& __a = _Alloc()) noexcept
1121 using _UpAlloc = __alloc_rebind<_Alloc, _Up>;
1122 size_t __n =
sizeof(_Tp) /
sizeof(_Up);
1123 return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};
1127 template<
typename _Tp,
typename _Alloc>
1134 template<
typename _Tp>
1141 template<
typename _Tp,
typename _Alloc>
1149 template<
typename _Tp>
1157#if __glibcxx_smart_ptr_for_overwrite
1158 template<
typename _Tp,
typename _Alloc>
1160 allocate_shared_for_overwrite(
const _Alloc& __a)
1162 if constexpr (is_array_v<_Tp>)
1164 _Sp_overwrite_tag{});
1169 using _Alloc2 = __alloc_rebind<_Alloc, _Sp_overwrite_tag>;
1175 template<
typename _Tp>
1177 make_shared_for_overwrite()
1179 if constexpr (is_array_v<_Tp>)
1181 _Sp_overwrite_tag{});
1189 template<
typename _Tp,
typename _Alloc>
1191 allocate_shared_for_overwrite(
const _Alloc& __a,
size_t __n)
1194 _Sp_overwrite_tag{});
1197 template<
typename _Tp>
1199 make_shared_for_overwrite(
size_t __n)
1202 _Sp_overwrite_tag{});
1208 template<
typename _Tp>
1210 :
public __hash_base<size_t, shared_ptr<_Tp>>
1219#if __cpp_variable_templates
1220 template<
typename _Tp>
1221 constexpr bool __is_shared_ptr =
false;
1222 template<
typename _Tp>
1223 constexpr bool __is_shared_ptr<shared_ptr<_Tp>> =
true;
1229#if __cplusplus >= 201703L
1230 namespace __detail::__variant
1232 template<
typename>
struct _Never_valueless_alt;
1236 template<
typename _Tp>
1243 template<
typename _Tp>
1244 struct _Never_valueless_alt<
std::weak_ptr<_Tp>>
1250_GLIBCXX_END_NAMESPACE_VERSION
bool operator==(const shared_ptr< _Tp > &__a, nullptr_t) noexcept
shared_ptr comparison with nullptr
shared_ptr< _NonArray< _Tp > > make_shared(_Args &&... __args)
Create an object that is owned by a shared_ptr.
shared_ptr< _Tp > static_pointer_cast(const shared_ptr< _Up > &__r) noexcept
Convert type of shared_ptr, via static_cast
shared_ptr< _Tp > const_pointer_cast(shared_ptr< _Up > &&__r) noexcept
Convert type of shared_ptr rvalue, via const_cast
_Del * get_deleter(const shared_ptr< _State_base > &__p) noexcept
bool operator==(const shared_ptr< _Tp > &__a, const shared_ptr< _Up > &__b) noexcept
Equality operator for shared_ptr objects, compares the stored pointers.
shared_ptr< _Tp > static_pointer_cast(shared_ptr< _Up > &&__r) noexcept
Convert type of shared_ptr rvalue, via static_cast
shared_ptr< _Tp > reinterpret_pointer_cast(const shared_ptr< _Up > &__r) noexcept
Convert type of shared_ptr, via reinterpret_cast
shared_ptr< _NonArray< _Tp > > allocate_shared(const _Alloc &__a, _Args &&... __args)
Create an object that is owned by a shared_ptr.
void swap(weak_ptr< _Tp > &__a, weak_ptr< _Tp > &__b) noexcept
Swap overload for weak_ptr.
shared_ptr< _Tp > reinterpret_pointer_cast(shared_ptr< _Up > &&__r) noexcept
Convert type of shared_ptr rvalue, via reinterpret_cast
shared_ptr< _Tp > dynamic_pointer_cast(const shared_ptr< _Up > &__r) noexcept
Convert type of shared_ptr, via dynamic_cast
shared_ptr< _Tp > const_pointer_cast(const shared_ptr< _Up > &__r) noexcept
Convert type of shared_ptr, via const_cast
void swap(shared_ptr< _Tp > &__a, shared_ptr< _Tp > &__b) noexcept
Swap overload for shared_ptr.
shared_ptr< _Tp > dynamic_pointer_cast(shared_ptr< _Up > &&__r) noexcept
Convert type of shared_ptr rvalue, via dynamic_cast
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
typename remove_extent< _Tp >::type remove_extent_t
Alias template for remove_extent.
typename remove_all_extents< _Tp >::type remove_all_extents_t
Alias template for remove_all_extents.
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.
ISO C++ entities toplevel namespace is std.
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Template class basic_ostream.
Primary class template hash.
Define a member typedef type only if a boolean constant is true.
The standard allocator, as per C++03 [20.4.1].
A smart pointer with reference-counted copy semantics.
typename __shared_ptr< _State_base >::element_type element_type
shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
Construct a shared_ptr that owns a null pointer and the deleter __d.
shared_ptr(const shared_ptr< _Yp > &__r) noexcept
If __r is empty, constructs an empty shared_ptr; otherwise construct a shared_ptr that shares ownersh...
shared_ptr(shared_ptr< _Yp > &&__r) noexcept
Move-constructs a shared_ptr instance from __r.
shared_ptr(_Yp *__p, _Deleter __d, _Alloc __a)
Construct a shared_ptr that owns the pointer __p and the deleter __d.
constexpr shared_ptr() noexcept
shared_ptr(const shared_ptr &) noexcept=default
Copy constructor.
shared_ptr(shared_ptr &&__r) noexcept
Move-constructs a shared_ptr instance from __r.
shared_ptr(_Yp *__p)
Construct a shared_ptr that owns the pointer __p.
shared_ptr(nullptr_t __p, _Deleter __d)
Construct a shared_ptr that owns a null pointer and the deleter __d.
shared_ptr(_Yp *__p, _Deleter __d)
Construct a shared_ptr that owns the pointer __p and the deleter __d.
shared_ptr(const shared_ptr< _Yp > &__r, element_type *__p) noexcept
Constructs a shared_ptr instance that stores __p and shares ownership with __r.
shared_ptr(const weak_ptr< _Yp > &__r)
Constructs a shared_ptr that shares ownership with __r and stores a copy of the pointer stored in __r...
constexpr shared_ptr(nullptr_t) noexcept
Construct an empty shared_ptr.
shared_ptr(shared_ptr< _Yp > &&__r, element_type *__p) noexcept
Constructs a shared_ptr instance that stores __p and shares ownership with __r.
A non-owning observer for a pointer owned by a shared_ptr.
Primary template owner_less.
A simple smart pointer providing strict ownership semantics.
One of the comparison functors.
A move-only smart pointer that manages unique ownership of a resource.