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
117 template<
typename _Tp>
118 requires is_array_v<_Tp> && (extent_v<_Tp> == 0)
119 using _UnboundedArray = _Tp;
122 template<
typename _Tp>
123 requires (extent_v<_Tp> != 0)
124 using _BoundedArray = _Tp;
126#if __glibcxx_smart_ptr_for_overwrite
128 template<
typename _Tp>
129 requires (!is_array_v<_Tp>) || (extent_v<_Tp> != 0)
130 using _NotUnboundedArray = _Tp;
156 template<
typename _Tp>
159 template<
typename... _Args>
160 using _Constructible =
typename enable_if<
164 template<
typename _Arg>
174#ifdef __glibcxx_shared_ptr_weak_type
177 using weak_type = weak_ptr<_Tp>;
193 template<
typename _Yp,
typename = _Constructible<_Yp*>>
210 template<
typename _Yp,
typename _Deleter,
211 typename = _Constructible<_Yp*, _Deleter>>
213 : __shared_ptr<_Tp>(__p,
std::
move(__d)) { }
228 template<
typename _Deleter>
230 : __shared_ptr<_Tp>(__p,
std::
move(__d)) { }
247 template<
typename _Yp,
typename _Deleter,
typename _Alloc,
248 typename = _Constructible<_Yp*, _Deleter, _Alloc>>
267 template<
typename _Deleter,
typename _Alloc>
291 template<
typename _Yp>
293 : __shared_ptr<_Tp>(__r, __p) { }
295#if __cplusplus > 201703L
319 template<
typename _Yp>
321 : __shared_ptr<_Tp>(
std::move(__r), __p) { }
330 template<
typename _Yp,
331 typename = _Constructible<const shared_ptr<_Yp>&>>
333 : __shared_ptr<_Tp>(__r) { }
348 template<
typename _Yp,
typename = _Constructible<shared_ptr<_Yp>>>
360 template<
typename _Yp,
typename = _Constructible<const weak_ptr<_Yp>&>>
362 : __shared_ptr<_Tp>(__r) { }
364#if _GLIBCXX_USE_DEPRECATED
365#pragma GCC diagnostic push
366#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
367 template<
typename _Yp,
typename = _Constructible<auto_ptr<_Yp>>>
369#pragma GCC diagnostic pop
374 template<
typename _Yp,
typename _Del,
375 typename = _Constructible<unique_ptr<_Yp, _Del>>>
377 : __shared_ptr<_Tp>(
std::
move(__r)) { }
379#if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
383 template<
typename _Yp,
typename _Del,
384 _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
386 : __shared_ptr<_Tp>(
std::
move(__r), __sp_array_delete()) { }
397 template<
typename _Yp>
398 _Assignable<const shared_ptr<_Yp>&>
401 this->__shared_ptr<_Tp>::operator=(__r);
405#if _GLIBCXX_USE_DEPRECATED
406#pragma GCC diagnostic push
407#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
408 template<
typename _Yp>
409 _Assignable<auto_ptr<_Yp>>
410 operator=(auto_ptr<_Yp>&& __r)
412 this->__shared_ptr<_Tp>::operator=(
std::move(__r));
415#pragma GCC diagnostic pop
421 this->__shared_ptr<_Tp>::operator=(
std::move(__r));
426 _Assignable<shared_ptr<_Yp>>
429 this->__shared_ptr<_Tp>::operator=(
std::move(__r));
433 template<
typename _Yp,
typename _Del>
434 _Assignable<unique_ptr<_Yp, _Del>>
435 operator=(unique_ptr<_Yp, _Del>&& __r)
437 this->__shared_ptr<_Tp>::operator=(
std::move(__r));
443 template<
typename _Alloc,
typename... _Args>
444 shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
445 : __shared_ptr<_Tp>(__tag, std::
forward<_Args>(__args)...)
448 template<
typename _Yp,
typename _Alloc,
typename... _Args>
450 allocate_shared(
const _Alloc&, _Args&&...);
452 template<
typename _Yp,
typename... _Args>
454 make_shared(_Args&&...);
456#if __glibcxx_shared_ptr_arrays >= 201707L
458 template<
typename _Alloc,
typename _Init = const remove_extent_t<_Tp>*>
459 shared_ptr(
const _Sp_counted_array_base<_Alloc>& __a,
460 _Init __init =
nullptr)
461 : __shared_ptr<_Tp>(__a, __init)
464 template<
typename _Yp,
typename _Alloc>
466 allocate_shared(
const _Alloc&,
size_t);
468 template<
typename _Yp>
472 template<
typename _Yp,
typename _Alloc>
476 template<
typename _Yp>
480 template<
typename _Yp,
typename _Alloc>
482 allocate_shared(
const _Alloc&);
484 template<
typename _Yp>
488 template<
typename _Yp,
typename _Alloc>
492 template<
typename _Yp>
496#if __glibcxx_smart_ptr_for_overwrite
497 template<
typename _Yp,
typename _Alloc>
499 allocate_shared_for_overwrite(
const _Alloc&);
501 template<
typename _Yp>
503 make_shared_for_overwrite();
505 template<
typename _Yp,
typename _Alloc>
507 allocate_shared_for_overwrite(
const _Alloc&,
size_t);
509 template<
typename _Yp>
511 make_shared_for_overwrite(
size_t);
516 shared_ptr(
const weak_ptr<_Tp>& __r, std::nothrow_t) noexcept
517 : __shared_ptr<_Tp>(__r, std::nothrow) { }
519 friend class weak_ptr<_Tp>;
522#if __cpp_deduction_guides >= 201606
523 template<
typename _Tp>
525 template<
typename _Tp,
typename _Del>
534 template<
typename _Tp,
typename _Up>
535 _GLIBCXX_NODISCARD
inline bool
537 {
return __a.get() == __b.get(); }
540 template<
typename _Tp>
541 _GLIBCXX_NODISCARD
inline bool
545#ifdef __cpp_lib_three_way_comparison
546 template<
typename _Tp,
typename _Up>
547 inline strong_ordering
550 {
return compare_three_way()(__a.get(), __b.get()); }
552 template<
typename _Tp>
553 inline strong_ordering
554 operator<=>(
const shared_ptr<_Tp>& __a, nullptr_t)
noexcept
557 return compare_three_way()(__a.get(),
static_cast<pointer
>(
nullptr));
561 template<
typename _Tp>
562 _GLIBCXX_NODISCARD
inline bool
567 template<
typename _Tp,
typename _Up>
568 _GLIBCXX_NODISCARD
inline bool
570 {
return __a.get() != __b.get(); }
573 template<
typename _Tp>
574 _GLIBCXX_NODISCARD
inline bool
576 {
return (
bool)__a; }
579 template<
typename _Tp>
580 _GLIBCXX_NODISCARD
inline bool
582 {
return (
bool)__a; }
585 template<
typename _Tp,
typename _Up>
586 _GLIBCXX_NODISCARD
inline bool
592 return less<_Vp>()(__a.get(), __b.get());
596 template<
typename _Tp>
597 _GLIBCXX_NODISCARD
inline bool
605 template<
typename _Tp>
606 _GLIBCXX_NODISCARD
inline bool
614 template<
typename _Tp,
typename _Up>
615 _GLIBCXX_NODISCARD
inline bool
617 {
return !(__b < __a); }
620 template<
typename _Tp>
621 _GLIBCXX_NODISCARD
inline bool
623 {
return !(
nullptr < __a); }
626 template<
typename _Tp>
627 _GLIBCXX_NODISCARD
inline bool
629 {
return !(__a <
nullptr); }
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 !(__a < __b); }
656 template<
typename _Tp>
657 _GLIBCXX_NODISCARD
inline bool
659 {
return !(__a <
nullptr); }
662 template<
typename _Tp>
663 _GLIBCXX_NODISCARD
inline bool
665 {
return !(
nullptr < __a); }
671 template<
typename _Tp>
679 template<
typename _Tp,
typename _Up>
684 return _Sp(__r,
static_cast<typename _Sp::element_type*
>(__r.get()));
688 template<
typename _Tp,
typename _Up>
693 return _Sp(__r,
const_cast<typename _Sp::element_type*
>(__r.get()));
697 template<
typename _Tp,
typename _Up>
702 if (
auto* __p =
dynamic_cast<typename _Sp::element_type*
>(__r.get()))
703 return _Sp(__r, __p);
707#if __cplusplus >= 201703L
710 template<
typename _Tp,
typename _Up>
715 return _Sp(__r,
reinterpret_cast<typename _Sp::element_type*
>(__r.get()));
718#if __cplusplus > 201703L
724 template<
typename _Tp,
typename _Up>
730 static_cast<typename _Sp::element_type*
>(__r.get()));
735 template<
typename _Tp,
typename _Up>
741 const_cast<typename _Sp::element_type*
>(__r.get()));
746 template<
typename _Tp,
typename _Up>
751 if (
auto* __p =
dynamic_cast<typename _Sp::element_type*
>(__r.get()))
758 template<
typename _Tp,
typename _Up>
764 reinterpret_cast<typename _Sp::element_type*
>(__r.get()));
791 template<
typename _Tp>
792 class weak_ptr :
public __weak_ptr<_Tp>
794 template<
typename _Arg>
795 using _Constructible =
typename enable_if<
799 template<
typename _Arg>
805 constexpr weak_ptr()
noexcept =
default;
807 template<
typename _Yp,
808 typename = _Constructible<const shared_ptr<_Yp>&>>
810 : __weak_ptr<_Tp>(__r) { }
812 weak_ptr(
const weak_ptr&)
noexcept =
default;
814 template<
typename _Yp,
typename = _Constructible<const weak_ptr<_Yp>&>>
815 weak_ptr(
const weak_ptr<_Yp>& __r) noexcept
816 : __weak_ptr<_Tp>(__r) { }
818 weak_ptr(weak_ptr&&)
noexcept =
default;
820 template<
typename _Yp,
typename = _Constructible<weak_ptr<_Yp>>>
821 weak_ptr(weak_ptr<_Yp>&& __r) noexcept
825 operator=(
const weak_ptr& __r)
noexcept =
default;
827 template<
typename _Yp>
828 _Assignable<const weak_ptr<_Yp>&>
829 operator=(
const weak_ptr<_Yp>& __r)
noexcept
831 this->__weak_ptr<_Tp>::operator=(__r);
835 template<
typename _Yp>
836 _Assignable<const shared_ptr<_Yp>&>
839 this->__weak_ptr<_Tp>::operator=(__r);
844 operator=(weak_ptr&& __r)
noexcept =
default;
846 template<
typename _Yp>
847 _Assignable<weak_ptr<_Yp>>
848 operator=(weak_ptr<_Yp>&& __r)
noexcept
850 this->__weak_ptr<_Tp>::operator=(
std::move(__r));
855 lock()
const noexcept
859#if __cpp_deduction_guides >= 201606
860 template<
typename _Tp>
867 template<
typename _Tp>
869 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b)
noexcept
874 template<
typename _Tp =
void>
883 template<
typename _Tp>
885 :
public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
889 template<
typename _Tp>
891 :
public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
894#ifdef __glibcxx_smart_ptr_owner_equality
903 template<
typename _Tp>
906 {
return __s.owner_hash(); }
908 template<
typename _Tp>
910 operator()(
const weak_ptr<_Tp>& __s)
const noexcept
911 {
return __s.owner_hash(); }
913 using is_transparent = void;
924 template<
typename _Tp1,
typename _Tp2>
926 operator()(
const shared_ptr<_Tp1>& __lhs,
927 const shared_ptr<_Tp2>& __rhs)
const noexcept
928 {
return __lhs.owner_equal(__rhs); }
930 template<
typename _Tp1,
typename _Tp2>
932 operator()(
const shared_ptr<_Tp1>& __lhs,
933 const weak_ptr<_Tp2>& __rhs)
const noexcept
934 {
return __lhs.owner_equal(__rhs); }
936 template<
typename _Tp1,
typename _Tp2>
938 operator()(
const weak_ptr<_Tp1>& __lhs,
939 const shared_ptr<_Tp2>& __rhs)
const noexcept
940 {
return __lhs.owner_equal(__rhs); }
942 template<
typename _Tp1,
typename _Tp2>
944 operator()(
const weak_ptr<_Tp1>& __lhs,
945 const weak_ptr<_Tp2>& __rhs)
const noexcept
946 {
return __lhs.owner_equal(__rhs); }
948 using is_transparent = void;
957 template<
typename _Tp>
958 class enable_shared_from_this
961 constexpr enable_shared_from_this()
noexcept { }
963 enable_shared_from_this(
const enable_shared_from_this&)
noexcept { }
965 enable_shared_from_this&
966 operator=(
const enable_shared_from_this&)
noexcept
969 ~enable_shared_from_this() { }
977 shared_from_this()
const
980#ifdef __glibcxx_enable_shared_from_this
986 weak_from_this()
noexcept
987 {
return this->_M_weak_this; }
990 weak_from_this()
const noexcept
991 {
return this->_M_weak_this; }
996 template<
typename _Tp1>
998 _M_weak_assign(_Tp1* __p,
const __shared_count<>& __n)
const noexcept
999 { _M_weak_this._M_assign(__p, __n); }
1002 friend const enable_shared_from_this*
1003 __enable_shared_from_this_base(
const __shared_count<>&,
1004 const enable_shared_from_this* __p)
1007 template<
typename, _Lock_policy>
1008 friend class __shared_ptr;
1026 template<
typename _Tp,
typename _Alloc,
typename... _Args>
1041 template<
typename _Tp,
typename... _Args>
1051#if __glibcxx_shared_ptr_arrays >= 201707L
1053 template<
typename _Tp,
typename _Alloc = allocator<
void>>
1055 __make_shared_arr_tag(
size_t __n,
const _Alloc& __a = _Alloc()) noexcept
1058 using _UpAlloc = __alloc_rebind<_Alloc, _Up>;
1060 if (__builtin_mul_overflow(__s, __n, &__n))
1061 std::__throw_bad_array_new_length();
1062 return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};
1066 template<
typename _Tp,
typename _Alloc>
1073 template<
typename _Tp>
1080 template<
typename _Tp,
typename _Alloc>
1089 template<
typename _Tp>
1098 template<
typename _Tp,
typename _Alloc = allocator<
void>>
1100 __make_shared_arrN_tag(
const _Alloc& __a = _Alloc()) noexcept
1103 using _UpAlloc = __alloc_rebind<_Alloc, _Up>;
1104 size_t __n =
sizeof(_Tp) /
sizeof(_Up);
1105 return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};
1109 template<
typename _Tp,
typename _Alloc>
1116 template<
typename _Tp>
1123 template<
typename _Tp,
typename _Alloc>
1131 template<
typename _Tp>
1139#if __glibcxx_smart_ptr_for_overwrite
1140 template<
typename _Tp,
typename _Alloc>
1142 allocate_shared_for_overwrite(
const _Alloc& __a)
1144 if constexpr (is_array_v<_Tp>)
1146 _Sp_overwrite_tag{});
1151 using _Alloc2 = __alloc_rebind<_Alloc, _Sp_overwrite_tag>;
1157 template<
typename _Tp>
1159 make_shared_for_overwrite()
1161 if constexpr (is_array_v<_Tp>)
1163 _Sp_overwrite_tag{});
1171 template<
typename _Tp,
typename _Alloc>
1173 allocate_shared_for_overwrite(
const _Alloc& __a,
size_t __n)
1176 _Sp_overwrite_tag{});
1179 template<
typename _Tp>
1181 make_shared_for_overwrite(
size_t __n)
1184 _Sp_overwrite_tag{});
1190 template<
typename _Tp>
1192 :
public __hash_base<size_t, shared_ptr<_Tp>>
1201#if __cpp_variable_templates
1202 template<
typename _Tp>
1203 constexpr bool __is_shared_ptr =
false;
1204 template<
typename _Tp>
1205 constexpr bool __is_shared_ptr<shared_ptr<_Tp>> =
true;
1211#if __cplusplus >= 201703L
1212 namespace __detail::__variant
1214 template<
typename>
struct _Never_valueless_alt;
1218 template<
typename _Tp>
1225 template<
typename _Tp>
1226 struct _Never_valueless_alt<
std::weak_ptr<_Tp>>
1232_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.