50 #define _SHARED_PTR_H 1
55 namespace 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>;
149 #endif // smart_ptr_for_overwrite
150 #endif // shared_ptr_arrays
174 template<
typename _Tp>
177 template<
typename... _Args>
178 using _Constructible =
typename enable_if<
182 template<
typename _Arg>
190 using element_type =
typename __shared_ptr<_Tp>::element_type;
192 #ifdef __glibcxx_shared_ptr_weak_type // C++ >= 17 && HOSTED
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>>
445 operator=(shared_ptr<_Yp>&& __r) noexcept
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>
467 friend shared_ptr<_NonArray<_Yp>>
468 allocate_shared(
const _Alloc&, _Args&&...);
470 template<
typename _Yp,
typename... _Args>
471 friend shared_ptr<_NonArray<_Yp>>
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>
483 friend shared_ptr<_UnboundedArray<_Yp>>
484 allocate_shared(
const _Alloc&,
size_t);
486 template<
typename _Yp>
487 friend shared_ptr<_UnboundedArray<_Yp>>
490 template<
typename _Yp,
typename _Alloc>
491 friend shared_ptr<_UnboundedArray<_Yp>>
492 allocate_shared(
const _Alloc&,
size_t,
const remove_extent_t<_Yp>&);
494 template<
typename _Yp>
495 friend shared_ptr<_UnboundedArray<_Yp>>
496 make_shared(
size_t,
const remove_extent_t<_Yp>&);
498 template<
typename _Yp,
typename _Alloc>
499 friend shared_ptr<_BoundedArray<_Yp>>
500 allocate_shared(
const _Alloc&);
502 template<
typename _Yp>
503 friend shared_ptr<_BoundedArray<_Yp>>
506 template<
typename _Yp,
typename _Alloc>
507 friend shared_ptr<_BoundedArray<_Yp>>
508 allocate_shared(
const _Alloc&,
const remove_extent_t<_Yp>&);
510 template<
typename _Yp>
511 friend shared_ptr<_BoundedArray<_Yp>>
512 make_shared(
const remove_extent_t<_Yp>&);
514 #if __glibcxx_smart_ptr_for_overwrite
515 template<
typename _Yp,
typename _Alloc>
516 friend shared_ptr<_NotUnboundedArray<_Yp>>
517 allocate_shared_for_overwrite(
const _Alloc&);
519 template<
typename _Yp>
520 friend shared_ptr<_NotUnboundedArray<_Yp>>
521 make_shared_for_overwrite();
523 template<
typename _Yp,
typename _Alloc>
524 friend shared_ptr<_UnboundedArray<_Yp>>
525 allocate_shared_for_overwrite(
const _Alloc&,
size_t);
527 template<
typename _Yp>
528 friend shared_ptr<_UnboundedArray<_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>
542 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
543 template<
typename _Tp,
typename _Del>
544 shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>;
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>
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) { }
832 template<
typename _Yp,
typename = _Constructible<const weak_ptr<_Yp>&>>
834 : __weak_ptr<_Tp>(__r) { }
838 template<
typename _Yp,
typename = _Constructible<weak_ptr<_Yp>>>
843 operator=(
const weak_ptr& __r) noexcept =
default;
845 template<
typename _Yp>
846 _Assignable<const weak_ptr<_Yp>&>
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>>
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>
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>>
917 template<
typename _Tp>
937 shared_from_this()
const
940 #ifdef __glibcxx_enable_shared_from_this // C++ >= 17 && HOSTED
946 weak_from_this() noexcept
947 {
return this->_M_weak_this; }
950 weak_from_this()
const noexcept
951 {
return this->_M_weak_this; }
956 template<
typename _Tp1>
958 _M_weak_assign(_Tp1* __p,
const __shared_count<>& __n)
const noexcept
959 { _M_weak_this._M_assign(__p, __n); }
963 __enable_shared_from_this_base(
const __shared_count<>&,
967 template<
typename, _Lock_policy>
968 friend class __shared_ptr;
986 template<
typename _Tp,
typename _Alloc,
typename... _Args>
991 std::forward<_Args>(__args)...);
1001 template<
typename _Tp,
typename... _Args>
1008 std::forward<_Args>(__args)...);
1011 #if __glibcxx_shared_ptr_arrays >= 201707L
1013 template<
typename _Tp,
typename _Alloc = allocator<
void>>
1015 __make_shared_arr_tag(
size_t __n,
const _Alloc& __a = _Alloc()) noexcept
1018 using _UpAlloc = __alloc_rebind<_Alloc, _Up>;
1020 if (__builtin_mul_overflow(__s, __n, &__n))
1021 std::__throw_bad_array_new_length();
1022 return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};
1026 template<
typename _Tp,
typename _Alloc>
1027 inline shared_ptr<_UnboundedArray<_Tp>>
1033 template<
typename _Tp>
1035 make_shared(
size_t __n)
1040 template<
typename _Tp,
typename _Alloc>
1041 inline shared_ptr<_UnboundedArray<_Tp>>
1042 allocate_shared(
const _Alloc& __a,
size_t __n,
1043 const remove_extent_t<_Tp>& __u)
1045 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n, __a),
1049 template<
typename _Tp>
1050 inline shared_ptr<_UnboundedArray<_Tp>>
1051 make_shared(
size_t __n,
const remove_extent_t<_Tp>& __u)
1053 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n),
1058 template<
typename _Tp,
typename _Alloc = allocator<
void>>
1060 __make_shared_arrN_tag(
const _Alloc& __a = _Alloc()) noexcept
1062 using _Up = remove_all_extents_t<_Tp>;
1063 using _UpAlloc = __alloc_rebind<_Alloc, _Up>;
1064 size_t __n =
sizeof(_Tp) /
sizeof(_Up);
1065 return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};
1069 template<
typename _Tp,
typename _Alloc>
1070 inline shared_ptr<_BoundedArray<_Tp>>
1076 template<
typename _Tp>
1083 template<
typename _Tp,
typename _Alloc>
1084 inline shared_ptr<_BoundedArray<_Tp>>
1085 allocate_shared(
const _Alloc& __a,
const remove_extent_t<_Tp>& __u)
1087 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(__a),
1091 template<
typename _Tp>
1092 inline shared_ptr<_BoundedArray<_Tp>>
1093 make_shared(
const remove_extent_t<_Tp>& __u)
1095 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(),
1099 #if __glibcxx_smart_ptr_for_overwrite
1100 template<
typename _Tp,
typename _Alloc>
1101 inline shared_ptr<_NotUnboundedArray<_Tp>>
1102 allocate_shared_for_overwrite(
const _Alloc& __a)
1104 if constexpr (is_array_v<_Tp>)
1105 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(__a),
1106 _Sp_overwrite_tag{});
1111 using _Alloc2 = __alloc_rebind<_Alloc, _Sp_overwrite_tag>;
1113 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc2>{__a2});
1117 template<
typename _Tp>
1118 inline shared_ptr<_NotUnboundedArray<_Tp>>
1119 make_shared_for_overwrite()
1121 if constexpr (is_array_v<_Tp>)
1122 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(),
1123 _Sp_overwrite_tag{});
1126 using _Alloc = allocator<_Sp_overwrite_tag>;
1127 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{{}});
1131 template<
typename _Tp,
typename _Alloc>
1132 inline shared_ptr<_UnboundedArray<_Tp>>
1133 allocate_shared_for_overwrite(
const _Alloc& __a,
size_t __n)
1135 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n, __a),
1136 _Sp_overwrite_tag{});
1139 template<
typename _Tp>
1140 inline shared_ptr<_UnboundedArray<_Tp>>
1141 make_shared_for_overwrite(
size_t __n)
1143 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n),
1144 _Sp_overwrite_tag{});
1146 #endif // smart_ptr_for_overwrite
1147 #endif // shared_ptr_arrays
1150 template<
typename _Tp>
1152 :
public __hash_base<size_t, shared_ptr<_Tp>>
1161 #if __cpp_variable_templates
1162 template<
typename _Tp>
1163 constexpr
bool __is_shared_ptr =
false;
1164 template<
typename _Tp>
1165 constexpr
bool __is_shared_ptr<shared_ptr<_Tp>> =
true;
1171 #if __cplusplus >= 201703L
1172 namespace __detail::__variant
1174 template<
typename>
struct _Never_valueless_alt;
1178 template<
typename _Tp>
1185 template<
typename _Tp>
1186 struct _Never_valueless_alt<
std::weak_ptr<_Tp>>
1192 _GLIBCXX_END_NAMESPACE_VERSION
1195 #endif // _SHARED_PTR_H