2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___MEMORY_SHARED_PTR_H
11 #define _LIBCPP___MEMORY_SHARED_PTR_H
13 #include <__compare/compare_three_way.h>
14 #include <__compare/ordering.h>
16 #include <__cstddef/nullptr_t.h>
17 #include <__cstddef/ptrdiff_t.h>
18 #include <__exception/exception.h>
19 #include <__functional/binary_function.h>
20 #include <__functional/operations.h>
21 #include <__functional/reference_wrapper.h>
22 #include <__fwd/ostream.h>
23 #include <__iterator/access.h>
24 #include <__memory/addressof.h>
25 #include <__memory/allocation_guard.h>
26 #include <__memory/allocator.h>
27 #include <__memory/allocator_destructor.h>
28 #include <__memory/allocator_traits.h>
29 #include <__memory/auto_ptr.h>
30 #include <__memory/compressed_pair.h>
31 #include <__memory/construct_at.h>
32 #include <__memory/pointer_traits.h>
33 #include <__memory/shared_count.h>
34 #include <__memory/uninitialized_algorithms.h>
35 #include <__memory/unique_ptr.h>
36 #include <__type_traits/add_lvalue_reference.h>
37 #include <__type_traits/conditional.h>
38 #include <__type_traits/conjunction.h>
39 #include <__type_traits/disjunction.h>
40 #include <__type_traits/enable_if.h>
41 #include <__type_traits/integral_constant.h>
42 #include <__type_traits/is_array.h>
43 #include <__type_traits/is_bounded_array.h>
44 #include <__type_traits/is_constructible.h>
45 #include <__type_traits/is_convertible.h>
46 #include <__type_traits/is_reference.h>
47 #include <__type_traits/is_same.h>
48 #include <__type_traits/is_unbounded_array.h>
49 #include <__type_traits/nat.h>
50 #include <__type_traits/negation.h>
51 #include <__type_traits/remove_cv.h>
52 #include <__type_traits/remove_extent.h>
53 #include <__type_traits/remove_reference.h>
54 #include <__utility/declval.h>
55 #include <__utility/forward.h>
56 #include <__utility/move.h>
57 #include <__utility/swap.h>
58 #include <__verbose_abort>
61 #if _LIBCPP_HAS_ATOMIC_HEADER
62 # include <__atomic/memory_order.h>
65 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
66 # pragma GCC system_header
70 #include <__undef_macros>
72 _LIBCPP_BEGIN_NAMESPACE_STD
74 class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr
: public std::exception
{
76 _LIBCPP_HIDE_FROM_ABI
bad_weak_ptr() _NOEXCEPT
= default;
77 _LIBCPP_HIDE_FROM_ABI
bad_weak_ptr(const bad_weak_ptr
&) _NOEXCEPT
= default;
78 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr
& operator=(const bad_weak_ptr
&) _NOEXCEPT
= default;
79 ~bad_weak_ptr() _NOEXCEPT override
;
80 const char* what() const _NOEXCEPT override
;
83 [[__noreturn__
]] inline _LIBCPP_HIDE_FROM_ABI
void __throw_bad_weak_ptr() {
84 #if _LIBCPP_HAS_EXCEPTIONS
87 _LIBCPP_VERBOSE_ABORT("bad_weak_ptr was thrown in -fno-exceptions mode");
92 class _LIBCPP_TEMPLATE_VIS weak_ptr
;
94 template <class _Tp
, class _Dp
, class _Alloc
>
95 class __shared_ptr_pointer
: public __shared_weak_count
{
96 _LIBCPP_COMPRESSED_TRIPLE(_Tp
, __ptr_
, _Dp
, __deleter_
, _Alloc
, __alloc_
);
99 _LIBCPP_HIDE_FROM_ABI
__shared_ptr_pointer(_Tp __p
, _Dp __d
, _Alloc __a
)
100 : __ptr_(__p
), __deleter_(std::move(__d
)), __alloc_(std::move(__a
)) {}
103 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
const void* __get_deleter(const type_info
&) const _NOEXCEPT override
;
107 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
;
108 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
;
113 template <class _Tp
, class _Dp
, class _Alloc
>
114 const void* __shared_ptr_pointer
<_Tp
, _Dp
, _Alloc
>::__get_deleter(const type_info
& __t
) const _NOEXCEPT
{
115 return __t
== typeid(_Dp
) ? std::addressof(__deleter_
) : nullptr;
118 #endif // _LIBCPP_HAS_RTTI
120 template <class _Tp
, class _Dp
, class _Alloc
>
121 void __shared_ptr_pointer
<_Tp
, _Dp
, _Alloc
>::__on_zero_shared() _NOEXCEPT
{
126 template <class _Tp
, class _Dp
, class _Alloc
>
127 void __shared_ptr_pointer
<_Tp
, _Dp
, _Alloc
>::__on_zero_shared_weak() _NOEXCEPT
{
128 typedef typename __allocator_traits_rebind
<_Alloc
, __shared_ptr_pointer
>::type _Al
;
129 typedef allocator_traits
<_Al
> _ATraits
;
130 typedef pointer_traits
<typename
_ATraits::pointer
> _PTraits
;
134 __a
.deallocate(_PTraits::pointer_to(*this), 1);
137 // This tag is used to instantiate an allocator type. The various shared_ptr control blocks
138 // detect that the allocator has been instantiated for this type and perform alternative
139 // initialization/destruction based on that.
140 struct __for_overwrite_tag
{};
142 template <class _Tp
, class _Alloc
>
143 struct __shared_ptr_emplace
: __shared_weak_count
{
144 using __value_type
= __remove_cv_t
<_Tp
>;
146 template <class... _Args
,
147 class _Allocator
= _Alloc
,
148 __enable_if_t
<is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
149 _LIBCPP_HIDE_FROM_ABI
explicit __shared_ptr_emplace(_Alloc __a
, _Args
&&...) : __storage_(std::move(__a
)) {
151 sizeof...(_Args
) == 0, "No argument should be provided to the control block when using _for_overwrite");
152 ::new (static_cast<void*>(__get_elem())) __value_type
;
155 template <class... _Args
,
156 class _Allocator
= _Alloc
,
157 __enable_if_t
<!is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
158 _LIBCPP_HIDE_FROM_ABI
explicit __shared_ptr_emplace(_Alloc __a
, _Args
&&... __args
) : __storage_(std::move(__a
)) {
159 using _TpAlloc
= typename __allocator_traits_rebind
<_Alloc
, __value_type
>::type
;
160 _TpAlloc
__tmp(*__get_alloc());
161 allocator_traits
<_TpAlloc
>::construct(__tmp
, __get_elem(), std::forward
<_Args
>(__args
)...);
164 _LIBCPP_HIDE_FROM_ABI _Alloc
* __get_alloc() _NOEXCEPT
{ return __storage_
.__get_alloc(); }
166 _LIBCPP_HIDE_FROM_ABI __value_type
* __get_elem() _NOEXCEPT
{ return __storage_
.__get_elem(); }
169 template <class _Allocator
= _Alloc
,
170 __enable_if_t
<is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
171 _LIBCPP_HIDE_FROM_ABI
void __on_zero_shared_impl() _NOEXCEPT
{
172 __get_elem()->~__value_type();
175 template <class _Allocator
= _Alloc
,
176 __enable_if_t
<!is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
177 _LIBCPP_HIDE_FROM_ABI
void __on_zero_shared_impl() _NOEXCEPT
{
178 using _TpAlloc
= typename __allocator_traits_rebind
<_Allocator
, __remove_cv_t
<_Tp
> >::type
;
179 _TpAlloc
__tmp(*__get_alloc());
180 allocator_traits
<_TpAlloc
>::destroy(__tmp
, __get_elem());
183 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
{ __on_zero_shared_impl(); }
185 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
{
186 using _ControlBlockAlloc
= typename __allocator_traits_rebind
<_Alloc
, __shared_ptr_emplace
>::type
;
187 using _ControlBlockPointer
= typename allocator_traits
<_ControlBlockAlloc
>::pointer
;
188 _ControlBlockAlloc
__tmp(*__get_alloc());
189 __storage_
.~_Storage();
190 allocator_traits
<_ControlBlockAlloc
>::deallocate(__tmp
, pointer_traits
<_ControlBlockPointer
>::pointer_to(*this), 1);
193 // TODO: It should be possible to refactor this to remove `_Storage` entirely.
194 // This class implements the control block for non-array shared pointers created
195 // through `std::allocate_shared` and `std::make_shared`.
198 _LIBCPP_COMPRESSED_PAIR(_Alloc
, __alloc_
, __value_type
, __elem_
);
201 _ALIGNAS_TYPE(_Data
) char __buffer_
[sizeof(_Data
)];
203 _LIBCPP_HIDE_FROM_ABI
explicit _Storage(_Alloc
&& __a
) { ::new ((void*)__get_alloc()) _Alloc(std::move(__a
)); }
204 _LIBCPP_HIDE_FROM_ABI
~_Storage() { __get_alloc()->~_Alloc(); }
206 _LIBCPP_HIDE_FROM_ABI _Alloc
* __get_alloc() _NOEXCEPT
{
207 return std::addressof(reinterpret_cast<_Data
*>(__buffer_
)->__alloc_
);
210 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __value_type
* __get_elem() _NOEXCEPT
{
211 return std::addressof(reinterpret_cast<_Data
*>(__buffer_
)->__elem_
);
218 struct __shared_ptr_dummy_rebind_allocator_type
;
220 class _LIBCPP_TEMPLATE_VIS allocator
<__shared_ptr_dummy_rebind_allocator_type
> {
222 template <class _Other
>
224 typedef allocator
<_Other
> other
;
229 class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
;
231 // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.general-6
232 // A pointer type Y* is said to be compatible with a pointer type T*
233 // when either Y* is convertible to T* or Y is U[N] and T is cv U[].
234 #if _LIBCPP_STD_VER >= 17
235 template <class _Yp
, class _Tp
>
236 struct __bounded_convertible_to_unbounded
: false_type
{};
238 template <class _Up
, std::size_t _Np
, class _Tp
>
239 struct __bounded_convertible_to_unbounded
<_Up
[_Np
], _Tp
> : is_same
<__remove_cv_t
<_Tp
>, _Up
[]> {};
241 template <class _Yp
, class _Tp
>
242 struct __compatible_with
: _Or
< is_convertible
<_Yp
*, _Tp
*>, __bounded_convertible_to_unbounded
<_Yp
, _Tp
> > {};
244 template <class _Yp
, class _Tp
>
245 struct __compatible_with
: is_convertible
<_Yp
*, _Tp
*> {};
246 #endif // _LIBCPP_STD_VER >= 17
248 // Constructors that take raw pointers have a different set of "compatible" constraints
249 // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.const-9.1
250 // - If T is an array type, then either T is U[N] and Y(*)[N] is convertible to T*,
251 // or T is U[] and Y(*)[] is convertible to T*.
252 // - If T is not an array type, then Y* is convertible to T*.
253 #if _LIBCPP_STD_VER >= 17
254 template <class _Yp
, class _Tp
, class = void>
255 struct __raw_pointer_compatible_with
: _And
< _Not
<is_array
<_Tp
>>, is_convertible
<_Yp
*, _Tp
*> > {};
257 template <class _Yp
, class _Up
, std::size_t _Np
>
258 struct __raw_pointer_compatible_with
<_Yp
, _Up
[_Np
], __enable_if_t
< is_convertible
<_Yp (*)[_Np
], _Up (*)[_Np
]>::value
> >
261 template <class _Yp
, class _Up
>
262 struct __raw_pointer_compatible_with
<_Yp
, _Up
[], __enable_if_t
< is_convertible
<_Yp (*)[], _Up (*)[]>::value
> >
266 template <class _Yp
, class _Tp
>
267 struct __raw_pointer_compatible_with
: is_convertible
<_Yp
*, _Tp
*> {};
268 #endif // _LIBCPP_STD_VER >= 17
270 template <class _Ptr
, class = void>
271 struct __is_deletable
: false_type
{};
272 template <class _Ptr
>
273 struct __is_deletable
<_Ptr
, decltype(delete std::declval
<_Ptr
>())> : true_type
{};
275 template <class _Ptr
, class = void>
276 struct __is_array_deletable
: false_type
{};
277 template <class _Ptr
>
278 struct __is_array_deletable
<_Ptr
, decltype(delete[] std::declval
<_Ptr
>())> : true_type
{};
280 template <class _Dp
, class _Pt
, class = decltype(std::declval
<_Dp
>()(std::declval
<_Pt
>()))>
281 true_type
__well_formed_deleter_test(int);
283 template <class, class>
284 false_type
__well_formed_deleter_test(...);
286 template <class _Dp
, class _Pt
>
287 struct __well_formed_deleter
: decltype(std::__well_formed_deleter_test
<_Dp
, _Pt
>(0)) {};
289 template <class _Dp
, class _Yp
, class _Tp
>
290 struct __shared_ptr_deleter_ctor_reqs
{
291 static const bool value
= __raw_pointer_compatible_with
<_Yp
, _Tp
>::value
&& is_move_constructible
<_Dp
>::value
&&
292 __well_formed_deleter
<_Dp
, _Yp
*>::value
;
296 using __shared_ptr_nullptr_deleter_ctor_reqs
= _And
<is_move_constructible
<_Dp
>, __well_formed_deleter
<_Dp
, nullptr_t
> >;
298 #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
299 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
301 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
305 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
{
306 struct __nullptr_sfinae_tag
{};
309 #if _LIBCPP_STD_VER >= 17
310 typedef weak_ptr
<_Tp
> weak_type
;
311 typedef remove_extent_t
<_Tp
> element_type
;
313 typedef _Tp element_type
;
316 // A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
317 // any bookkeeping, so it's always trivially relocatable.
318 using __trivially_relocatable
= shared_ptr
;
321 element_type
* __ptr_
;
322 __shared_weak_count
* __cntrl_
;
325 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
shared_ptr() _NOEXCEPT
: __ptr_(nullptr), __cntrl_(nullptr) {}
327 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
shared_ptr(nullptr_t
) _NOEXCEPT
: __ptr_(nullptr), __cntrl_(nullptr) {}
330 __enable_if_t
< _And
< __raw_pointer_compatible_with
<_Yp
, _Tp
>
331 // In C++03 we get errors when trying to do SFINAE with the
332 // delete operator, so we always pretend that it's deletable.
333 // The same happens on GCC.
334 #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC)
336 _If
<is_array
<_Tp
>::value
, __is_array_deletable
<_Yp
*>, __is_deletable
<_Yp
*> >
340 _LIBCPP_HIDE_FROM_ABI
explicit shared_ptr(_Yp
* __p
) : __ptr_(__p
) {
341 unique_ptr
<_Yp
> __hold(__p
);
342 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
343 typedef __shared_ptr_pointer
<_Yp
*, __shared_ptr_default_delete
<_Tp
, _Yp
>, _AllocT
> _CntrlBlk
;
344 __cntrl_
= new _CntrlBlk(__p
, __shared_ptr_default_delete
<_Tp
, _Yp
>(), _AllocT());
346 __enable_weak_this(__p
, __p
);
349 template <class _Yp
, class _Dp
, __enable_if_t
<__shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
, int> = 0>
350 _LIBCPP_HIDE_FROM_ABI
shared_ptr(_Yp
* __p
, _Dp __d
) : __ptr_(__p
) {
351 #if _LIBCPP_HAS_EXCEPTIONS
353 #endif // _LIBCPP_HAS_EXCEPTIONS
354 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
355 typedef __shared_ptr_pointer
<_Yp
*, _Dp
, _AllocT
> _CntrlBlk
;
356 #ifndef _LIBCPP_CXX03_LANG
357 __cntrl_
= new _CntrlBlk(__p
, std::move(__d
), _AllocT());
359 __cntrl_
= new _CntrlBlk(__p
, __d
, _AllocT());
360 #endif // not _LIBCPP_CXX03_LANG
361 __enable_weak_this(__p
, __p
);
362 #if _LIBCPP_HAS_EXCEPTIONS
367 #endif // _LIBCPP_HAS_EXCEPTIONS
373 __enable_if_t
<__shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
, int> = 0>
374 _LIBCPP_HIDE_FROM_ABI
shared_ptr(_Yp
* __p
, _Dp __d
, _Alloc __a
) : __ptr_(__p
) {
375 #if _LIBCPP_HAS_EXCEPTIONS
377 #endif // _LIBCPP_HAS_EXCEPTIONS
378 typedef __shared_ptr_pointer
<_Yp
*, _Dp
, _Alloc
> _CntrlBlk
;
379 typedef typename __allocator_traits_rebind
<_Alloc
, _CntrlBlk
>::type _A2
;
380 typedef __allocator_destructor
<_A2
> _D2
;
382 unique_ptr
<_CntrlBlk
, _D2
> __hold2(__a2
.allocate(1), _D2(__a2
, 1));
383 ::new ((void*)std::addressof(*__hold2
.get()))
384 #ifndef _LIBCPP_CXX03_LANG
385 _CntrlBlk(__p
, std::move(__d
), __a
);
387 _CntrlBlk(__p
, __d
, __a
);
388 #endif // not _LIBCPP_CXX03_LANG
389 __cntrl_
= std::addressof(*__hold2
.release());
390 __enable_weak_this(__p
, __p
);
391 #if _LIBCPP_HAS_EXCEPTIONS
396 #endif // _LIBCPP_HAS_EXCEPTIONS
400 _LIBCPP_HIDE_FROM_ABI
shared_ptr(
403 __enable_if_t
<__shared_ptr_nullptr_deleter_ctor_reqs
<_Dp
>::value
, __nullptr_sfinae_tag
> = __nullptr_sfinae_tag())
405 #if _LIBCPP_HAS_EXCEPTIONS
407 #endif // _LIBCPP_HAS_EXCEPTIONS
408 typedef typename __shared_ptr_default_allocator
<_Tp
>::type _AllocT
;
409 typedef __shared_ptr_pointer
<nullptr_t
, _Dp
, _AllocT
> _CntrlBlk
;
410 #ifndef _LIBCPP_CXX03_LANG
411 __cntrl_
= new _CntrlBlk(__p
, std::move(__d
), _AllocT());
413 __cntrl_
= new _CntrlBlk(__p
, __d
, _AllocT());
414 #endif // not _LIBCPP_CXX03_LANG
415 #if _LIBCPP_HAS_EXCEPTIONS
420 #endif // _LIBCPP_HAS_EXCEPTIONS
423 template <class _Dp
, class _Alloc
>
424 _LIBCPP_HIDE_FROM_ABI
shared_ptr(
428 __enable_if_t
<__shared_ptr_nullptr_deleter_ctor_reqs
<_Dp
>::value
, __nullptr_sfinae_tag
> = __nullptr_sfinae_tag())
430 #if _LIBCPP_HAS_EXCEPTIONS
432 #endif // _LIBCPP_HAS_EXCEPTIONS
433 typedef __shared_ptr_pointer
<nullptr_t
, _Dp
, _Alloc
> _CntrlBlk
;
434 typedef typename __allocator_traits_rebind
<_Alloc
, _CntrlBlk
>::type _A2
;
435 typedef __allocator_destructor
<_A2
> _D2
;
437 unique_ptr
<_CntrlBlk
, _D2
> __hold2(__a2
.allocate(1), _D2(__a2
, 1));
438 ::new ((void*)std::addressof(*__hold2
.get()))
439 #ifndef _LIBCPP_CXX03_LANG
440 _CntrlBlk(__p
, std::move(__d
), __a
);
442 _CntrlBlk(__p
, __d
, __a
);
443 #endif // not _LIBCPP_CXX03_LANG
444 __cntrl_
= std::addressof(*__hold2
.release());
445 #if _LIBCPP_HAS_EXCEPTIONS
450 #endif // _LIBCPP_HAS_EXCEPTIONS
454 _LIBCPP_HIDE_FROM_ABI
shared_ptr(const shared_ptr
<_Yp
>& __r
, element_type
* __p
) _NOEXCEPT
456 __cntrl_(__r
.__cntrl_
) {
458 __cntrl_
->__add_shared();
462 // We don't backport because it is an evolutionary change.
463 #if _LIBCPP_STD_VER >= 20
465 _LIBCPP_HIDE_FROM_ABI
shared_ptr(shared_ptr
<_Yp
>&& __r
, element_type
* __p
) noexcept
466 : __ptr_(__p
), __cntrl_(__r
.__cntrl_
) {
467 __r
.__ptr_
= nullptr;
468 __r
.__cntrl_
= nullptr;
472 _LIBCPP_HIDE_FROM_ABI
shared_ptr(const shared_ptr
& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
474 __cntrl_
->__add_shared();
477 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
478 _LIBCPP_HIDE_FROM_ABI
shared_ptr(const shared_ptr
<_Yp
>& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
480 __cntrl_
->__add_shared();
483 _LIBCPP_HIDE_FROM_ABI
shared_ptr(shared_ptr
&& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
484 __r
.__ptr_
= nullptr;
485 __r
.__cntrl_
= nullptr;
488 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
489 _LIBCPP_HIDE_FROM_ABI
shared_ptr(shared_ptr
<_Yp
>&& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
490 __r
.__ptr_
= nullptr;
491 __r
.__cntrl_
= nullptr;
494 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
495 _LIBCPP_HIDE_FROM_ABI
explicit shared_ptr(const weak_ptr
<_Yp
>& __r
)
496 : __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
? __r
.__cntrl_
->lock() : __r
.__cntrl_
) {
497 if (__cntrl_
== nullptr)
498 __throw_bad_weak_ptr();
501 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
502 template <class _Yp
, __enable_if_t
<is_convertible
<_Yp
*, element_type
*>::value
, int> = 0>
503 _LIBCPP_HIDE_FROM_ABI
shared_ptr(auto_ptr
<_Yp
>&& __r
) : __ptr_(__r
.get()) {
504 typedef __shared_ptr_pointer
<_Yp
*, default_delete
<_Yp
>, allocator
<__remove_cv_t
<_Yp
> > > _CntrlBlk
;
505 __cntrl_
= new _CntrlBlk(__r
.get(), default_delete
<_Yp
>(), allocator
<__remove_cv_t
<_Yp
> >());
506 __enable_weak_this(__r
.get(), __r
.get());
513 __enable_if_t
<!is_lvalue_reference
<_Dp
>::value
&& __compatible_with
<_Yp
, _Tp
>::value
&&
514 is_convertible
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, element_type
*>::value
,
516 _LIBCPP_HIDE_FROM_ABI
shared_ptr(unique_ptr
<_Yp
, _Dp
>&& __r
) : __ptr_(__r
.get()) {
517 #if _LIBCPP_STD_VER >= 14
518 if (__ptr_
== nullptr)
523 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
524 typedef __shared_ptr_pointer
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, _Dp
, _AllocT
> _CntrlBlk
;
525 __cntrl_
= new _CntrlBlk(__r
.get(), std::move(__r
.get_deleter()), _AllocT());
526 __enable_weak_this(__r
.get(), __r
.get());
534 __enable_if_t
<is_lvalue_reference
<_Dp
>::value
&& __compatible_with
<_Yp
, _Tp
>::value
&&
535 is_convertible
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, element_type
*>::value
,
537 _LIBCPP_HIDE_FROM_ABI
shared_ptr(unique_ptr
<_Yp
, _Dp
>&& __r
) : __ptr_(__r
.get()) {
538 #if _LIBCPP_STD_VER >= 14
539 if (__ptr_
== nullptr)
544 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
545 typedef __shared_ptr_pointer
<typename unique_ptr
<_Yp
, _Dp
>::pointer
,
546 reference_wrapper
<__libcpp_remove_reference_t
<_Dp
> >,
549 __cntrl_
= new _CntrlBlk(__r
.get(), std::ref(__r
.get_deleter()), _AllocT());
550 __enable_weak_this(__r
.get(), __r
.get());
555 _LIBCPP_HIDE_FROM_ABI
~shared_ptr() {
557 __cntrl_
->__release_shared();
560 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(const shared_ptr
& __r
) _NOEXCEPT
{
561 shared_ptr(__r
).swap(*this);
565 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
566 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(const shared_ptr
<_Yp
>& __r
) _NOEXCEPT
{
567 shared_ptr(__r
).swap(*this);
571 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(shared_ptr
&& __r
) _NOEXCEPT
{
572 shared_ptr(std::move(__r
)).swap(*this);
576 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
577 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(shared_ptr
<_Yp
>&& __r
) {
578 shared_ptr(std::move(__r
)).swap(*this);
582 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
584 __enable_if_t
<!is_array
<_Yp
>::value
&& is_convertible
<_Yp
*, typename shared_ptr
<_Tp
>::element_type
*>::value
,
586 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(auto_ptr
<_Yp
>&& __r
) {
587 shared_ptr(std::move(__r
)).swap(*this);
594 __enable_if_t
<_And
< __compatible_with
<_Yp
, _Tp
>,
595 is_convertible
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, element_type
*> >::value
,
597 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(unique_ptr
<_Yp
, _Dp
>&& __r
) {
598 shared_ptr(std::move(__r
)).swap(*this);
602 _LIBCPP_HIDE_FROM_ABI
void swap(shared_ptr
& __r
) _NOEXCEPT
{
603 std::swap(__ptr_
, __r
.__ptr_
);
604 std::swap(__cntrl_
, __r
.__cntrl_
);
607 _LIBCPP_HIDE_FROM_ABI
void reset() _NOEXCEPT
{ shared_ptr().swap(*this); }
609 template <class _Yp
, __enable_if_t
<__raw_pointer_compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
610 _LIBCPP_HIDE_FROM_ABI
void reset(_Yp
* __p
) {
611 shared_ptr(__p
).swap(*this);
614 template <class _Yp
, class _Dp
, __enable_if_t
<__shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
, int> = 0>
615 _LIBCPP_HIDE_FROM_ABI
void reset(_Yp
* __p
, _Dp __d
) {
616 shared_ptr(__p
, __d
).swap(*this);
622 __enable_if_t
<__shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
, int> = 0>
623 _LIBCPP_HIDE_FROM_ABI
void reset(_Yp
* __p
, _Dp __d
, _Alloc __a
) {
624 shared_ptr(__p
, __d
, __a
).swap(*this);
627 _LIBCPP_HIDE_FROM_ABI element_type
* get() const _NOEXCEPT
{ return __ptr_
; }
629 _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t
<element_type
> operator*() const _NOEXCEPT
{ return *__ptr_
; }
631 _LIBCPP_HIDE_FROM_ABI element_type
* operator->() const _NOEXCEPT
{
632 static_assert(!is_array
<_Tp
>::value
, "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
636 _LIBCPP_HIDE_FROM_ABI
long use_count() const _NOEXCEPT
{ return __cntrl_
? __cntrl_
->use_count() : 0; }
638 #if _LIBCPP_STD_VER < 20 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE)
639 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI
bool unique() const _NOEXCEPT
{ return use_count() == 1; }
642 _LIBCPP_HIDE_FROM_ABI
explicit operator bool() const _NOEXCEPT
{ return get() != nullptr; }
645 _LIBCPP_HIDE_FROM_ABI
bool owner_before(shared_ptr
<_Up
> const& __p
) const _NOEXCEPT
{
646 return __cntrl_
< __p
.__cntrl_
;
650 _LIBCPP_HIDE_FROM_ABI
bool owner_before(weak_ptr
<_Up
> const& __p
) const _NOEXCEPT
{
651 return __cntrl_
< __p
.__cntrl_
;
654 _LIBCPP_HIDE_FROM_ABI
bool __owner_equivalent(const shared_ptr
& __p
) const { return __cntrl_
== __p
.__cntrl_
; }
656 #if _LIBCPP_STD_VER >= 17
657 _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t
<element_type
> operator[](ptrdiff_t __i
) const {
658 static_assert(is_array
<_Tp
>::value
, "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
665 _LIBCPP_HIDE_FROM_ABI _Dp
* __get_deleter() const _NOEXCEPT
{
666 return static_cast<_Dp
*>(__cntrl_
? const_cast<void*>(__cntrl_
->__get_deleter(typeid(_Dp
))) : nullptr);
668 #endif // _LIBCPP_HAS_RTTI
670 template <class _Yp
, class _CntrlBlk
>
671 _LIBCPP_HIDE_FROM_ABI
static shared_ptr
<_Tp
> __create_with_control_block(_Yp
* __p
, _CntrlBlk
* __cntrl
) _NOEXCEPT
{
674 __r
.__cntrl_
= __cntrl
;
675 __r
.__enable_weak_this(__r
.__ptr_
, __r
.__ptr_
);
680 template <class _Yp
, bool = is_function
<_Yp
>::value
>
681 struct __shared_ptr_default_allocator
{
682 typedef allocator
<__remove_cv_t
<_Yp
> > type
;
686 struct __shared_ptr_default_allocator
<_Yp
, true> {
687 typedef allocator
<__shared_ptr_dummy_rebind_allocator_type
> type
;
692 __enable_if_t
<is_convertible
<_OrigPtr
*, const enable_shared_from_this
<_Yp
>*>::value
, int> = 0>
693 _LIBCPP_HIDE_FROM_ABI
void __enable_weak_this(const enable_shared_from_this
<_Yp
>* __e
, _OrigPtr
* __ptr
) _NOEXCEPT
{
694 typedef __remove_cv_t
<_Yp
> _RawYp
;
695 if (__e
&& __e
->__weak_this_
.expired()) {
696 __e
->__weak_this_
= shared_ptr
<_RawYp
>(*this, const_cast<_RawYp
*>(static_cast<const _Yp
*>(__ptr
)));
700 _LIBCPP_HIDE_FROM_ABI
void __enable_weak_this(...) _NOEXCEPT
{}
702 template <class, class _Yp
>
703 struct __shared_ptr_default_delete
: default_delete
<_Yp
> {};
705 template <class _Yp
, class _Un
, size_t _Sz
>
706 struct __shared_ptr_default_delete
<_Yp
[_Sz
], _Un
> : default_delete
<_Yp
[]> {};
708 template <class _Yp
, class _Un
>
709 struct __shared_ptr_default_delete
<_Yp
[], _Un
> : default_delete
<_Yp
[]> {};
712 friend class _LIBCPP_TEMPLATE_VIS shared_ptr
;
714 friend class _LIBCPP_TEMPLATE_VIS weak_ptr
;
717 #if _LIBCPP_STD_VER >= 17
719 shared_ptr(weak_ptr
<_Tp
>) -> shared_ptr
<_Tp
>;
720 template <class _Tp
, class _Dp
>
721 shared_ptr(unique_ptr
<_Tp
, _Dp
>) -> shared_ptr
<_Tp
>;
725 // std::allocate_shared and std::make_shared
727 template <class _Tp
, class _Alloc
, class... _Args
, __enable_if_t
<!is_array
<_Tp
>::value
, int> = 0>
728 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, _Args
&&... __args
) {
729 using _ControlBlock
= __shared_ptr_emplace
<_Tp
, _Alloc
>;
730 using _ControlBlockAllocator
= typename __allocator_traits_rebind
<_Alloc
, _ControlBlock
>::type
;
731 __allocation_guard
<_ControlBlockAllocator
> __guard(__a
, 1);
732 ::new ((void*)std::addressof(*__guard
.__get())) _ControlBlock(__a
, std::forward
<_Args
>(__args
)...);
733 auto __control_block
= __guard
.__release_ptr();
734 return shared_ptr
<_Tp
>::__create_with_control_block(
735 (*__control_block
).__get_elem(), std::addressof(*__control_block
));
738 template <class _Tp
, class... _Args
, __enable_if_t
<!is_array
<_Tp
>::value
, int> = 0>
739 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared(_Args
&&... __args
) {
740 return std::allocate_shared
<_Tp
>(allocator
<__remove_cv_t
<_Tp
> >(), std::forward
<_Args
>(__args
)...);
743 #if _LIBCPP_STD_VER >= 20
745 template <class _Tp
, class _Alloc
, __enable_if_t
<!is_array
<_Tp
>::value
, int> = 0>
746 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared_for_overwrite(const _Alloc
& __a
) {
747 using _ForOverwriteAllocator
= __allocator_traits_rebind_t
<_Alloc
, __for_overwrite_tag
>;
748 _ForOverwriteAllocator
__alloc(__a
);
749 return std::allocate_shared
<_Tp
>(__alloc
);
752 template <class _Tp
, __enable_if_t
<!is_array
<_Tp
>::value
, int> = 0>
753 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared_for_overwrite() {
754 return std::allocate_shared_for_overwrite
<_Tp
>(allocator
<__remove_cv_t
<_Tp
>>());
757 #endif // _LIBCPP_STD_VER >= 20
759 #if _LIBCPP_STD_VER >= 17
761 template <size_t _Alignment
>
762 struct __sp_aligned_storage
{
763 alignas(_Alignment
) char __storage
[_Alignment
];
766 template <class _Tp
, class _Alloc
>
767 struct __unbounded_array_control_block
;
769 template <class _Tp
, class _Alloc
>
770 struct __unbounded_array_control_block
<_Tp
[], _Alloc
> : __shared_weak_count
{
771 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
* __get_data() noexcept
{ return __data_
; }
773 _LIBCPP_HIDE_FROM_ABI
explicit __unbounded_array_control_block(
774 _Alloc
const& __alloc
, size_t __count
, _Tp
const& __arg
)
775 : __alloc_(__alloc
), __count_(__count
) {
776 std::__uninitialized_allocator_fill_n_multidimensional(__alloc_
, std::begin(__data_
), __count_
, __arg
);
779 _LIBCPP_HIDE_FROM_ABI
explicit __unbounded_array_control_block(_Alloc
const& __alloc
, size_t __count
)
780 : __alloc_(__alloc
), __count_(__count
) {
781 # if _LIBCPP_STD_VER >= 20
782 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
783 // We are purposefully not using an allocator-aware default construction because the spec says so.
784 // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
785 std::uninitialized_default_construct_n(std::begin(__data_
), __count_
);
787 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::begin(__data_
), __count_
);
790 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::begin(__data_
), __count_
);
794 // Returns the number of bytes required to store a control block followed by the given number
795 // of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment.
796 _LIBCPP_HIDE_FROM_ABI
static constexpr size_t __bytes_for(size_t __elements
) {
797 // When there's 0 elements, the control block alone is enough since it holds one element.
798 // Otherwise, we allocate one fewer element than requested because the control block already
799 // holds one. Also, we use the bitwise formula below to ensure that we allocate enough bytes
800 // for the whole allocation to be a multiple of _Tp's alignment. That formula is taken from [1].
802 // [1]: https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding
803 size_t __bytes
= __elements
== 0 ? sizeof(__unbounded_array_control_block
)
804 : (__elements
- 1) * sizeof(_Tp
) + sizeof(__unbounded_array_control_block
);
805 constexpr size_t __align
= alignof(_Tp
);
806 return (__bytes
+ __align
- 1) & ~(__align
- 1);
809 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
810 ~__unbounded_array_control_block() override
{
811 } // can't be `= default` because of the sometimes-non-trivial union member __data_
814 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
{
815 # if _LIBCPP_STD_VER >= 20
816 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
817 std::__reverse_destroy(__data_
, __data_
+ __count_
);
819 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
820 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ __count_
);
823 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
824 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ __count_
);
828 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
{
829 using _AlignedStorage
= __sp_aligned_storage
<alignof(__unbounded_array_control_block
)>;
830 using _StorageAlloc
= __allocator_traits_rebind_t
<_Alloc
, _AlignedStorage
>;
831 using _PointerTraits
= pointer_traits
<typename allocator_traits
<_StorageAlloc
>::pointer
>;
833 _StorageAlloc
__tmp(__alloc_
);
835 size_t __size
= __unbounded_array_control_block::__bytes_for(__count_
);
836 _AlignedStorage
* __storage
= reinterpret_cast<_AlignedStorage
*>(this);
837 allocator_traits
<_StorageAlloc
>::deallocate(
838 __tmp
, _PointerTraits::pointer_to(*__storage
), __size
/ sizeof(_AlignedStorage
));
841 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_
;
848 template <class _Array
, class _Alloc
, class... _Arg
>
849 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Array
>
850 __allocate_shared_unbounded_array(const _Alloc
& __a
, size_t __n
, _Arg
&&... __arg
) {
851 static_assert(__is_unbounded_array_v
<_Array
>);
852 // We compute the number of bytes necessary to hold the control block and the
853 // array elements. Then, we allocate an array of properly-aligned dummy structs
854 // large enough to hold the control block and array. This allows shifting the
855 // burden of aligning memory properly from us to the allocator.
856 using _ControlBlock
= __unbounded_array_control_block
<_Array
, _Alloc
>;
857 using _AlignedStorage
= __sp_aligned_storage
<alignof(_ControlBlock
)>;
858 using _StorageAlloc
= __allocator_traits_rebind_t
<_Alloc
, _AlignedStorage
>;
859 __allocation_guard
<_StorageAlloc
> __guard(__a
, _ControlBlock::__bytes_for(__n
) / sizeof(_AlignedStorage
));
860 _ControlBlock
* __control_block
= reinterpret_cast<_ControlBlock
*>(std::addressof(*__guard
.__get()));
861 std::__construct_at(__control_block
, __a
, __n
, std::forward
<_Arg
>(__arg
)...);
862 __guard
.__release_ptr();
863 return shared_ptr
<_Array
>::__create_with_control_block(__control_block
->__get_data(), __control_block
);
866 template <class _Tp
, class _Alloc
>
867 struct __bounded_array_control_block
;
869 template <class _Tp
, size_t _Count
, class _Alloc
>
870 struct __bounded_array_control_block
<_Tp
[_Count
], _Alloc
> : __shared_weak_count
{
871 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
* __get_data() noexcept
{ return __data_
; }
873 _LIBCPP_HIDE_FROM_ABI
explicit __bounded_array_control_block(_Alloc
const& __alloc
, _Tp
const& __arg
)
874 : __alloc_(__alloc
) {
875 std::__uninitialized_allocator_fill_n_multidimensional(__alloc_
, std::addressof(__data_
[0]), _Count
, __arg
);
878 _LIBCPP_HIDE_FROM_ABI
explicit __bounded_array_control_block(_Alloc
const& __alloc
) : __alloc_(__alloc
) {
879 # if _LIBCPP_STD_VER >= 20
880 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
881 // We are purposefully not using an allocator-aware default construction because the spec says so.
882 // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
883 std::uninitialized_default_construct_n(std::addressof(__data_
[0]), _Count
);
885 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::addressof(__data_
[0]), _Count
);
888 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::addressof(__data_
[0]), _Count
);
892 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
893 ~__bounded_array_control_block() override
{
894 } // can't be `= default` because of the sometimes-non-trivial union member __data_
897 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
{
898 # if _LIBCPP_STD_VER >= 20
899 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
900 std::__reverse_destroy(__data_
, __data_
+ _Count
);
902 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
903 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ _Count
);
906 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
907 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ _Count
);
911 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
{
912 using _ControlBlockAlloc
= __allocator_traits_rebind_t
<_Alloc
, __bounded_array_control_block
>;
913 using _PointerTraits
= pointer_traits
<typename allocator_traits
<_ControlBlockAlloc
>::pointer
>;
915 _ControlBlockAlloc
__tmp(__alloc_
);
917 allocator_traits
<_ControlBlockAlloc
>::deallocate(__tmp
, _PointerTraits::pointer_to(*this), 1);
920 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_
;
926 template <class _Array
, class _Alloc
, class... _Arg
>
927 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Array
> __allocate_shared_bounded_array(const _Alloc
& __a
, _Arg
&&... __arg
) {
928 static_assert(__is_bounded_array_v
<_Array
>);
929 using _ControlBlock
= __bounded_array_control_block
<_Array
, _Alloc
>;
930 using _ControlBlockAlloc
= __allocator_traits_rebind_t
<_Alloc
, _ControlBlock
>;
932 __allocation_guard
<_ControlBlockAlloc
> __guard(__a
, 1);
933 _ControlBlock
* __control_block
= reinterpret_cast<_ControlBlock
*>(std::addressof(*__guard
.__get()));
934 std::__construct_at(__control_block
, __a
, std::forward
<_Arg
>(__arg
)...);
935 __guard
.__release_ptr();
936 return shared_ptr
<_Array
>::__create_with_control_block(__control_block
->__get_data(), __control_block
);
939 #endif // _LIBCPP_STD_VER >= 17
941 #if _LIBCPP_STD_VER >= 20
943 // bounded array variants
944 template <class _Tp
, class _Alloc
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
945 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
) {
946 return std::__allocate_shared_bounded_array
<_Tp
>(__a
);
949 template <class _Tp
, class _Alloc
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
950 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, const remove_extent_t
<_Tp
>& __u
) {
951 return std::__allocate_shared_bounded_array
<_Tp
>(__a
, __u
);
954 template <class _Tp
, class _Alloc
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
955 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared_for_overwrite(const _Alloc
& __a
) {
956 using _ForOverwriteAllocator
= __allocator_traits_rebind_t
<_Alloc
, __for_overwrite_tag
>;
957 _ForOverwriteAllocator
__alloc(__a
);
958 return std::__allocate_shared_bounded_array
<_Tp
>(__alloc
);
961 template <class _Tp
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
962 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared() {
963 return std::__allocate_shared_bounded_array
<_Tp
>(allocator
<_Tp
>());
966 template <class _Tp
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
967 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared(const remove_extent_t
<_Tp
>& __u
) {
968 return std::__allocate_shared_bounded_array
<_Tp
>(allocator
<_Tp
>(), __u
);
971 template <class _Tp
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
972 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared_for_overwrite() {
973 return std::__allocate_shared_bounded_array
<_Tp
>(allocator
<__for_overwrite_tag
>());
976 // unbounded array variants
977 template <class _Tp
, class _Alloc
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
978 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, size_t __n
) {
979 return std::__allocate_shared_unbounded_array
<_Tp
>(__a
, __n
);
982 template <class _Tp
, class _Alloc
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
983 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, size_t __n
, const remove_extent_t
<_Tp
>& __u
) {
984 return std::__allocate_shared_unbounded_array
<_Tp
>(__a
, __n
, __u
);
987 template <class _Tp
, class _Alloc
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
988 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared_for_overwrite(const _Alloc
& __a
, size_t __n
) {
989 using _ForOverwriteAllocator
= __allocator_traits_rebind_t
<_Alloc
, __for_overwrite_tag
>;
990 _ForOverwriteAllocator
__alloc(__a
);
991 return std::__allocate_shared_unbounded_array
<_Tp
>(__alloc
, __n
);
994 template <class _Tp
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
995 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared(size_t __n
) {
996 return std::__allocate_shared_unbounded_array
<_Tp
>(allocator
<_Tp
>(), __n
);
999 template <class _Tp
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
1000 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared(size_t __n
, const remove_extent_t
<_Tp
>& __u
) {
1001 return std::__allocate_shared_unbounded_array
<_Tp
>(allocator
<_Tp
>(), __n
, __u
);
1004 template <class _Tp
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
1005 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared_for_overwrite(size_t __n
) {
1006 return std::__allocate_shared_unbounded_array
<_Tp
>(allocator
<__for_overwrite_tag
>(), __n
);
1009 #endif // _LIBCPP_STD_VER >= 20
1011 template <class _Tp
, class _Up
>
1012 inline _LIBCPP_HIDE_FROM_ABI
bool operator==(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1013 return __x
.get() == __y
.get();
1016 #if _LIBCPP_STD_VER <= 17
1018 template <class _Tp
, class _Up
>
1019 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1020 return !(__x
== __y
);
1023 template <class _Tp
, class _Up
>
1024 inline _LIBCPP_HIDE_FROM_ABI
bool operator<(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1025 # if _LIBCPP_STD_VER <= 11
1026 typedef typename common_type
<_Tp
*, _Up
*>::type _Vp
;
1027 return less
<_Vp
>()(__x
.get(), __y
.get());
1029 return less
<>()(__x
.get(), __y
.get());
1033 template <class _Tp
, class _Up
>
1034 inline _LIBCPP_HIDE_FROM_ABI
bool operator>(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1038 template <class _Tp
, class _Up
>
1039 inline _LIBCPP_HIDE_FROM_ABI
bool operator<=(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1040 return !(__y
< __x
);
1043 template <class _Tp
, class _Up
>
1044 inline _LIBCPP_HIDE_FROM_ABI
bool operator>=(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1045 return !(__x
< __y
);
1048 #endif // _LIBCPP_STD_VER <= 17
1050 #if _LIBCPP_STD_VER >= 20
1051 template <class _Tp
, class _Up
>
1052 _LIBCPP_HIDE_FROM_ABI strong_ordering
operator<=>(shared_ptr
<_Tp
> const& __x
, shared_ptr
<_Up
> const& __y
) noexcept
{
1053 return compare_three_way()(__x
.get(), __y
.get());
1057 template <class _Tp
>
1058 inline _LIBCPP_HIDE_FROM_ABI
bool operator==(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1062 #if _LIBCPP_STD_VER <= 17
1064 template <class _Tp
>
1065 inline _LIBCPP_HIDE_FROM_ABI
bool operator==(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1069 template <class _Tp
>
1070 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1071 return static_cast<bool>(__x
);
1074 template <class _Tp
>
1075 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1076 return static_cast<bool>(__x
);
1079 template <class _Tp
>
1080 inline _LIBCPP_HIDE_FROM_ABI
bool operator<(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1081 return less
<typename shared_ptr
<_Tp
>::element_type
*>()(__x
.get(), nullptr);
1084 template <class _Tp
>
1085 inline _LIBCPP_HIDE_FROM_ABI
bool operator<(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1086 return less
<typename shared_ptr
<_Tp
>::element_type
*>()(nullptr, __x
.get());
1089 template <class _Tp
>
1090 inline _LIBCPP_HIDE_FROM_ABI
bool operator>(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1091 return nullptr < __x
;
1094 template <class _Tp
>
1095 inline _LIBCPP_HIDE_FROM_ABI
bool operator>(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1096 return __x
< nullptr;
1099 template <class _Tp
>
1100 inline _LIBCPP_HIDE_FROM_ABI
bool operator<=(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1101 return !(nullptr < __x
);
1104 template <class _Tp
>
1105 inline _LIBCPP_HIDE_FROM_ABI
bool operator<=(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1106 return !(__x
< nullptr);
1109 template <class _Tp
>
1110 inline _LIBCPP_HIDE_FROM_ABI
bool operator>=(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1111 return !(__x
< nullptr);
1114 template <class _Tp
>
1115 inline _LIBCPP_HIDE_FROM_ABI
bool operator>=(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1116 return !(nullptr < __x
);
1119 #endif // _LIBCPP_STD_VER <= 17
1121 #if _LIBCPP_STD_VER >= 20
1122 template <class _Tp
>
1123 _LIBCPP_HIDE_FROM_ABI strong_ordering
operator<=>(shared_ptr
<_Tp
> const& __x
, nullptr_t
) noexcept
{
1124 return compare_three_way()(__x
.get(), static_cast<typename shared_ptr
<_Tp
>::element_type
*>(nullptr));
1128 template <class _Tp
>
1129 inline _LIBCPP_HIDE_FROM_ABI
void swap(shared_ptr
<_Tp
>& __x
, shared_ptr
<_Tp
>& __y
) _NOEXCEPT
{
1133 template <class _Tp
, class _Up
>
1134 inline _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> static_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
{
1135 return shared_ptr
<_Tp
>(__r
, static_cast< typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1139 // We don't backport because it is an evolutionary change.
1140 #if _LIBCPP_STD_VER >= 20
1141 template <class _Tp
, class _Up
>
1142 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> static_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1143 return shared_ptr
<_Tp
>(std::move(__r
), static_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1147 template <class _Tp
, class _Up
>
1148 inline _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> dynamic_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
{
1149 typedef typename shared_ptr
<_Tp
>::element_type _ET
;
1150 _ET
* __p
= dynamic_cast<_ET
*>(__r
.get());
1151 return __p
? shared_ptr
<_Tp
>(__r
, __p
) : shared_ptr
<_Tp
>();
1155 // We don't backport because it is an evolutionary change.
1156 #if _LIBCPP_STD_VER >= 20
1157 template <class _Tp
, class _Up
>
1158 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> dynamic_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1159 auto* __p
= dynamic_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get());
1160 return __p
? shared_ptr
<_Tp
>(std::move(__r
), __p
) : shared_ptr
<_Tp
>();
1164 template <class _Tp
, class _Up
>
1165 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> const_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
{
1166 typedef typename shared_ptr
<_Tp
>::element_type _RTp
;
1167 return shared_ptr
<_Tp
>(__r
, const_cast<_RTp
*>(__r
.get()));
1171 // We don't backport because it is an evolutionary change.
1172 #if _LIBCPP_STD_VER >= 20
1173 template <class _Tp
, class _Up
>
1174 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> const_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1175 return shared_ptr
<_Tp
>(std::move(__r
), const_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1179 template <class _Tp
, class _Up
>
1180 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> reinterpret_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
{
1181 return shared_ptr
<_Tp
>(__r
, reinterpret_cast< typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1185 // We don't backport because it is an evolutionary change.
1186 #if _LIBCPP_STD_VER >= 20
1187 template <class _Tp
, class _Up
>
1188 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> reinterpret_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1189 return shared_ptr
<_Tp
>(std::move(__r
), reinterpret_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1193 #if _LIBCPP_HAS_RTTI
1195 template <class _Dp
, class _Tp
>
1196 inline _LIBCPP_HIDE_FROM_ABI _Dp
* get_deleter(const shared_ptr
<_Tp
>& __p
) _NOEXCEPT
{
1197 return __p
.template __get_deleter
<_Dp
>();
1200 #endif // _LIBCPP_HAS_RTTI
1202 template <class _Tp
>
1203 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
{
1205 #if _LIBCPP_STD_VER >= 17
1206 typedef remove_extent_t
<_Tp
> element_type
;
1208 typedef _Tp element_type
;
1211 // A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
1212 // any bookkeeping, so it's always trivially relocatable.
1213 using __trivially_relocatable
= weak_ptr
;
1216 element_type
* __ptr_
;
1217 __shared_weak_count
* __cntrl_
;
1220 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
weak_ptr() _NOEXCEPT
;
1222 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1223 _LIBCPP_HIDE_FROM_ABI
weak_ptr(shared_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1225 _LIBCPP_HIDE_FROM_ABI
weak_ptr(weak_ptr
const& __r
) _NOEXCEPT
;
1227 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1228 _LIBCPP_HIDE_FROM_ABI
weak_ptr(weak_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1230 _LIBCPP_HIDE_FROM_ABI
weak_ptr(weak_ptr
&& __r
) _NOEXCEPT
;
1232 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1233 _LIBCPP_HIDE_FROM_ABI
weak_ptr(weak_ptr
<_Yp
>&& __r
) _NOEXCEPT
;
1235 _LIBCPP_HIDE_FROM_ABI
~weak_ptr();
1237 _LIBCPP_HIDE_FROM_ABI weak_ptr
& operator=(weak_ptr
const& __r
) _NOEXCEPT
;
1238 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1239 _LIBCPP_HIDE_FROM_ABI weak_ptr
& operator=(weak_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1241 _LIBCPP_HIDE_FROM_ABI weak_ptr
& operator=(weak_ptr
&& __r
) _NOEXCEPT
;
1242 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1243 _LIBCPP_HIDE_FROM_ABI weak_ptr
& operator=(weak_ptr
<_Yp
>&& __r
) _NOEXCEPT
;
1245 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1246 _LIBCPP_HIDE_FROM_ABI weak_ptr
& operator=(shared_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1248 _LIBCPP_HIDE_FROM_ABI
void swap(weak_ptr
& __r
) _NOEXCEPT
;
1249 _LIBCPP_HIDE_FROM_ABI
void reset() _NOEXCEPT
;
1251 _LIBCPP_HIDE_FROM_ABI
long use_count() const _NOEXCEPT
{ return __cntrl_
? __cntrl_
->use_count() : 0; }
1252 _LIBCPP_HIDE_FROM_ABI
bool expired() const _NOEXCEPT
{ return __cntrl_
== nullptr || __cntrl_
->use_count() == 0; }
1253 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> lock() const _NOEXCEPT
;
1254 template <class _Up
>
1255 _LIBCPP_HIDE_FROM_ABI
bool owner_before(const shared_ptr
<_Up
>& __r
) const _NOEXCEPT
{
1256 return __cntrl_
< __r
.__cntrl_
;
1258 template <class _Up
>
1259 _LIBCPP_HIDE_FROM_ABI
bool owner_before(const weak_ptr
<_Up
>& __r
) const _NOEXCEPT
{
1260 return __cntrl_
< __r
.__cntrl_
;
1263 template <class _Up
>
1264 friend class _LIBCPP_TEMPLATE_VIS weak_ptr
;
1265 template <class _Up
>
1266 friend class _LIBCPP_TEMPLATE_VIS shared_ptr
;
1269 #if _LIBCPP_STD_VER >= 17
1270 template <class _Tp
>
1271 weak_ptr(shared_ptr
<_Tp
>) -> weak_ptr
<_Tp
>;
1274 template <class _Tp
>
1275 inline _LIBCPP_CONSTEXPR weak_ptr
<_Tp
>::weak_ptr() _NOEXCEPT
: __ptr_(nullptr), __cntrl_(nullptr) {}
1277 template <class _Tp
>
1278 inline weak_ptr
<_Tp
>::weak_ptr(weak_ptr
const& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
1280 __cntrl_
->__add_weak();
1283 template <class _Tp
>
1284 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1285 inline weak_ptr
<_Tp
>::weak_ptr(shared_ptr
<_Yp
> const& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
1287 __cntrl_
->__add_weak();
1290 template <class _Tp
>
1291 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1292 inline weak_ptr
<_Tp
>::weak_ptr(weak_ptr
<_Yp
> const& __r
) _NOEXCEPT
: __ptr_(nullptr), __cntrl_(nullptr) {
1293 shared_ptr
<_Yp
> __s
= __r
.lock();
1294 *this = weak_ptr
<_Tp
>(__s
);
1297 template <class _Tp
>
1298 inline weak_ptr
<_Tp
>::weak_ptr(weak_ptr
&& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
1299 __r
.__ptr_
= nullptr;
1300 __r
.__cntrl_
= nullptr;
1303 template <class _Tp
>
1304 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1305 inline weak_ptr
<_Tp
>::weak_ptr(weak_ptr
<_Yp
>&& __r
) _NOEXCEPT
: __ptr_(nullptr), __cntrl_(nullptr) {
1306 shared_ptr
<_Yp
> __s
= __r
.lock();
1307 *this = weak_ptr
<_Tp
>(__s
);
1311 template <class _Tp
>
1312 weak_ptr
<_Tp
>::~weak_ptr() {
1314 __cntrl_
->__release_weak();
1317 template <class _Tp
>
1318 inline weak_ptr
<_Tp
>& weak_ptr
<_Tp
>::operator=(weak_ptr
const& __r
) _NOEXCEPT
{
1319 weak_ptr(__r
).swap(*this);
1323 template <class _Tp
>
1324 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1325 inline weak_ptr
<_Tp
>& weak_ptr
<_Tp
>::operator=(weak_ptr
<_Yp
> const& __r
) _NOEXCEPT
{
1326 weak_ptr(__r
).swap(*this);
1330 template <class _Tp
>
1331 inline weak_ptr
<_Tp
>& weak_ptr
<_Tp
>::operator=(weak_ptr
&& __r
) _NOEXCEPT
{
1332 weak_ptr(std::move(__r
)).swap(*this);
1336 template <class _Tp
>
1337 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1338 inline weak_ptr
<_Tp
>& weak_ptr
<_Tp
>::operator=(weak_ptr
<_Yp
>&& __r
) _NOEXCEPT
{
1339 weak_ptr(std::move(__r
)).swap(*this);
1343 template <class _Tp
>
1344 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1345 inline weak_ptr
<_Tp
>& weak_ptr
<_Tp
>::operator=(shared_ptr
<_Yp
> const& __r
) _NOEXCEPT
{
1346 weak_ptr(__r
).swap(*this);
1350 template <class _Tp
>
1351 inline void weak_ptr
<_Tp
>::swap(weak_ptr
& __r
) _NOEXCEPT
{
1352 std::swap(__ptr_
, __r
.__ptr_
);
1353 std::swap(__cntrl_
, __r
.__cntrl_
);
1356 template <class _Tp
>
1357 inline _LIBCPP_HIDE_FROM_ABI
void swap(weak_ptr
<_Tp
>& __x
, weak_ptr
<_Tp
>& __y
) _NOEXCEPT
{
1361 template <class _Tp
>
1362 inline void weak_ptr
<_Tp
>::reset() _NOEXCEPT
{
1363 weak_ptr().swap(*this);
1366 template <class _Tp
>
1367 shared_ptr
<_Tp
> weak_ptr
<_Tp
>::lock() const _NOEXCEPT
{
1368 shared_ptr
<_Tp
> __r
;
1369 __r
.__cntrl_
= __cntrl_
? __cntrl_
->lock() : __cntrl_
;
1371 __r
.__ptr_
= __ptr_
;
1375 #if _LIBCPP_STD_VER >= 17
1376 template <class _Tp
= void>
1379 template <class _Tp
>
1383 template <class _Tp
>
1384 struct _LIBCPP_TEMPLATE_VIS owner_less
<shared_ptr
<_Tp
> > : __binary_function
<shared_ptr
<_Tp
>, shared_ptr
<_Tp
>, bool> {
1385 _LIBCPP_HIDE_FROM_ABI
bool operator()(shared_ptr
<_Tp
> const& __x
, shared_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1386 return __x
.owner_before(__y
);
1388 _LIBCPP_HIDE_FROM_ABI
bool operator()(shared_ptr
<_Tp
> const& __x
, weak_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1389 return __x
.owner_before(__y
);
1391 _LIBCPP_HIDE_FROM_ABI
bool operator()(weak_ptr
<_Tp
> const& __x
, shared_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1392 return __x
.owner_before(__y
);
1396 template <class _Tp
>
1397 struct _LIBCPP_TEMPLATE_VIS owner_less
<weak_ptr
<_Tp
> > : __binary_function
<weak_ptr
<_Tp
>, weak_ptr
<_Tp
>, bool> {
1398 _LIBCPP_HIDE_FROM_ABI
bool operator()(weak_ptr
<_Tp
> const& __x
, weak_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1399 return __x
.owner_before(__y
);
1401 _LIBCPP_HIDE_FROM_ABI
bool operator()(shared_ptr
<_Tp
> const& __x
, weak_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1402 return __x
.owner_before(__y
);
1404 _LIBCPP_HIDE_FROM_ABI
bool operator()(weak_ptr
<_Tp
> const& __x
, shared_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1405 return __x
.owner_before(__y
);
1409 #if _LIBCPP_STD_VER >= 17
1411 struct _LIBCPP_TEMPLATE_VIS owner_less
<void> {
1412 template <class _Tp
, class _Up
>
1413 _LIBCPP_HIDE_FROM_ABI
bool operator()(shared_ptr
<_Tp
> const& __x
, shared_ptr
<_Up
> const& __y
) const _NOEXCEPT
{
1414 return __x
.owner_before(__y
);
1416 template <class _Tp
, class _Up
>
1417 _LIBCPP_HIDE_FROM_ABI
bool operator()(shared_ptr
<_Tp
> const& __x
, weak_ptr
<_Up
> const& __y
) const _NOEXCEPT
{
1418 return __x
.owner_before(__y
);
1420 template <class _Tp
, class _Up
>
1421 _LIBCPP_HIDE_FROM_ABI
bool operator()(weak_ptr
<_Tp
> const& __x
, shared_ptr
<_Up
> const& __y
) const _NOEXCEPT
{
1422 return __x
.owner_before(__y
);
1424 template <class _Tp
, class _Up
>
1425 _LIBCPP_HIDE_FROM_ABI
bool operator()(weak_ptr
<_Tp
> const& __x
, weak_ptr
<_Up
> const& __y
) const _NOEXCEPT
{
1426 return __x
.owner_before(__y
);
1428 typedef void is_transparent
;
1432 template <class _Tp
>
1433 class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
{
1434 mutable weak_ptr
<_Tp
> __weak_this_
;
1437 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
enable_shared_from_this() _NOEXCEPT
{}
1438 _LIBCPP_HIDE_FROM_ABI
enable_shared_from_this(enable_shared_from_this
const&) _NOEXCEPT
{}
1439 _LIBCPP_HIDE_FROM_ABI enable_shared_from_this
& operator=(enable_shared_from_this
const&) _NOEXCEPT
{ return *this; }
1440 _LIBCPP_HIDE_FROM_ABI
~enable_shared_from_this() {}
1443 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> shared_from_this() { return shared_ptr
<_Tp
>(__weak_this_
); }
1444 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
const> shared_from_this() const { return shared_ptr
<const _Tp
>(__weak_this_
); }
1446 #if _LIBCPP_STD_VER >= 17
1447 _LIBCPP_HIDE_FROM_ABI weak_ptr
<_Tp
> weak_from_this() _NOEXCEPT
{ return __weak_this_
; }
1449 _LIBCPP_HIDE_FROM_ABI weak_ptr
<const _Tp
> weak_from_this() const _NOEXCEPT
{ return __weak_this_
; }
1450 #endif // _LIBCPP_STD_VER >= 17
1452 template <class _Up
>
1453 friend class shared_ptr
;
1456 template <class _Tp
>
1457 struct _LIBCPP_TEMPLATE_VIS hash
;
1459 template <class _Tp
>
1460 struct _LIBCPP_TEMPLATE_VIS hash
<shared_ptr
<_Tp
> > {
1461 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1462 _LIBCPP_DEPRECATED_IN_CXX17
typedef shared_ptr
<_Tp
> argument_type
;
1463 _LIBCPP_DEPRECATED_IN_CXX17
typedef size_t result_type
;
1466 _LIBCPP_HIDE_FROM_ABI
size_t operator()(const shared_ptr
<_Tp
>& __ptr
) const _NOEXCEPT
{
1467 return hash
<typename shared_ptr
<_Tp
>::element_type
*>()(__ptr
.get());
1471 template <class _CharT
, class _Traits
, class _Yp
>
1472 inline _LIBCPP_HIDE_FROM_ABI basic_ostream
<_CharT
, _Traits
>&
1473 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
, shared_ptr
<_Yp
> const& __p
);
1475 #if _LIBCPP_HAS_THREADS
1477 class _LIBCPP_EXPORTED_FROM_ABI __sp_mut
{
1481 void lock() _NOEXCEPT
;
1482 void unlock() _NOEXCEPT
;
1485 _LIBCPP_CONSTEXPR
__sp_mut(void*) _NOEXCEPT
;
1486 __sp_mut(const __sp_mut
&);
1487 __sp_mut
& operator=(const __sp_mut
&);
1489 friend _LIBCPP_EXPORTED_FROM_ABI __sp_mut
& __get_sp_mut(const void*);
1492 _LIBCPP_EXPORTED_FROM_ABI __sp_mut
& __get_sp_mut(const void*);
1494 template <class _Tp
>
1495 inline _LIBCPP_HIDE_FROM_ABI
bool atomic_is_lock_free(const shared_ptr
<_Tp
>*) {
1499 template <class _Tp
>
1500 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> atomic_load(const shared_ptr
<_Tp
>* __p
) {
1501 __sp_mut
& __m
= std::__get_sp_mut(__p
);
1503 shared_ptr
<_Tp
> __q
= *__p
;
1508 template <class _Tp
>
1509 inline _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> atomic_load_explicit(const shared_ptr
<_Tp
>* __p
, memory_order
) {
1510 return std::atomic_load(__p
);
1513 template <class _Tp
>
1514 _LIBCPP_HIDE_FROM_ABI
void atomic_store(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
) {
1515 __sp_mut
& __m
= std::__get_sp_mut(__p
);
1521 template <class _Tp
>
1522 inline _LIBCPP_HIDE_FROM_ABI
void atomic_store_explicit(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
, memory_order
) {
1523 std::atomic_store(__p
, __r
);
1526 template <class _Tp
>
1527 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> atomic_exchange(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
) {
1528 __sp_mut
& __m
= std::__get_sp_mut(__p
);
1535 template <class _Tp
>
1536 inline _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>
1537 atomic_exchange_explicit(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
, memory_order
) {
1538 return std::atomic_exchange(__p
, __r
);
1541 template <class _Tp
>
1542 _LIBCPP_HIDE_FROM_ABI
bool
1543 atomic_compare_exchange_strong(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
, shared_ptr
<_Tp
> __w
) {
1544 shared_ptr
<_Tp
> __temp
;
1545 __sp_mut
& __m
= std::__get_sp_mut(__p
);
1547 if (__p
->__owner_equivalent(*__v
)) {
1548 std::swap(__temp
, *__p
);
1553 std::swap(__temp
, *__v
);
1559 template <class _Tp
>
1560 inline _LIBCPP_HIDE_FROM_ABI
bool
1561 atomic_compare_exchange_weak(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
, shared_ptr
<_Tp
> __w
) {
1562 return std::atomic_compare_exchange_strong(__p
, __v
, __w
);
1565 template <class _Tp
>
1566 inline _LIBCPP_HIDE_FROM_ABI
bool atomic_compare_exchange_strong_explicit(
1567 shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
, shared_ptr
<_Tp
> __w
, memory_order
, memory_order
) {
1568 return std::atomic_compare_exchange_strong(__p
, __v
, __w
);
1571 template <class _Tp
>
1572 inline _LIBCPP_HIDE_FROM_ABI
bool atomic_compare_exchange_weak_explicit(
1573 shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
, shared_ptr
<_Tp
> __w
, memory_order
, memory_order
) {
1574 return std::atomic_compare_exchange_weak(__p
, __v
, __w
);
1577 #endif // _LIBCPP_HAS_THREADS
1579 _LIBCPP_END_NAMESPACE_STD
1583 #endif // _LIBCPP___MEMORY_SHARED_PTR_H