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 <__availability>
14 #include <__compare/compare_three_way.h>
15 #include <__compare/ordering.h>
17 #include <__exception/exception.h>
18 #include <__functional/binary_function.h>
19 #include <__functional/operations.h>
20 #include <__functional/reference_wrapper.h>
21 #include <__fwd/ostream.h>
22 #include <__iterator/access.h>
23 #include <__memory/addressof.h>
24 #include <__memory/allocation_guard.h>
25 #include <__memory/allocator.h>
26 #include <__memory/allocator_destructor.h>
27 #include <__memory/allocator_traits.h>
28 #include <__memory/auto_ptr.h>
29 #include <__memory/compressed_pair.h>
30 #include <__memory/construct_at.h>
31 #include <__memory/pointer_traits.h>
32 #include <__memory/uninitialized_algorithms.h>
33 #include <__memory/unique_ptr.h>
34 #include <__type_traits/add_lvalue_reference.h>
35 #include <__type_traits/conditional.h>
36 #include <__type_traits/conjunction.h>
37 #include <__type_traits/disjunction.h>
38 #include <__type_traits/is_array.h>
39 #include <__type_traits/is_bounded_array.h>
40 #include <__type_traits/is_convertible.h>
41 #include <__type_traits/is_move_constructible.h>
42 #include <__type_traits/is_reference.h>
43 #include <__type_traits/is_unbounded_array.h>
44 #include <__type_traits/nat.h>
45 #include <__type_traits/negation.h>
46 #include <__type_traits/remove_extent.h>
47 #include <__type_traits/remove_reference.h>
48 #include <__utility/declval.h>
49 #include <__utility/forward.h>
50 #include <__utility/move.h>
51 #include <__utility/swap.h>
52 #include <__verbose_abort>
56 #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
57 # include <__atomic/memory_order.h>
60 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
61 # pragma GCC system_header
64 _LIBCPP_BEGIN_NAMESPACE_STD
66 // NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
67 // should be sufficient for thread safety.
68 // See https://llvm.org/PR22803
69 #if defined(__clang__) && __has_builtin(__atomic_add_fetch) \
70 && defined(__ATOMIC_RELAXED) \
71 && defined(__ATOMIC_ACQ_REL)
72 # define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
73 #elif defined(_LIBCPP_COMPILER_GCC)
74 # define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
77 template <class _ValueType
>
78 inline _LIBCPP_INLINE_VISIBILITY
79 _ValueType
__libcpp_relaxed_load(_ValueType
const* __value
) {
80 #if !defined(_LIBCPP_HAS_NO_THREADS) && \
81 defined(__ATOMIC_RELAXED) && \
82 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
83 return __atomic_load_n(__value
, __ATOMIC_RELAXED
);
89 template <class _ValueType
>
90 inline _LIBCPP_INLINE_VISIBILITY
91 _ValueType
__libcpp_acquire_load(_ValueType
const* __value
) {
92 #if !defined(_LIBCPP_HAS_NO_THREADS) && \
93 defined(__ATOMIC_ACQUIRE) && \
94 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
95 return __atomic_load_n(__value
, __ATOMIC_ACQUIRE
);
102 inline _LIBCPP_INLINE_VISIBILITY _Tp
103 __libcpp_atomic_refcount_increment(_Tp
& __t
) _NOEXCEPT
105 #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
106 return __atomic_add_fetch(&__t
, 1, __ATOMIC_RELAXED
);
113 inline _LIBCPP_INLINE_VISIBILITY _Tp
114 __libcpp_atomic_refcount_decrement(_Tp
& __t
) _NOEXCEPT
116 #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
117 return __atomic_add_fetch(&__t
, -1, __ATOMIC_ACQ_REL
);
123 class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr
124 : public std::exception
127 _LIBCPP_HIDE_FROM_ABI
bad_weak_ptr() _NOEXCEPT
= default;
128 _LIBCPP_HIDE_FROM_ABI
bad_weak_ptr(const bad_weak_ptr
&) _NOEXCEPT
= default;
129 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr
& operator=(const bad_weak_ptr
&) _NOEXCEPT
= default;
130 ~bad_weak_ptr() _NOEXCEPT override
;
131 const char* what() const _NOEXCEPT override
;
134 _LIBCPP_NORETURN
inline _LIBCPP_INLINE_VISIBILITY
135 void __throw_bad_weak_ptr()
137 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
138 throw bad_weak_ptr();
140 _LIBCPP_VERBOSE_ABORT("bad_weak_ptr was thrown in -fno-exceptions mode");
144 template<class _Tp
> class _LIBCPP_TEMPLATE_VIS weak_ptr
;
146 class _LIBCPP_EXPORTED_FROM_ABI __shared_count
148 __shared_count(const __shared_count
&);
149 __shared_count
& operator=(const __shared_count
&);
152 long __shared_owners_
;
153 virtual ~__shared_count();
155 virtual void __on_zero_shared() _NOEXCEPT
= 0;
158 _LIBCPP_INLINE_VISIBILITY
159 explicit __shared_count(long __refs
= 0) _NOEXCEPT
160 : __shared_owners_(__refs
) {}
162 #if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
163 void __add_shared() noexcept
;
164 bool __release_shared() noexcept
;
166 _LIBCPP_INLINE_VISIBILITY
167 void __add_shared() _NOEXCEPT
{
168 __libcpp_atomic_refcount_increment(__shared_owners_
);
170 _LIBCPP_INLINE_VISIBILITY
171 bool __release_shared() _NOEXCEPT
{
172 if (__libcpp_atomic_refcount_decrement(__shared_owners_
) == -1) {
179 _LIBCPP_INLINE_VISIBILITY
180 long use_count() const _NOEXCEPT
{
181 return __libcpp_relaxed_load(&__shared_owners_
) + 1;
185 class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count
186 : private __shared_count
188 long __shared_weak_owners_
;
191 _LIBCPP_INLINE_VISIBILITY
192 explicit __shared_weak_count(long __refs
= 0) _NOEXCEPT
193 : __shared_count(__refs
),
194 __shared_weak_owners_(__refs
) {}
196 ~__shared_weak_count() override
;
199 #if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
200 void __add_shared() noexcept
;
201 void __add_weak() noexcept
;
202 void __release_shared() noexcept
;
204 _LIBCPP_INLINE_VISIBILITY
205 void __add_shared() _NOEXCEPT
{
206 __shared_count::__add_shared();
208 _LIBCPP_INLINE_VISIBILITY
209 void __add_weak() _NOEXCEPT
{
210 __libcpp_atomic_refcount_increment(__shared_weak_owners_
);
212 _LIBCPP_INLINE_VISIBILITY
213 void __release_shared() _NOEXCEPT
{
214 if (__shared_count::__release_shared())
218 void __release_weak() _NOEXCEPT
;
219 _LIBCPP_INLINE_VISIBILITY
220 long use_count() const _NOEXCEPT
{return __shared_count::use_count();}
221 __shared_weak_count
* lock() _NOEXCEPT
;
223 virtual const void* __get_deleter(const type_info
&) const _NOEXCEPT
;
225 virtual void __on_zero_shared_weak() _NOEXCEPT
= 0;
228 template <class _Tp
, class _Dp
, class _Alloc
>
229 class __shared_ptr_pointer
230 : public __shared_weak_count
232 __compressed_pair
<__compressed_pair
<_Tp
, _Dp
>, _Alloc
> __data_
;
234 _LIBCPP_INLINE_VISIBILITY
235 __shared_ptr_pointer(_Tp __p
, _Dp __d
, _Alloc __a
)
236 : __data_(__compressed_pair
<_Tp
, _Dp
>(__p
, _VSTD::move(__d
)), _VSTD::move(__a
)) {}
238 #ifndef _LIBCPP_HAS_NO_RTTI
239 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
const void* __get_deleter(const type_info
&) const _NOEXCEPT override
;
243 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
;
244 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
;
247 #ifndef _LIBCPP_HAS_NO_RTTI
249 template <class _Tp
, class _Dp
, class _Alloc
>
251 __shared_ptr_pointer
<_Tp
, _Dp
, _Alloc
>::__get_deleter(const type_info
& __t
) const _NOEXCEPT
253 return __t
== typeid(_Dp
) ? _VSTD::addressof(__data_
.first().second()) : nullptr;
256 #endif // _LIBCPP_HAS_NO_RTTI
258 template <class _Tp
, class _Dp
, class _Alloc
>
260 __shared_ptr_pointer
<_Tp
, _Dp
, _Alloc
>::__on_zero_shared() _NOEXCEPT
262 __data_
.first().second()(__data_
.first().first());
263 __data_
.first().second().~_Dp();
266 template <class _Tp
, class _Dp
, class _Alloc
>
268 __shared_ptr_pointer
<_Tp
, _Dp
, _Alloc
>::__on_zero_shared_weak() _NOEXCEPT
270 typedef typename __allocator_traits_rebind
<_Alloc
, __shared_ptr_pointer
>::type _Al
;
271 typedef allocator_traits
<_Al
> _ATraits
;
272 typedef pointer_traits
<typename
_ATraits::pointer
> _PTraits
;
274 _Al
__a(__data_
.second());
275 __data_
.second().~_Alloc();
276 __a
.deallocate(_PTraits::pointer_to(*this), 1);
279 // This tag is used to instantiate an allocator type. The various shared_ptr control blocks
280 // detect that the allocator has been instantiated for this type and perform alternative
281 // initialization/destruction based on that.
282 struct __for_overwrite_tag
{};
284 template <class _Tp
, class _Alloc
>
285 struct __shared_ptr_emplace
286 : __shared_weak_count
288 template <class... _Args
, class _Allocator
= _Alloc
, __enable_if_t
<is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
289 _LIBCPP_HIDE_FROM_ABI
290 explicit __shared_ptr_emplace(_Alloc __a
, _Args
&& ...)
291 : __storage_(_VSTD::move(__a
))
293 static_assert(sizeof...(_Args
) == 0, "No argument should be provided to the control block when using _for_overwrite");
294 ::new ((void*)__get_elem()) _Tp
;
297 template <class... _Args
, class _Allocator
= _Alloc
, __enable_if_t
<!is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
298 _LIBCPP_HIDE_FROM_ABI
299 explicit __shared_ptr_emplace(_Alloc __a
, _Args
&& ...__args
)
300 : __storage_(_VSTD::move(__a
))
302 using _TpAlloc
= typename __allocator_traits_rebind
<_Alloc
, _Tp
>::type
;
303 _TpAlloc
__tmp(*__get_alloc());
304 allocator_traits
<_TpAlloc
>::construct(__tmp
, __get_elem(), _VSTD::forward
<_Args
>(__args
)...);
307 _LIBCPP_HIDE_FROM_ABI
308 _Alloc
* __get_alloc() _NOEXCEPT
{ return __storage_
.__get_alloc(); }
310 _LIBCPP_HIDE_FROM_ABI
311 _Tp
* __get_elem() _NOEXCEPT
{ return __storage_
.__get_elem(); }
314 template <class _Allocator
= _Alloc
, __enable_if_t
<is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
315 _LIBCPP_HIDE_FROM_ABI
void __on_zero_shared_impl() _NOEXCEPT
{
316 __get_elem()->~_Tp();
319 template <class _Allocator
= _Alloc
, __enable_if_t
<!is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
320 _LIBCPP_HIDE_FROM_ABI
void __on_zero_shared_impl() _NOEXCEPT
{
321 using _TpAlloc
= typename __allocator_traits_rebind
<_Allocator
, _Tp
>::type
;
322 _TpAlloc
__tmp(*__get_alloc());
323 allocator_traits
<_TpAlloc
>::destroy(__tmp
, __get_elem());
326 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
{
327 __on_zero_shared_impl();
330 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
{
331 using _ControlBlockAlloc
= typename __allocator_traits_rebind
<_Alloc
, __shared_ptr_emplace
>::type
;
332 using _ControlBlockPointer
= typename allocator_traits
<_ControlBlockAlloc
>::pointer
;
333 _ControlBlockAlloc
__tmp(*__get_alloc());
334 __storage_
.~_Storage();
335 allocator_traits
<_ControlBlockAlloc
>::deallocate(__tmp
,
336 pointer_traits
<_ControlBlockPointer
>::pointer_to(*this), 1);
339 // This class implements the control block for non-array shared pointers created
340 // through `std::allocate_shared` and `std::make_shared`.
342 // In previous versions of the library, we used a compressed pair to store
343 // both the _Alloc and the _Tp. This implies using EBO, which is incompatible
344 // with Allocator construction for _Tp. To allow implementing P0674 in C++20,
345 // we now use a properly aligned char buffer while making sure that we maintain
346 // the same layout that we had when we used a compressed pair.
347 using _CompressedPair
= __compressed_pair
<_Alloc
, _Tp
>;
348 struct _ALIGNAS_TYPE(_CompressedPair
) _Storage
{
349 char __blob_
[sizeof(_CompressedPair
)];
351 _LIBCPP_HIDE_FROM_ABI
explicit _Storage(_Alloc
&& __a
) {
352 ::new ((void*)__get_alloc()) _Alloc(_VSTD::move(__a
));
354 _LIBCPP_HIDE_FROM_ABI
~_Storage() {
355 __get_alloc()->~_Alloc();
357 _LIBCPP_HIDE_FROM_ABI _Alloc
* __get_alloc() _NOEXCEPT
{
358 _CompressedPair
*__as_pair
= reinterpret_cast<_CompressedPair
*>(__blob_
);
359 typename
_CompressedPair::_Base1
* __first
= _CompressedPair::__get_first_base(__as_pair
);
360 _Alloc
*__alloc
= reinterpret_cast<_Alloc
*>(__first
);
363 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp
* __get_elem() _NOEXCEPT
{
364 _CompressedPair
*__as_pair
= reinterpret_cast<_CompressedPair
*>(__blob_
);
365 typename
_CompressedPair::_Base2
* __second
= _CompressedPair::__get_second_base(__as_pair
);
366 _Tp
*__elem
= reinterpret_cast<_Tp
*>(__second
);
371 static_assert(_LIBCPP_ALIGNOF(_Storage
) == _LIBCPP_ALIGNOF(_CompressedPair
), "");
372 static_assert(sizeof(_Storage
) == sizeof(_CompressedPair
), "");
376 struct __shared_ptr_dummy_rebind_allocator_type
;
378 class _LIBCPP_TEMPLATE_VIS allocator
<__shared_ptr_dummy_rebind_allocator_type
>
381 template <class _Other
>
384 typedef allocator
<_Other
> other
;
388 template<class _Tp
> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
;
390 // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.general-6
391 // A pointer type Y* is said to be compatible with a pointer type T*
392 // when either Y* is convertible to T* or Y is U[N] and T is cv U[].
393 #if _LIBCPP_STD_VER >= 17
394 template <class _Yp
, class _Tp
>
395 struct __bounded_convertible_to_unbounded
: false_type
{};
397 template <class _Up
, std::size_t _Np
, class _Tp
>
398 struct __bounded_convertible_to_unbounded
<_Up
[_Np
], _Tp
>
399 : is_same
<__remove_cv_t
<_Tp
>, _Up
[]> {};
401 template <class _Yp
, class _Tp
>
402 struct __compatible_with
404 is_convertible
<_Yp
*, _Tp
*>,
405 __bounded_convertible_to_unbounded
<_Yp
, _Tp
>
408 template <class _Yp
, class _Tp
>
409 struct __compatible_with
410 : is_convertible
<_Yp
*, _Tp
*> {};
411 #endif // _LIBCPP_STD_VER >= 17
413 // Constructors that take raw pointers have a different set of "compatible" constraints
414 // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.const-9.1
415 // - If T is an array type, then either T is U[N] and Y(*)[N] is convertible to T*,
416 // or T is U[] and Y(*)[] is convertible to T*.
417 // - If T is not an array type, then Y* is convertible to T*.
418 #if _LIBCPP_STD_VER >= 17
419 template <class _Yp
, class _Tp
, class = void>
420 struct __raw_pointer_compatible_with
: _And
<
422 is_convertible
<_Yp
*, _Tp
*>
425 template <class _Yp
, class _Up
, std::size_t _Np
>
426 struct __raw_pointer_compatible_with
<_Yp
, _Up
[_Np
], __enable_if_t
<
427 is_convertible
<_Yp(*)[_Np
], _Up(*)[_Np
]>::value
> >
430 template <class _Yp
, class _Up
>
431 struct __raw_pointer_compatible_with
<_Yp
, _Up
[], __enable_if_t
<
432 is_convertible
<_Yp(*)[], _Up(*)[]>::value
> >
436 template <class _Yp
, class _Tp
>
437 struct __raw_pointer_compatible_with
438 : is_convertible
<_Yp
*, _Tp
*> {};
439 #endif // _LIBCPP_STD_VER >= 17
442 template <class _Ptr
, class = void>
443 struct __is_deletable
: false_type
{ };
444 template <class _Ptr
>
445 struct __is_deletable
<_Ptr
, decltype(delete std::declval
<_Ptr
>())> : true_type
{ };
447 template <class _Ptr
, class = void>
448 struct __is_array_deletable
: false_type
{ };
449 template <class _Ptr
>
450 struct __is_array_deletable
<_Ptr
, decltype(delete[] std::declval
<_Ptr
>())> : true_type
{ };
452 template <class _Dp
, class _Pt
,
453 class = decltype(std::declval
<_Dp
>()(std::declval
<_Pt
>()))>
454 true_type
__well_formed_deleter_test(int);
456 template <class, class>
457 false_type
__well_formed_deleter_test(...);
459 template <class _Dp
, class _Pt
>
460 struct __well_formed_deleter
: decltype(std::__well_formed_deleter_test
<_Dp
, _Pt
>(0)) {};
462 template<class _Dp
, class _Yp
, class _Tp
>
463 struct __shared_ptr_deleter_ctor_reqs
465 static const bool value
= __raw_pointer_compatible_with
<_Yp
, _Tp
>::value
&&
466 is_move_constructible
<_Dp
>::value
&&
467 __well_formed_deleter
<_Dp
, _Yp
*>::value
;
470 #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
471 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
473 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
477 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
480 #if _LIBCPP_STD_VER >= 17
481 typedef weak_ptr
<_Tp
> weak_type
;
482 typedef remove_extent_t
<_Tp
> element_type
;
484 typedef _Tp element_type
;
488 element_type
* __ptr_
;
489 __shared_weak_count
* __cntrl_
;
492 _LIBCPP_HIDE_FROM_ABI
493 _LIBCPP_CONSTEXPR
shared_ptr() _NOEXCEPT
498 _LIBCPP_HIDE_FROM_ABI
499 _LIBCPP_CONSTEXPR
shared_ptr(nullptr_t
) _NOEXCEPT
504 template<class _Yp
, class = __enable_if_t
<
506 __raw_pointer_compatible_with
<_Yp
, _Tp
>
507 // In C++03 we get errors when trying to do SFINAE with the
508 // delete operator, so we always pretend that it's deletable.
509 // The same happens on GCC.
510 #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC)
511 , _If
<is_array
<_Tp
>::value
, __is_array_deletable
<_Yp
*>, __is_deletable
<_Yp
*> >
515 _LIBCPP_HIDE_FROM_ABI
explicit shared_ptr(_Yp
* __p
) : __ptr_(__p
) {
516 unique_ptr
<_Yp
> __hold(__p
);
517 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
518 typedef __shared_ptr_pointer
<_Yp
*, __shared_ptr_default_delete
<_Tp
, _Yp
>, _AllocT
> _CntrlBlk
;
519 __cntrl_
= new _CntrlBlk(__p
, __shared_ptr_default_delete
<_Tp
, _Yp
>(), _AllocT());
521 __enable_weak_this(__p
, __p
);
524 template<class _Yp
, class _Dp
, class = __enable_if_t
<__shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
> >
525 _LIBCPP_HIDE_FROM_ABI
526 shared_ptr(_Yp
* __p
, _Dp __d
)
529 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
532 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
533 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
534 typedef __shared_ptr_pointer
<_Yp
*, _Dp
, _AllocT
> _CntrlBlk
;
535 #ifndef _LIBCPP_CXX03_LANG
536 __cntrl_
= new _CntrlBlk(__p
, _VSTD::move(__d
), _AllocT());
538 __cntrl_
= new _CntrlBlk(__p
, __d
, _AllocT());
539 #endif // not _LIBCPP_CXX03_LANG
540 __enable_weak_this(__p
, __p
);
541 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
548 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
551 template<class _Yp
, class _Dp
, class _Alloc
, class = __enable_if_t
<__shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
> >
552 _LIBCPP_HIDE_FROM_ABI
553 shared_ptr(_Yp
* __p
, _Dp __d
, _Alloc __a
)
556 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
559 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
560 typedef __shared_ptr_pointer
<_Yp
*, _Dp
, _Alloc
> _CntrlBlk
;
561 typedef typename __allocator_traits_rebind
<_Alloc
, _CntrlBlk
>::type _A2
;
562 typedef __allocator_destructor
<_A2
> _D2
;
564 unique_ptr
<_CntrlBlk
, _D2
> __hold2(__a2
.allocate(1), _D2(__a2
, 1));
565 ::new ((void*)_VSTD::addressof(*__hold2
.get()))
566 #ifndef _LIBCPP_CXX03_LANG
567 _CntrlBlk(__p
, _VSTD::move(__d
), __a
);
569 _CntrlBlk(__p
, __d
, __a
);
570 #endif // not _LIBCPP_CXX03_LANG
571 __cntrl_
= _VSTD::addressof(*__hold2
.release());
572 __enable_weak_this(__p
, __p
);
573 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
580 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
584 _LIBCPP_HIDE_FROM_ABI
585 shared_ptr(nullptr_t __p
, _Dp __d
)
588 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
591 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
592 typedef typename __shared_ptr_default_allocator
<_Tp
>::type _AllocT
;
593 typedef __shared_ptr_pointer
<nullptr_t
, _Dp
, _AllocT
> _CntrlBlk
;
594 #ifndef _LIBCPP_CXX03_LANG
595 __cntrl_
= new _CntrlBlk(__p
, _VSTD::move(__d
), _AllocT());
597 __cntrl_
= new _CntrlBlk(__p
, __d
, _AllocT());
598 #endif // not _LIBCPP_CXX03_LANG
599 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
606 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
609 template<class _Dp
, class _Alloc
>
610 _LIBCPP_HIDE_FROM_ABI
611 shared_ptr(nullptr_t __p
, _Dp __d
, _Alloc __a
)
614 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
617 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
618 typedef __shared_ptr_pointer
<nullptr_t
, _Dp
, _Alloc
> _CntrlBlk
;
619 typedef typename __allocator_traits_rebind
<_Alloc
, _CntrlBlk
>::type _A2
;
620 typedef __allocator_destructor
<_A2
> _D2
;
622 unique_ptr
<_CntrlBlk
, _D2
> __hold2(__a2
.allocate(1), _D2(__a2
, 1));
623 ::new ((void*)_VSTD::addressof(*__hold2
.get()))
624 #ifndef _LIBCPP_CXX03_LANG
625 _CntrlBlk(__p
, _VSTD::move(__d
), __a
);
627 _CntrlBlk(__p
, __d
, __a
);
628 #endif // not _LIBCPP_CXX03_LANG
629 __cntrl_
= _VSTD::addressof(*__hold2
.release());
630 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
637 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
641 _LIBCPP_HIDE_FROM_ABI
642 shared_ptr(const shared_ptr
<_Yp
>& __r
, element_type
*__p
) _NOEXCEPT
644 __cntrl_(__r
.__cntrl_
)
647 __cntrl_
->__add_shared();
651 // We don't backport because it is an evolutionary change.
652 #if _LIBCPP_STD_VER >= 20
654 _LIBCPP_HIDE_FROM_ABI
shared_ptr(shared_ptr
<_Yp
>&& __r
, element_type
* __p
) noexcept
656 __cntrl_(__r
.__cntrl_
) {
657 __r
.__ptr_
= nullptr;
658 __r
.__cntrl_
= nullptr;
662 _LIBCPP_HIDE_FROM_ABI
663 shared_ptr(const shared_ptr
& __r
) _NOEXCEPT
664 : __ptr_(__r
.__ptr_
),
665 __cntrl_(__r
.__cntrl_
)
668 __cntrl_
->__add_shared();
671 template<class _Yp
, class = __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
> >
672 _LIBCPP_HIDE_FROM_ABI
673 shared_ptr(const shared_ptr
<_Yp
>& __r
) _NOEXCEPT
674 : __ptr_(__r
.__ptr_
),
675 __cntrl_(__r
.__cntrl_
)
678 __cntrl_
->__add_shared();
681 _LIBCPP_HIDE_FROM_ABI
682 shared_ptr(shared_ptr
&& __r
) _NOEXCEPT
683 : __ptr_(__r
.__ptr_
),
684 __cntrl_(__r
.__cntrl_
)
686 __r
.__ptr_
= nullptr;
687 __r
.__cntrl_
= nullptr;
690 template<class _Yp
, class = __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
> >
691 _LIBCPP_HIDE_FROM_ABI
692 shared_ptr(shared_ptr
<_Yp
>&& __r
) _NOEXCEPT
693 : __ptr_(__r
.__ptr_
),
694 __cntrl_(__r
.__cntrl_
)
696 __r
.__ptr_
= nullptr;
697 __r
.__cntrl_
= nullptr;
700 template<class _Yp
, class = __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
> >
701 _LIBCPP_HIDE_FROM_ABI
702 explicit shared_ptr(const weak_ptr
<_Yp
>& __r
)
703 : __ptr_(__r
.__ptr_
),
704 __cntrl_(__r
.__cntrl_
? __r
.__cntrl_
->lock() : __r
.__cntrl_
)
706 if (__cntrl_
== nullptr)
707 __throw_bad_weak_ptr();
710 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
711 template<class _Yp
, class = __enable_if_t
<is_convertible
<_Yp
*, element_type
*>::value
> >
712 _LIBCPP_HIDE_FROM_ABI
713 shared_ptr(auto_ptr
<_Yp
>&& __r
)
716 typedef __shared_ptr_pointer
<_Yp
*, default_delete
<_Yp
>, allocator
<_Yp
> > _CntrlBlk
;
717 __cntrl_
= new _CntrlBlk(__r
.get(), default_delete
<_Yp
>(), allocator
<_Yp
>());
718 __enable_weak_this(__r
.get(), __r
.get());
723 template <class _Yp
, class _Dp
, class = __enable_if_t
<
724 !is_lvalue_reference
<_Dp
>::value
&&
725 __compatible_with
<_Yp
, _Tp
>::value
&&
726 is_convertible
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, element_type
*>::value
728 _LIBCPP_HIDE_FROM_ABI
729 shared_ptr(unique_ptr
<_Yp
, _Dp
>&& __r
)
732 #if _LIBCPP_STD_VER >= 14
733 if (__ptr_
== nullptr)
738 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
739 typedef __shared_ptr_pointer
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, _Dp
, _AllocT
> _CntrlBlk
;
740 __cntrl_
= new _CntrlBlk(__r
.get(), std::move(__r
.get_deleter()), _AllocT());
741 __enable_weak_this(__r
.get(), __r
.get());
746 template <class _Yp
, class _Dp
, class = void, class = __enable_if_t
<
747 is_lvalue_reference
<_Dp
>::value
&&
748 __compatible_with
<_Yp
, _Tp
>::value
&&
749 is_convertible
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, element_type
*>::value
751 _LIBCPP_HIDE_FROM_ABI
752 shared_ptr(unique_ptr
<_Yp
, _Dp
>&& __r
)
755 #if _LIBCPP_STD_VER >= 14
756 if (__ptr_
== nullptr)
761 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
762 typedef __shared_ptr_pointer
<typename unique_ptr
<_Yp
, _Dp
>::pointer
,
763 reference_wrapper
<__libcpp_remove_reference_t
<_Dp
> >,
765 __cntrl_
= new _CntrlBlk(__r
.get(), _VSTD::ref(__r
.get_deleter()), _AllocT());
766 __enable_weak_this(__r
.get(), __r
.get());
771 _LIBCPP_HIDE_FROM_ABI
775 __cntrl_
->__release_shared();
778 _LIBCPP_HIDE_FROM_ABI
779 shared_ptr
<_Tp
>& operator=(const shared_ptr
& __r
) _NOEXCEPT
781 shared_ptr(__r
).swap(*this);
785 template<class _Yp
, class = __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
> >
786 _LIBCPP_HIDE_FROM_ABI
787 shared_ptr
<_Tp
>& operator=(const shared_ptr
<_Yp
>& __r
) _NOEXCEPT
789 shared_ptr(__r
).swap(*this);
793 _LIBCPP_HIDE_FROM_ABI
794 shared_ptr
<_Tp
>& operator=(shared_ptr
&& __r
) _NOEXCEPT
796 shared_ptr(_VSTD::move(__r
)).swap(*this);
800 template<class _Yp
, class = __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
> >
801 _LIBCPP_HIDE_FROM_ABI
802 shared_ptr
<_Tp
>& operator=(shared_ptr
<_Yp
>&& __r
)
804 shared_ptr(_VSTD::move(__r
)).swap(*this);
808 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
809 template<class _Yp
, class = __enable_if_t
<
810 !is_array
<_Yp
>::value
&&
811 is_convertible
<_Yp
*, typename shared_ptr
<_Tp
>::element_type
*>::value
813 _LIBCPP_HIDE_FROM_ABI
814 shared_ptr
<_Tp
>& operator=(auto_ptr
<_Yp
>&& __r
)
816 shared_ptr(_VSTD::move(__r
)).swap(*this);
821 template <class _Yp
, class _Dp
, class = __enable_if_t
<_And
<
822 __compatible_with
<_Yp
, _Tp
>,
823 is_convertible
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, element_type
*>
825 _LIBCPP_HIDE_FROM_ABI
826 shared_ptr
<_Tp
>& operator=(unique_ptr
<_Yp
, _Dp
>&& __r
)
828 shared_ptr(_VSTD::move(__r
)).swap(*this);
832 _LIBCPP_HIDE_FROM_ABI
833 void swap(shared_ptr
& __r
) _NOEXCEPT
835 _VSTD::swap(__ptr_
, __r
.__ptr_
);
836 _VSTD::swap(__cntrl_
, __r
.__cntrl_
);
839 _LIBCPP_HIDE_FROM_ABI
840 void reset() _NOEXCEPT
842 shared_ptr().swap(*this);
845 template<class _Yp
, class = __enable_if_t
<
846 __raw_pointer_compatible_with
<_Yp
, _Tp
>::value
848 _LIBCPP_HIDE_FROM_ABI
851 shared_ptr(__p
).swap(*this);
854 template<class _Yp
, class _Dp
, class = __enable_if_t
<
855 __shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
> >
856 _LIBCPP_HIDE_FROM_ABI
857 void reset(_Yp
* __p
, _Dp __d
)
859 shared_ptr(__p
, __d
).swap(*this);
862 template<class _Yp
, class _Dp
, class _Alloc
, class = __enable_if_t
<
863 __shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
> >
864 _LIBCPP_HIDE_FROM_ABI
865 void reset(_Yp
* __p
, _Dp __d
, _Alloc __a
)
867 shared_ptr(__p
, __d
, __a
).swap(*this);
870 _LIBCPP_HIDE_FROM_ABI
871 element_type
* get() const _NOEXCEPT
876 _LIBCPP_HIDE_FROM_ABI
877 __add_lvalue_reference_t
<element_type
> operator*() const _NOEXCEPT
882 _LIBCPP_HIDE_FROM_ABI
883 element_type
* operator->() const _NOEXCEPT
885 static_assert(!is_array
<_Tp
>::value
,
886 "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
890 _LIBCPP_HIDE_FROM_ABI
891 long use_count() const _NOEXCEPT
893 return __cntrl_
? __cntrl_
->use_count() : 0;
896 _LIBCPP_HIDE_FROM_ABI
897 bool unique() const _NOEXCEPT
899 return use_count() == 1;
902 _LIBCPP_HIDE_FROM_ABI
903 explicit operator bool() const _NOEXCEPT
905 return get() != nullptr;
909 _LIBCPP_HIDE_FROM_ABI
910 bool owner_before(shared_ptr
<_Up
> const& __p
) const _NOEXCEPT
912 return __cntrl_
< __p
.__cntrl_
;
916 _LIBCPP_HIDE_FROM_ABI
917 bool owner_before(weak_ptr
<_Up
> const& __p
) const _NOEXCEPT
919 return __cntrl_
< __p
.__cntrl_
;
922 _LIBCPP_HIDE_FROM_ABI
923 bool __owner_equivalent(const shared_ptr
& __p
) const
925 return __cntrl_
== __p
.__cntrl_
;
928 #if _LIBCPP_STD_VER >= 17
929 _LIBCPP_HIDE_FROM_ABI
930 __add_lvalue_reference_t
<element_type
> operator[](ptrdiff_t __i
) const
932 static_assert(is_array
<_Tp
>::value
,
933 "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
938 #ifndef _LIBCPP_HAS_NO_RTTI
940 _LIBCPP_HIDE_FROM_ABI
941 _Dp
* __get_deleter() const _NOEXCEPT
943 return static_cast<_Dp
*>(__cntrl_
944 ? const_cast<void *>(__cntrl_
->__get_deleter(typeid(_Dp
)))
947 #endif // _LIBCPP_HAS_NO_RTTI
949 template<class _Yp
, class _CntrlBlk
>
950 _LIBCPP_HIDE_FROM_ABI
951 static shared_ptr
<_Tp
> __create_with_control_block(_Yp
* __p
, _CntrlBlk
* __cntrl
) _NOEXCEPT
955 __r
.__cntrl_
= __cntrl
;
956 __r
.__enable_weak_this(__r
.__ptr_
, __r
.__ptr_
);
961 template <class _Yp
, bool = is_function
<_Yp
>::value
>
962 struct __shared_ptr_default_allocator
964 typedef allocator
<_Yp
> type
;
968 struct __shared_ptr_default_allocator
<_Yp
, true>
970 typedef allocator
<__shared_ptr_dummy_rebind_allocator_type
> type
;
973 template <class _Yp
, class _OrigPtr
, class = __enable_if_t
<
974 is_convertible
<_OrigPtr
*, const enable_shared_from_this
<_Yp
>*>::value
976 _LIBCPP_HIDE_FROM_ABI
977 void __enable_weak_this(const enable_shared_from_this
<_Yp
>* __e
, _OrigPtr
* __ptr
) _NOEXCEPT
979 typedef __remove_cv_t
<_Yp
> _RawYp
;
980 if (__e
&& __e
->__weak_this_
.expired())
982 __e
->__weak_this_
= shared_ptr
<_RawYp
>(*this,
983 const_cast<_RawYp
*>(static_cast<const _Yp
*>(__ptr
)));
987 _LIBCPP_HIDE_FROM_ABI
void __enable_weak_this(...) _NOEXCEPT
{ }
989 template <class, class _Yp
>
990 struct __shared_ptr_default_delete
991 : default_delete
<_Yp
>
994 template <class _Yp
, class _Un
, size_t _Sz
>
995 struct __shared_ptr_default_delete
<_Yp
[_Sz
], _Un
>
996 : default_delete
<_Yp
[]>
999 template <class _Yp
, class _Un
>
1000 struct __shared_ptr_default_delete
<_Yp
[], _Un
>
1001 : default_delete
<_Yp
[]>
1004 template <class _Up
> friend class _LIBCPP_TEMPLATE_VIS shared_ptr
;
1005 template <class _Up
> friend class _LIBCPP_TEMPLATE_VIS weak_ptr
;
1008 #if _LIBCPP_STD_VER >= 17
1010 shared_ptr(weak_ptr
<_Tp
>) -> shared_ptr
<_Tp
>;
1011 template<class _Tp
, class _Dp
>
1012 shared_ptr(unique_ptr
<_Tp
, _Dp
>) -> shared_ptr
<_Tp
>;
1016 // std::allocate_shared and std::make_shared
1018 template<class _Tp
, class _Alloc
, class ..._Args
, class = __enable_if_t
<!is_array
<_Tp
>::value
> >
1019 _LIBCPP_HIDE_FROM_ABI
1020 shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, _Args
&& ...__args
)
1022 using _ControlBlock
= __shared_ptr_emplace
<_Tp
, _Alloc
>;
1023 using _ControlBlockAllocator
= typename __allocator_traits_rebind
<_Alloc
, _ControlBlock
>::type
;
1024 __allocation_guard
<_ControlBlockAllocator
> __guard(__a
, 1);
1025 ::new ((void*)_VSTD::addressof(*__guard
.__get())) _ControlBlock(__a
, _VSTD::forward
<_Args
>(__args
)...);
1026 auto __control_block
= __guard
.__release_ptr();
1027 return shared_ptr
<_Tp
>::__create_with_control_block((*__control_block
).__get_elem(), _VSTD::addressof(*__control_block
));
1030 template<class _Tp
, class ..._Args
, class = __enable_if_t
<!is_array
<_Tp
>::value
> >
1031 _LIBCPP_HIDE_FROM_ABI
1032 shared_ptr
<_Tp
> make_shared(_Args
&& ...__args
)
1034 return _VSTD::allocate_shared
<_Tp
>(allocator
<_Tp
>(), _VSTD::forward
<_Args
>(__args
)...);
1037 #if _LIBCPP_STD_VER >= 20
1039 template<class _Tp
, class _Alloc
, __enable_if_t
<!is_array
<_Tp
>::value
, int> = 0>
1040 _LIBCPP_HIDE_FROM_ABI
1041 shared_ptr
<_Tp
> allocate_shared_for_overwrite(const _Alloc
& __a
)
1043 using _ForOverwriteAllocator
= __allocator_traits_rebind_t
<_Alloc
, __for_overwrite_tag
>;
1044 _ForOverwriteAllocator
__alloc(__a
);
1045 return std::allocate_shared
<_Tp
>(__alloc
);
1048 template<class _Tp
, __enable_if_t
<!is_array
<_Tp
>::value
, int> = 0>
1049 _LIBCPP_HIDE_FROM_ABI
1050 shared_ptr
<_Tp
> make_shared_for_overwrite()
1052 return std::allocate_shared_for_overwrite
<_Tp
>(allocator
<_Tp
>());
1055 #endif // _LIBCPP_STD_VER >= 20
1057 #if _LIBCPP_STD_VER >= 17
1059 template <size_t _Alignment
>
1060 struct __sp_aligned_storage
{
1061 alignas(_Alignment
) char __storage
[_Alignment
];
1064 template <class _Tp
, class _Alloc
>
1065 struct __unbounded_array_control_block
;
1067 template <class _Tp
, class _Alloc
>
1068 struct __unbounded_array_control_block
<_Tp
[], _Alloc
> : __shared_weak_count
1070 _LIBCPP_HIDE_FROM_ABI
constexpr
1071 _Tp
* __get_data() noexcept
{ return __data_
; }
1073 _LIBCPP_HIDE_FROM_ABI
1074 explicit __unbounded_array_control_block(_Alloc
const& __alloc
, size_t __count
, _Tp
const& __arg
)
1075 : __alloc_(__alloc
), __count_(__count
)
1077 std::__uninitialized_allocator_fill_n_multidimensional(__alloc_
, std::begin(__data_
), __count_
, __arg
);
1080 _LIBCPP_HIDE_FROM_ABI
1081 explicit __unbounded_array_control_block(_Alloc
const& __alloc
, size_t __count
)
1082 : __alloc_(__alloc
), __count_(__count
)
1084 #if _LIBCPP_STD_VER >= 20
1085 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
1086 // We are purposefully not using an allocator-aware default construction because the spec says so.
1087 // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
1088 std::uninitialized_default_construct_n(std::begin(__data_
), __count_
);
1090 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::begin(__data_
), __count_
);
1093 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::begin(__data_
), __count_
);
1097 // Returns the number of bytes required to store a control block followed by the given number
1098 // of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment.
1099 _LIBCPP_HIDE_FROM_ABI
1100 static constexpr size_t __bytes_for(size_t __elements
) {
1101 // When there's 0 elements, the control block alone is enough since it holds one element.
1102 // Otherwise, we allocate one fewer element than requested because the control block already
1103 // holds one. Also, we use the bitwise formula below to ensure that we allocate enough bytes
1104 // for the whole allocation to be a multiple of _Tp's alignment. That formula is taken from [1].
1106 // [1]: https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding
1107 size_t __bytes
= __elements
== 0 ? sizeof(__unbounded_array_control_block
)
1108 : (__elements
- 1) * sizeof(_Tp
) + sizeof(__unbounded_array_control_block
);
1109 constexpr size_t __align
= alignof(_Tp
);
1110 return (__bytes
+ __align
- 1) & ~(__align
- 1);
1113 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
1114 ~__unbounded_array_control_block() override
{ } // can't be `= default` because of the sometimes-non-trivial union member __data_
1117 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
{
1118 #if _LIBCPP_STD_VER >= 20
1119 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
1120 std::__reverse_destroy(__data_
, __data_
+ __count_
);
1122 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
1123 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ __count_
);
1126 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
1127 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ __count_
);
1131 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
{
1132 using _AlignedStorage
= __sp_aligned_storage
<alignof(__unbounded_array_control_block
)>;
1133 using _StorageAlloc
= __allocator_traits_rebind_t
<_Alloc
, _AlignedStorage
>;
1134 using _PointerTraits
= pointer_traits
<typename allocator_traits
<_StorageAlloc
>::pointer
>;
1136 _StorageAlloc
__tmp(__alloc_
);
1138 size_t __size
= __unbounded_array_control_block::__bytes_for(__count_
);
1139 _AlignedStorage
* __storage
= reinterpret_cast<_AlignedStorage
*>(this);
1140 allocator_traits
<_StorageAlloc
>::deallocate(
1141 __tmp
, _PointerTraits::pointer_to(*__storage
), __size
/ sizeof(_AlignedStorage
));
1144 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_
;
1151 template<class _Array
, class _Alloc
, class... _Arg
>
1152 _LIBCPP_HIDE_FROM_ABI
1153 shared_ptr
<_Array
> __allocate_shared_unbounded_array(const _Alloc
& __a
, size_t __n
, _Arg
&& ...__arg
)
1155 static_assert(__libcpp_is_unbounded_array
<_Array
>::value
);
1156 // We compute the number of bytes necessary to hold the control block and the
1157 // array elements. Then, we allocate an array of properly-aligned dummy structs
1158 // large enough to hold the control block and array. This allows shifting the
1159 // burden of aligning memory properly from us to the allocator.
1160 using _ControlBlock
= __unbounded_array_control_block
<_Array
, _Alloc
>;
1161 using _AlignedStorage
= __sp_aligned_storage
<alignof(_ControlBlock
)>;
1162 using _StorageAlloc
= __allocator_traits_rebind_t
<_Alloc
, _AlignedStorage
>;
1163 __allocation_guard
<_StorageAlloc
> __guard(__a
, _ControlBlock::__bytes_for(__n
) / sizeof(_AlignedStorage
));
1164 _ControlBlock
* __control_block
= reinterpret_cast<_ControlBlock
*>(std::addressof(*__guard
.__get()));
1165 std::__construct_at(__control_block
, __a
, __n
, std::forward
<_Arg
>(__arg
)...);
1166 __guard
.__release_ptr();
1167 return shared_ptr
<_Array
>::__create_with_control_block(__control_block
->__get_data(), __control_block
);
1170 template <class _Tp
, class _Alloc
>
1171 struct __bounded_array_control_block
;
1173 template <class _Tp
, size_t _Count
, class _Alloc
>
1174 struct __bounded_array_control_block
<_Tp
[_Count
], _Alloc
>
1175 : __shared_weak_count
1177 _LIBCPP_HIDE_FROM_ABI
constexpr
1178 _Tp
* __get_data() noexcept
{ return __data_
; }
1180 _LIBCPP_HIDE_FROM_ABI
1181 explicit __bounded_array_control_block(_Alloc
const& __alloc
, _Tp
const& __arg
) : __alloc_(__alloc
) {
1182 std::__uninitialized_allocator_fill_n_multidimensional(__alloc_
, std::addressof(__data_
[0]), _Count
, __arg
);
1185 _LIBCPP_HIDE_FROM_ABI
1186 explicit __bounded_array_control_block(_Alloc
const& __alloc
) : __alloc_(__alloc
) {
1187 #if _LIBCPP_STD_VER >= 20
1188 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
1189 // We are purposefully not using an allocator-aware default construction because the spec says so.
1190 // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
1191 std::uninitialized_default_construct_n(std::addressof(__data_
[0]), _Count
);
1193 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::addressof(__data_
[0]), _Count
);
1196 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::addressof(__data_
[0]), _Count
);
1200 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
1201 ~__bounded_array_control_block() override
{ } // can't be `= default` because of the sometimes-non-trivial union member __data_
1204 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
{
1205 #if _LIBCPP_STD_VER >= 20
1206 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
1207 std::__reverse_destroy(__data_
, __data_
+ _Count
);
1209 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
1210 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ _Count
);
1213 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
1214 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ _Count
);
1218 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
{
1219 using _ControlBlockAlloc
= __allocator_traits_rebind_t
<_Alloc
, __bounded_array_control_block
>;
1220 using _PointerTraits
= pointer_traits
<typename allocator_traits
<_ControlBlockAlloc
>::pointer
>;
1222 _ControlBlockAlloc
__tmp(__alloc_
);
1224 allocator_traits
<_ControlBlockAlloc
>::deallocate(__tmp
, _PointerTraits::pointer_to(*this), 1);
1227 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_
;
1229 _Tp __data_
[_Count
];
1233 template<class _Array
, class _Alloc
, class... _Arg
>
1234 _LIBCPP_HIDE_FROM_ABI
1235 shared_ptr
<_Array
> __allocate_shared_bounded_array(const _Alloc
& __a
, _Arg
&& ...__arg
)
1237 static_assert(__libcpp_is_bounded_array
<_Array
>::value
);
1238 using _ControlBlock
= __bounded_array_control_block
<_Array
, _Alloc
>;
1239 using _ControlBlockAlloc
= __allocator_traits_rebind_t
<_Alloc
, _ControlBlock
>;
1241 __allocation_guard
<_ControlBlockAlloc
> __guard(__a
, 1);
1242 _ControlBlock
* __control_block
= reinterpret_cast<_ControlBlock
*>(std::addressof(*__guard
.__get()));
1243 std::__construct_at(__control_block
, __a
, std::forward
<_Arg
>(__arg
)...);
1244 __guard
.__release_ptr();
1245 return shared_ptr
<_Array
>::__create_with_control_block(__control_block
->__get_data(), __control_block
);
1248 #endif // _LIBCPP_STD_VER >= 17
1250 #if _LIBCPP_STD_VER >= 20
1252 // bounded array variants
1253 template<class _Tp
, class _Alloc
, class = __enable_if_t
<is_bounded_array
<_Tp
>::value
>>
1254 _LIBCPP_HIDE_FROM_ABI
1255 shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
)
1257 return std::__allocate_shared_bounded_array
<_Tp
>(__a
);
1260 template<class _Tp
, class _Alloc
, class = __enable_if_t
<is_bounded_array
<_Tp
>::value
>>
1261 _LIBCPP_HIDE_FROM_ABI
1262 shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, const remove_extent_t
<_Tp
>& __u
)
1264 return std::__allocate_shared_bounded_array
<_Tp
>(__a
, __u
);
1267 template<class _Tp
, class _Alloc
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
1268 _LIBCPP_HIDE_FROM_ABI
1269 shared_ptr
<_Tp
> allocate_shared_for_overwrite(const _Alloc
& __a
)
1271 using _ForOverwriteAllocator
= __allocator_traits_rebind_t
<_Alloc
, __for_overwrite_tag
>;
1272 _ForOverwriteAllocator
__alloc(__a
);
1273 return std::__allocate_shared_bounded_array
<_Tp
>(__alloc
);
1276 template<class _Tp
, class = __enable_if_t
<is_bounded_array
<_Tp
>::value
>>
1277 _LIBCPP_HIDE_FROM_ABI
1278 shared_ptr
<_Tp
> make_shared()
1280 return std::__allocate_shared_bounded_array
<_Tp
>(allocator
<_Tp
>());
1283 template<class _Tp
, class = __enable_if_t
<is_bounded_array
<_Tp
>::value
>>
1284 _LIBCPP_HIDE_FROM_ABI
1285 shared_ptr
<_Tp
> make_shared(const remove_extent_t
<_Tp
>& __u
)
1287 return std::__allocate_shared_bounded_array
<_Tp
>(allocator
<_Tp
>(), __u
);
1290 template<class _Tp
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
1291 _LIBCPP_HIDE_FROM_ABI
1292 shared_ptr
<_Tp
> make_shared_for_overwrite()
1294 return std::__allocate_shared_bounded_array
<_Tp
>(allocator
<__for_overwrite_tag
>());
1297 // unbounded array variants
1298 template<class _Tp
, class _Alloc
, class = __enable_if_t
<is_unbounded_array
<_Tp
>::value
>>
1299 _LIBCPP_HIDE_FROM_ABI
1300 shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, size_t __n
)
1302 return std::__allocate_shared_unbounded_array
<_Tp
>(__a
, __n
);
1305 template<class _Tp
, class _Alloc
, class = __enable_if_t
<is_unbounded_array
<_Tp
>::value
>>
1306 _LIBCPP_HIDE_FROM_ABI
1307 shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, size_t __n
, const remove_extent_t
<_Tp
>& __u
)
1309 return std::__allocate_shared_unbounded_array
<_Tp
>(__a
, __n
, __u
);
1312 template<class _Tp
, class _Alloc
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
1313 _LIBCPP_HIDE_FROM_ABI
1314 shared_ptr
<_Tp
> allocate_shared_for_overwrite(const _Alloc
& __a
, size_t __n
)
1316 using _ForOverwriteAllocator
= __allocator_traits_rebind_t
<_Alloc
, __for_overwrite_tag
>;
1317 _ForOverwriteAllocator
__alloc(__a
);
1318 return std::__allocate_shared_unbounded_array
<_Tp
>(__alloc
, __n
);
1321 template<class _Tp
, class = __enable_if_t
<is_unbounded_array
<_Tp
>::value
>>
1322 _LIBCPP_HIDE_FROM_ABI
1323 shared_ptr
<_Tp
> make_shared(size_t __n
)
1325 return std::__allocate_shared_unbounded_array
<_Tp
>(allocator
<_Tp
>(), __n
);
1328 template<class _Tp
, class = __enable_if_t
<is_unbounded_array
<_Tp
>::value
>>
1329 _LIBCPP_HIDE_FROM_ABI
1330 shared_ptr
<_Tp
> make_shared(size_t __n
, const remove_extent_t
<_Tp
>& __u
)
1332 return std::__allocate_shared_unbounded_array
<_Tp
>(allocator
<_Tp
>(), __n
, __u
);
1335 template<class _Tp
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
1336 _LIBCPP_HIDE_FROM_ABI
1337 shared_ptr
<_Tp
> make_shared_for_overwrite(size_t __n
)
1339 return std::__allocate_shared_unbounded_array
<_Tp
>(allocator
<__for_overwrite_tag
>(), __n
);
1342 #endif // _LIBCPP_STD_VER >= 20
1344 template<class _Tp
, class _Up
>
1345 inline _LIBCPP_INLINE_VISIBILITY
1347 operator==(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
1349 return __x
.get() == __y
.get();
1352 #if _LIBCPP_STD_VER <= 17
1354 template<class _Tp
, class _Up
>
1355 inline _LIBCPP_INLINE_VISIBILITY
1357 operator!=(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
1359 return !(__x
== __y
);
1362 template<class _Tp
, class _Up
>
1363 inline _LIBCPP_INLINE_VISIBILITY
1365 operator<(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
1367 #if _LIBCPP_STD_VER <= 11
1368 typedef typename common_type
<_Tp
*, _Up
*>::type _Vp
;
1369 return less
<_Vp
>()(__x
.get(), __y
.get());
1371 return less
<>()(__x
.get(), __y
.get());
1376 template<class _Tp
, class _Up
>
1377 inline _LIBCPP_INLINE_VISIBILITY
1379 operator>(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
1384 template<class _Tp
, class _Up
>
1385 inline _LIBCPP_INLINE_VISIBILITY
1387 operator<=(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
1389 return !(__y
< __x
);
1392 template<class _Tp
, class _Up
>
1393 inline _LIBCPP_INLINE_VISIBILITY
1395 operator>=(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
1397 return !(__x
< __y
);
1400 #endif // _LIBCPP_STD_VER <= 17
1402 #if _LIBCPP_STD_VER >= 20
1403 template<class _Tp
, class _Up
>
1404 _LIBCPP_HIDE_FROM_ABI strong_ordering
1405 operator<=>(shared_ptr
<_Tp
> const& __x
, shared_ptr
<_Up
> const& __y
) noexcept
1407 return compare_three_way()(__x
.get(), __y
.get());
1412 inline _LIBCPP_INLINE_VISIBILITY
1414 operator==(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
1419 #if _LIBCPP_STD_VER <= 17
1422 inline _LIBCPP_INLINE_VISIBILITY
1424 operator==(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
1430 inline _LIBCPP_INLINE_VISIBILITY
1432 operator!=(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
1434 return static_cast<bool>(__x
);
1438 inline _LIBCPP_INLINE_VISIBILITY
1440 operator!=(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
1442 return static_cast<bool>(__x
);
1446 inline _LIBCPP_INLINE_VISIBILITY
1448 operator<(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
1450 return less
<_Tp
*>()(__x
.get(), nullptr);
1454 inline _LIBCPP_INLINE_VISIBILITY
1456 operator<(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
1458 return less
<_Tp
*>()(nullptr, __x
.get());
1462 inline _LIBCPP_INLINE_VISIBILITY
1464 operator>(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
1466 return nullptr < __x
;
1470 inline _LIBCPP_INLINE_VISIBILITY
1472 operator>(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
1474 return __x
< nullptr;
1478 inline _LIBCPP_INLINE_VISIBILITY
1480 operator<=(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
1482 return !(nullptr < __x
);
1486 inline _LIBCPP_INLINE_VISIBILITY
1488 operator<=(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
1490 return !(__x
< nullptr);
1494 inline _LIBCPP_INLINE_VISIBILITY
1496 operator>=(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
1498 return !(__x
< nullptr);
1502 inline _LIBCPP_INLINE_VISIBILITY
1504 operator>=(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
1506 return !(nullptr < __x
);
1509 #endif // _LIBCPP_STD_VER <= 17
1511 #if _LIBCPP_STD_VER >= 20
1513 _LIBCPP_HIDE_FROM_ABI strong_ordering
1514 operator<=>(shared_ptr
<_Tp
> const& __x
, nullptr_t
) noexcept
1516 return compare_three_way()(__x
.get(), static_cast<typename shared_ptr
<_Tp
>::element_type
*>(nullptr));
1521 inline _LIBCPP_INLINE_VISIBILITY
1523 swap(shared_ptr
<_Tp
>& __x
, shared_ptr
<_Tp
>& __y
) _NOEXCEPT
1528 template<class _Tp
, class _Up
>
1529 inline _LIBCPP_INLINE_VISIBILITY
1531 static_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
1533 return shared_ptr
<_Tp
>(__r
,
1535 typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1539 // We don't backport because it is an evolutionary change.
1540 #if _LIBCPP_STD_VER >= 20
1541 template <class _Tp
, class _Up
>
1542 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> static_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1543 return shared_ptr
<_Tp
>(std::move(__r
), static_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1547 template<class _Tp
, class _Up
>
1548 inline _LIBCPP_INLINE_VISIBILITY
1550 dynamic_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
1552 typedef typename shared_ptr
<_Tp
>::element_type _ET
;
1553 _ET
* __p
= dynamic_cast<_ET
*>(__r
.get());
1554 return __p
? shared_ptr
<_Tp
>(__r
, __p
) : shared_ptr
<_Tp
>();
1558 // We don't backport because it is an evolutionary change.
1559 #if _LIBCPP_STD_VER >= 20
1560 template <class _Tp
, class _Up
>
1561 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> dynamic_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1562 auto* __p
= dynamic_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get());
1563 return __p
? shared_ptr
<_Tp
>(std::move(__r
), __p
) : shared_ptr
<_Tp
>();
1567 template<class _Tp
, class _Up
>
1568 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>
1569 const_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
1571 typedef typename shared_ptr
<_Tp
>::element_type _RTp
;
1572 return shared_ptr
<_Tp
>(__r
, const_cast<_RTp
*>(__r
.get()));
1576 // We don't backport because it is an evolutionary change.
1577 #if _LIBCPP_STD_VER >= 20
1578 template <class _Tp
, class _Up
>
1579 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> const_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1580 return shared_ptr
<_Tp
>(std::move(__r
), const_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1584 template<class _Tp
, class _Up
>
1585 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>
1586 reinterpret_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
1588 return shared_ptr
<_Tp
>(__r
,
1590 typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1594 // We don't backport because it is an evolutionary change.
1595 #if _LIBCPP_STD_VER >= 20
1596 template <class _Tp
, class _Up
>
1597 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> reinterpret_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1598 return shared_ptr
<_Tp
>(std::move(__r
), reinterpret_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1602 #ifndef _LIBCPP_HAS_NO_RTTI
1604 template<class _Dp
, class _Tp
>
1605 inline _LIBCPP_INLINE_VISIBILITY
1607 get_deleter(const shared_ptr
<_Tp
>& __p
) _NOEXCEPT
1609 return __p
.template __get_deleter
<_Dp
>();
1612 #endif // _LIBCPP_HAS_NO_RTTI
1615 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
1618 #if _LIBCPP_STD_VER >= 17
1619 typedef remove_extent_t
<_Tp
> element_type
;
1621 typedef _Tp element_type
;
1625 element_type
* __ptr_
;
1626 __shared_weak_count
* __cntrl_
;
1629 _LIBCPP_INLINE_VISIBILITY
1630 _LIBCPP_CONSTEXPR
weak_ptr() _NOEXCEPT
;
1632 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1633 _LIBCPP_INLINE_VISIBILITY
weak_ptr(shared_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1635 _LIBCPP_INLINE_VISIBILITY
1636 weak_ptr(weak_ptr
const& __r
) _NOEXCEPT
;
1638 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1639 _LIBCPP_INLINE_VISIBILITY
weak_ptr(weak_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1641 _LIBCPP_INLINE_VISIBILITY
1642 weak_ptr(weak_ptr
&& __r
) _NOEXCEPT
;
1644 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1645 _LIBCPP_INLINE_VISIBILITY
weak_ptr(weak_ptr
<_Yp
>&& __r
) _NOEXCEPT
;
1647 _LIBCPP_HIDE_FROM_ABI
~weak_ptr();
1649 _LIBCPP_INLINE_VISIBILITY
1650 weak_ptr
& operator=(weak_ptr
const& __r
) _NOEXCEPT
;
1651 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1652 _LIBCPP_INLINE_VISIBILITY weak_ptr
&
1653 operator=(weak_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1655 _LIBCPP_INLINE_VISIBILITY
1656 weak_ptr
& operator=(weak_ptr
&& __r
) _NOEXCEPT
;
1657 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1658 _LIBCPP_INLINE_VISIBILITY weak_ptr
&
1659 operator=(weak_ptr
<_Yp
>&& __r
) _NOEXCEPT
;
1661 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1662 _LIBCPP_INLINE_VISIBILITY weak_ptr
&
1663 operator=(shared_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1665 _LIBCPP_INLINE_VISIBILITY
1666 void swap(weak_ptr
& __r
) _NOEXCEPT
;
1667 _LIBCPP_INLINE_VISIBILITY
1668 void reset() _NOEXCEPT
;
1670 _LIBCPP_INLINE_VISIBILITY
1671 long use_count() const _NOEXCEPT
1672 {return __cntrl_
? __cntrl_
->use_count() : 0;}
1673 _LIBCPP_INLINE_VISIBILITY
1674 bool expired() const _NOEXCEPT
1675 {return __cntrl_
== nullptr || __cntrl_
->use_count() == 0;}
1676 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> lock() const _NOEXCEPT
;
1678 _LIBCPP_INLINE_VISIBILITY
1679 bool owner_before(const shared_ptr
<_Up
>& __r
) const _NOEXCEPT
1680 {return __cntrl_
< __r
.__cntrl_
;}
1682 _LIBCPP_INLINE_VISIBILITY
1683 bool owner_before(const weak_ptr
<_Up
>& __r
) const _NOEXCEPT
1684 {return __cntrl_
< __r
.__cntrl_
;}
1686 template <class _Up
> friend class _LIBCPP_TEMPLATE_VIS weak_ptr
;
1687 template <class _Up
> friend class _LIBCPP_TEMPLATE_VIS shared_ptr
;
1690 #if _LIBCPP_STD_VER >= 17
1692 weak_ptr(shared_ptr
<_Tp
>) -> weak_ptr
<_Tp
>;
1698 weak_ptr
<_Tp
>::weak_ptr() _NOEXCEPT
1706 weak_ptr
<_Tp
>::weak_ptr(weak_ptr
const& __r
) _NOEXCEPT
1707 : __ptr_(__r
.__ptr_
),
1708 __cntrl_(__r
.__cntrl_
)
1711 __cntrl_
->__add_weak();
1715 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1717 weak_ptr
<_Tp
>::weak_ptr(shared_ptr
<_Yp
> const& __r
)
1719 : __ptr_(__r
.__ptr_
),
1720 __cntrl_(__r
.__cntrl_
)
1723 __cntrl_
->__add_weak();
1727 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1729 weak_ptr
<_Tp
>::weak_ptr(weak_ptr
<_Yp
> const& __r
)
1734 shared_ptr
<_Yp
> __s
= __r
.lock();
1735 *this = weak_ptr
<_Tp
>(__s
);
1740 weak_ptr
<_Tp
>::weak_ptr(weak_ptr
&& __r
) _NOEXCEPT
1741 : __ptr_(__r
.__ptr_
),
1742 __cntrl_(__r
.__cntrl_
)
1744 __r
.__ptr_
= nullptr;
1745 __r
.__cntrl_
= nullptr;
1749 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1751 weak_ptr
<_Tp
>::weak_ptr(weak_ptr
<_Yp
>&& __r
)
1756 shared_ptr
<_Yp
> __s
= __r
.lock();
1757 *this = weak_ptr
<_Tp
>(__s
);
1762 weak_ptr
<_Tp
>::~weak_ptr()
1765 __cntrl_
->__release_weak();
1771 weak_ptr
<_Tp
>::operator=(weak_ptr
const& __r
) _NOEXCEPT
1773 weak_ptr(__r
).swap(*this);
1778 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1781 weak_ptr
<_Tp
>::operator=(weak_ptr
<_Yp
> const& __r
) _NOEXCEPT
1783 weak_ptr(__r
).swap(*this);
1790 weak_ptr
<_Tp
>::operator=(weak_ptr
&& __r
) _NOEXCEPT
1792 weak_ptr(_VSTD::move(__r
)).swap(*this);
1797 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1800 weak_ptr
<_Tp
>::operator=(weak_ptr
<_Yp
>&& __r
) _NOEXCEPT
1802 weak_ptr(_VSTD::move(__r
)).swap(*this);
1807 template<class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1810 weak_ptr
<_Tp
>::operator=(shared_ptr
<_Yp
> const& __r
) _NOEXCEPT
1812 weak_ptr(__r
).swap(*this);
1819 weak_ptr
<_Tp
>::swap(weak_ptr
& __r
) _NOEXCEPT
1821 _VSTD::swap(__ptr_
, __r
.__ptr_
);
1822 _VSTD::swap(__cntrl_
, __r
.__cntrl_
);
1826 inline _LIBCPP_INLINE_VISIBILITY
1828 swap(weak_ptr
<_Tp
>& __x
, weak_ptr
<_Tp
>& __y
) _NOEXCEPT
1836 weak_ptr
<_Tp
>::reset() _NOEXCEPT
1838 weak_ptr().swap(*this);
1843 weak_ptr
<_Tp
>::lock() const _NOEXCEPT
1845 shared_ptr
<_Tp
> __r
;
1846 __r
.__cntrl_
= __cntrl_
? __cntrl_
->lock() : __cntrl_
;
1848 __r
.__ptr_
= __ptr_
;
1852 #if _LIBCPP_STD_VER >= 17
1853 template <class _Tp
= void> struct owner_less
;
1855 template <class _Tp
> struct owner_less
;
1859 template <class _Tp
>
1860 struct _LIBCPP_TEMPLATE_VIS owner_less
<shared_ptr
<_Tp
> >
1861 : __binary_function
<shared_ptr
<_Tp
>, shared_ptr
<_Tp
>, bool>
1863 _LIBCPP_INLINE_VISIBILITY
1864 bool operator()(shared_ptr
<_Tp
> const& __x
, shared_ptr
<_Tp
> const& __y
) const _NOEXCEPT
1865 {return __x
.owner_before(__y
);}
1866 _LIBCPP_INLINE_VISIBILITY
1867 bool operator()(shared_ptr
<_Tp
> const& __x
, weak_ptr
<_Tp
> const& __y
) const _NOEXCEPT
1868 {return __x
.owner_before(__y
);}
1869 _LIBCPP_INLINE_VISIBILITY
1870 bool operator()( weak_ptr
<_Tp
> const& __x
, shared_ptr
<_Tp
> const& __y
) const _NOEXCEPT
1871 {return __x
.owner_before(__y
);}
1874 template <class _Tp
>
1875 struct _LIBCPP_TEMPLATE_VIS owner_less
<weak_ptr
<_Tp
> >
1876 : __binary_function
<weak_ptr
<_Tp
>, weak_ptr
<_Tp
>, bool>
1878 _LIBCPP_INLINE_VISIBILITY
1879 bool operator()( weak_ptr
<_Tp
> const& __x
, weak_ptr
<_Tp
> const& __y
) const _NOEXCEPT
1880 {return __x
.owner_before(__y
);}
1881 _LIBCPP_INLINE_VISIBILITY
1882 bool operator()(shared_ptr
<_Tp
> const& __x
, weak_ptr
<_Tp
> const& __y
) const _NOEXCEPT
1883 {return __x
.owner_before(__y
);}
1884 _LIBCPP_INLINE_VISIBILITY
1885 bool operator()( weak_ptr
<_Tp
> const& __x
, shared_ptr
<_Tp
> const& __y
) const _NOEXCEPT
1886 {return __x
.owner_before(__y
);}
1889 #if _LIBCPP_STD_VER >= 17
1891 struct _LIBCPP_TEMPLATE_VIS owner_less
<void>
1893 template <class _Tp
, class _Up
>
1894 _LIBCPP_INLINE_VISIBILITY
1895 bool operator()( shared_ptr
<_Tp
> const& __x
, shared_ptr
<_Up
> const& __y
) const _NOEXCEPT
1896 {return __x
.owner_before(__y
);}
1897 template <class _Tp
, class _Up
>
1898 _LIBCPP_INLINE_VISIBILITY
1899 bool operator()( shared_ptr
<_Tp
> const& __x
, weak_ptr
<_Up
> const& __y
) const _NOEXCEPT
1900 {return __x
.owner_before(__y
);}
1901 template <class _Tp
, class _Up
>
1902 _LIBCPP_INLINE_VISIBILITY
1903 bool operator()( weak_ptr
<_Tp
> const& __x
, shared_ptr
<_Up
> const& __y
) const _NOEXCEPT
1904 {return __x
.owner_before(__y
);}
1905 template <class _Tp
, class _Up
>
1906 _LIBCPP_INLINE_VISIBILITY
1907 bool operator()( weak_ptr
<_Tp
> const& __x
, weak_ptr
<_Up
> const& __y
) const _NOEXCEPT
1908 {return __x
.owner_before(__y
);}
1909 typedef void is_transparent
;
1914 class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
1916 mutable weak_ptr
<_Tp
> __weak_this_
;
1918 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1919 enable_shared_from_this() _NOEXCEPT
{}
1920 _LIBCPP_INLINE_VISIBILITY
1921 enable_shared_from_this(enable_shared_from_this
const&) _NOEXCEPT
{}
1922 _LIBCPP_INLINE_VISIBILITY
1923 enable_shared_from_this
& operator=(enable_shared_from_this
const&) _NOEXCEPT
1925 _LIBCPP_INLINE_VISIBILITY
1926 ~enable_shared_from_this() {}
1928 _LIBCPP_INLINE_VISIBILITY
1929 shared_ptr
<_Tp
> shared_from_this()
1930 {return shared_ptr
<_Tp
>(__weak_this_
);}
1931 _LIBCPP_INLINE_VISIBILITY
1932 shared_ptr
<_Tp
const> shared_from_this() const
1933 {return shared_ptr
<const _Tp
>(__weak_this_
);}
1935 #if _LIBCPP_STD_VER >= 17
1936 _LIBCPP_INLINE_VISIBILITY
1937 weak_ptr
<_Tp
> weak_from_this() _NOEXCEPT
1938 { return __weak_this_
; }
1940 _LIBCPP_INLINE_VISIBILITY
1941 weak_ptr
<const _Tp
> weak_from_this() const _NOEXCEPT
1942 { return __weak_this_
; }
1943 #endif // _LIBCPP_STD_VER >= 17
1945 template <class _Up
> friend class shared_ptr
;
1948 template <class _Tp
> struct _LIBCPP_TEMPLATE_VIS hash
;
1950 template <class _Tp
>
1951 struct _LIBCPP_TEMPLATE_VIS hash
<shared_ptr
<_Tp
> >
1953 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1954 _LIBCPP_DEPRECATED_IN_CXX17
typedef shared_ptr
<_Tp
> argument_type
;
1955 _LIBCPP_DEPRECATED_IN_CXX17
typedef size_t result_type
;
1958 _LIBCPP_INLINE_VISIBILITY
1959 size_t operator()(const shared_ptr
<_Tp
>& __ptr
) const _NOEXCEPT
1961 return hash
<typename shared_ptr
<_Tp
>::element_type
*>()(__ptr
.get());
1965 template<class _CharT
, class _Traits
, class _Yp
>
1966 inline _LIBCPP_INLINE_VISIBILITY
1967 basic_ostream
<_CharT
, _Traits
>&
1968 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
, shared_ptr
<_Yp
> const& __p
);
1971 #if !defined(_LIBCPP_HAS_NO_THREADS)
1973 class _LIBCPP_EXPORTED_FROM_ABI __sp_mut
1977 void lock() _NOEXCEPT
;
1978 void unlock() _NOEXCEPT
;
1981 _LIBCPP_CONSTEXPR
__sp_mut(void*) _NOEXCEPT
;
1982 __sp_mut(const __sp_mut
&);
1983 __sp_mut
& operator=(const __sp_mut
&);
1985 friend _LIBCPP_EXPORTED_FROM_ABI __sp_mut
& __get_sp_mut(const void*);
1988 _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1989 __sp_mut
& __get_sp_mut(const void*);
1991 template <class _Tp
>
1992 inline _LIBCPP_INLINE_VISIBILITY
1994 atomic_is_lock_free(const shared_ptr
<_Tp
>*)
1999 template <class _Tp
>
2000 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2001 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>
2002 atomic_load(const shared_ptr
<_Tp
>* __p
)
2004 __sp_mut
& __m
= std::__get_sp_mut(__p
);
2006 shared_ptr
<_Tp
> __q
= *__p
;
2011 template <class _Tp
>
2012 inline _LIBCPP_INLINE_VISIBILITY
2013 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2015 atomic_load_explicit(const shared_ptr
<_Tp
>* __p
, memory_order
)
2017 return std::atomic_load(__p
);
2020 template <class _Tp
>
2021 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2022 _LIBCPP_HIDE_FROM_ABI
void
2023 atomic_store(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
)
2025 __sp_mut
& __m
= std::__get_sp_mut(__p
);
2031 template <class _Tp
>
2032 inline _LIBCPP_INLINE_VISIBILITY
2033 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2035 atomic_store_explicit(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
, memory_order
)
2037 std::atomic_store(__p
, __r
);
2040 template <class _Tp
>
2041 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2042 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>
2043 atomic_exchange(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
)
2045 __sp_mut
& __m
= std::__get_sp_mut(__p
);
2052 template <class _Tp
>
2053 inline _LIBCPP_INLINE_VISIBILITY
2054 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2056 atomic_exchange_explicit(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
, memory_order
)
2058 return std::atomic_exchange(__p
, __r
);
2061 template <class _Tp
>
2062 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2063 _LIBCPP_HIDE_FROM_ABI
bool
2064 atomic_compare_exchange_strong(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
, shared_ptr
<_Tp
> __w
)
2066 shared_ptr
<_Tp
> __temp
;
2067 __sp_mut
& __m
= std::__get_sp_mut(__p
);
2069 if (__p
->__owner_equivalent(*__v
))
2071 _VSTD::swap(__temp
, *__p
);
2076 _VSTD::swap(__temp
, *__v
);
2082 template <class _Tp
>
2083 inline _LIBCPP_INLINE_VISIBILITY
2084 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2086 atomic_compare_exchange_weak(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
, shared_ptr
<_Tp
> __w
)
2088 return std::atomic_compare_exchange_strong(__p
, __v
, __w
);
2091 template <class _Tp
>
2092 inline _LIBCPP_INLINE_VISIBILITY
2093 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2095 atomic_compare_exchange_strong_explicit(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
,
2096 shared_ptr
<_Tp
> __w
, memory_order
, memory_order
)
2098 return std::atomic_compare_exchange_strong(__p
, __v
, __w
);
2101 template <class _Tp
>
2102 inline _LIBCPP_INLINE_VISIBILITY
2103 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2105 atomic_compare_exchange_weak_explicit(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
,
2106 shared_ptr
<_Tp
> __w
, memory_order
, memory_order
)
2108 return std::atomic_compare_exchange_weak(__p
, __v
, __w
);
2111 #endif // !defined(_LIBCPP_HAS_NO_THREADS)
2113 _LIBCPP_END_NAMESPACE_STD
2115 #endif // _LIBCPP___MEMORY_SHARED_PTR_H