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 <__cxx03/__compare/compare_three_way.h>
14 #include <__cxx03/__compare/ordering.h>
15 #include <__cxx03/__config>
16 #include <__cxx03/__exception/exception.h>
17 #include <__cxx03/__functional/binary_function.h>
18 #include <__cxx03/__functional/operations.h>
19 #include <__cxx03/__functional/reference_wrapper.h>
20 #include <__cxx03/__fwd/ostream.h>
21 #include <__cxx03/__iterator/access.h>
22 #include <__cxx03/__memory/addressof.h>
23 #include <__cxx03/__memory/allocation_guard.h>
24 #include <__cxx03/__memory/allocator.h>
25 #include <__cxx03/__memory/allocator_destructor.h>
26 #include <__cxx03/__memory/allocator_traits.h>
27 #include <__cxx03/__memory/auto_ptr.h>
28 #include <__cxx03/__memory/compressed_pair.h>
29 #include <__cxx03/__memory/construct_at.h>
30 #include <__cxx03/__memory/pointer_traits.h>
31 #include <__cxx03/__memory/uninitialized_algorithms.h>
32 #include <__cxx03/__memory/unique_ptr.h>
33 #include <__cxx03/__type_traits/add_lvalue_reference.h>
34 #include <__cxx03/__type_traits/conditional.h>
35 #include <__cxx03/__type_traits/conjunction.h>
36 #include <__cxx03/__type_traits/disjunction.h>
37 #include <__cxx03/__type_traits/is_array.h>
38 #include <__cxx03/__type_traits/is_bounded_array.h>
39 #include <__cxx03/__type_traits/is_constructible.h>
40 #include <__cxx03/__type_traits/is_convertible.h>
41 #include <__cxx03/__type_traits/is_reference.h>
42 #include <__cxx03/__type_traits/is_unbounded_array.h>
43 #include <__cxx03/__type_traits/nat.h>
44 #include <__cxx03/__type_traits/negation.h>
45 #include <__cxx03/__type_traits/remove_extent.h>
46 #include <__cxx03/__type_traits/remove_reference.h>
47 #include <__cxx03/__utility/declval.h>
48 #include <__cxx03/__utility/forward.h>
49 #include <__cxx03/__utility/move.h>
50 #include <__cxx03/__utility/swap.h>
51 #include <__cxx03/__verbose_abort>
52 #include <__cxx03/cstddef>
53 #include <__cxx03/new>
54 #include <__cxx03/typeinfo>
55 #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
56 # include <__cxx03/__atomic/memory_order.h>
59 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
60 # pragma GCC system_header
64 #include <__cxx03/__undef_macros>
66 _LIBCPP_BEGIN_NAMESPACE_STD
68 // NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
69 // should be sufficient for thread safety.
70 // See https://llvm.org/PR22803
71 #if defined(__clang__) && __has_builtin(__atomic_add_fetch) && defined(__ATOMIC_RELAXED) && 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_HIDE_FROM_ABI _ValueType
__libcpp_relaxed_load(_ValueType
const* __value
) {
79 #if !defined(_LIBCPP_HAS_NO_THREADS) && defined(__ATOMIC_RELAXED) && \
80 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
81 return __atomic_load_n(__value
, __ATOMIC_RELAXED
);
87 template <class _ValueType
>
88 inline _LIBCPP_HIDE_FROM_ABI _ValueType
__libcpp_acquire_load(_ValueType
const* __value
) {
89 #if !defined(_LIBCPP_HAS_NO_THREADS) && defined(__ATOMIC_ACQUIRE) && \
90 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
91 return __atomic_load_n(__value
, __ATOMIC_ACQUIRE
);
98 inline _LIBCPP_HIDE_FROM_ABI _Tp
__libcpp_atomic_refcount_increment(_Tp
& __t
) _NOEXCEPT
{
99 #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
100 return __atomic_add_fetch(&__t
, 1, __ATOMIC_RELAXED
);
107 inline _LIBCPP_HIDE_FROM_ABI _Tp
__libcpp_atomic_refcount_decrement(_Tp
& __t
) _NOEXCEPT
{
108 #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
109 return __atomic_add_fetch(&__t
, -1, __ATOMIC_ACQ_REL
);
115 class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr
: public std::exception
{
117 _LIBCPP_HIDE_FROM_ABI
bad_weak_ptr() _NOEXCEPT
= default;
118 _LIBCPP_HIDE_FROM_ABI
bad_weak_ptr(const bad_weak_ptr
&) _NOEXCEPT
= default;
119 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr
& operator=(const bad_weak_ptr
&) _NOEXCEPT
= default;
120 ~bad_weak_ptr() _NOEXCEPT override
;
121 const char* what() const _NOEXCEPT override
;
124 _LIBCPP_NORETURN
inline _LIBCPP_HIDE_FROM_ABI
void __throw_bad_weak_ptr() {
125 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
126 throw bad_weak_ptr();
128 _LIBCPP_VERBOSE_ABORT("bad_weak_ptr was thrown in -fno-exceptions mode");
133 class _LIBCPP_TEMPLATE_VIS weak_ptr
;
135 class _LIBCPP_EXPORTED_FROM_ABI __shared_count
{
136 __shared_count(const __shared_count
&);
137 __shared_count
& operator=(const __shared_count
&);
140 long __shared_owners_
;
141 virtual ~__shared_count();
144 virtual void __on_zero_shared() _NOEXCEPT
= 0;
147 _LIBCPP_HIDE_FROM_ABI
explicit __shared_count(long __refs
= 0) _NOEXCEPT
: __shared_owners_(__refs
) {}
149 #if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
150 void __add_shared() noexcept
;
151 bool __release_shared() noexcept
;
153 _LIBCPP_HIDE_FROM_ABI
void __add_shared() _NOEXCEPT
{ __libcpp_atomic_refcount_increment(__shared_owners_
); }
154 _LIBCPP_HIDE_FROM_ABI
bool __release_shared() _NOEXCEPT
{
155 if (__libcpp_atomic_refcount_decrement(__shared_owners_
) == -1) {
162 _LIBCPP_HIDE_FROM_ABI
long use_count() const _NOEXCEPT
{ return __libcpp_relaxed_load(&__shared_owners_
) + 1; }
165 class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count
: private __shared_count
{
166 long __shared_weak_owners_
;
169 _LIBCPP_HIDE_FROM_ABI
explicit __shared_weak_count(long __refs
= 0) _NOEXCEPT
170 : __shared_count(__refs
),
171 __shared_weak_owners_(__refs
) {}
174 ~__shared_weak_count() override
;
177 #if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
178 void __add_shared() noexcept
;
179 void __add_weak() noexcept
;
180 void __release_shared() noexcept
;
182 _LIBCPP_HIDE_FROM_ABI
void __add_shared() _NOEXCEPT
{ __shared_count::__add_shared(); }
183 _LIBCPP_HIDE_FROM_ABI
void __add_weak() _NOEXCEPT
{ __libcpp_atomic_refcount_increment(__shared_weak_owners_
); }
184 _LIBCPP_HIDE_FROM_ABI
void __release_shared() _NOEXCEPT
{
185 if (__shared_count::__release_shared())
189 void __release_weak() _NOEXCEPT
;
190 _LIBCPP_HIDE_FROM_ABI
long use_count() const _NOEXCEPT
{ return __shared_count::use_count(); }
191 __shared_weak_count
* lock() _NOEXCEPT
;
193 virtual const void* __get_deleter(const type_info
&) const _NOEXCEPT
;
196 virtual void __on_zero_shared_weak() _NOEXCEPT
= 0;
199 template <class _Tp
, class _Dp
, class _Alloc
>
200 class __shared_ptr_pointer
: public __shared_weak_count
{
201 __compressed_pair
<__compressed_pair
<_Tp
, _Dp
>, _Alloc
> __data_
;
204 _LIBCPP_HIDE_FROM_ABI
__shared_ptr_pointer(_Tp __p
, _Dp __d
, _Alloc __a
)
205 : __data_(__compressed_pair
<_Tp
, _Dp
>(__p
, std::move(__d
)), std::move(__a
)) {}
207 #ifndef _LIBCPP_HAS_NO_RTTI
208 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
const void* __get_deleter(const type_info
&) const _NOEXCEPT override
;
212 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
;
213 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
;
216 #ifndef _LIBCPP_HAS_NO_RTTI
218 template <class _Tp
, class _Dp
, class _Alloc
>
219 const void* __shared_ptr_pointer
<_Tp
, _Dp
, _Alloc
>::__get_deleter(const type_info
& __t
) const _NOEXCEPT
{
220 return __t
== typeid(_Dp
) ? std::addressof(__data_
.first().second()) : nullptr;
223 #endif // _LIBCPP_HAS_NO_RTTI
225 template <class _Tp
, class _Dp
, class _Alloc
>
226 void __shared_ptr_pointer
<_Tp
, _Dp
, _Alloc
>::__on_zero_shared() _NOEXCEPT
{
227 __data_
.first().second()(__data_
.first().first());
228 __data_
.first().second().~_Dp();
231 template <class _Tp
, class _Dp
, class _Alloc
>
232 void __shared_ptr_pointer
<_Tp
, _Dp
, _Alloc
>::__on_zero_shared_weak() _NOEXCEPT
{
233 typedef typename __allocator_traits_rebind
<_Alloc
, __shared_ptr_pointer
>::type _Al
;
234 typedef allocator_traits
<_Al
> _ATraits
;
235 typedef pointer_traits
<typename
_ATraits::pointer
> _PTraits
;
237 _Al
__a(__data_
.second());
238 __data_
.second().~_Alloc();
239 __a
.deallocate(_PTraits::pointer_to(*this), 1);
242 // This tag is used to instantiate an allocator type. The various shared_ptr control blocks
243 // detect that the allocator has been instantiated for this type and perform alternative
244 // initialization/destruction based on that.
245 struct __for_overwrite_tag
{};
247 template <class _Tp
, class _Alloc
>
248 struct __shared_ptr_emplace
: __shared_weak_count
{
249 template <class... _Args
,
250 class _Allocator
= _Alloc
,
251 __enable_if_t
<is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
252 _LIBCPP_HIDE_FROM_ABI
explicit __shared_ptr_emplace(_Alloc __a
, _Args
&&...) : __storage_(std::move(__a
)) {
254 sizeof...(_Args
) == 0, "No argument should be provided to the control block when using _for_overwrite");
255 ::new ((void*)__get_elem()) _Tp
;
258 template <class... _Args
,
259 class _Allocator
= _Alloc
,
260 __enable_if_t
<!is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
261 _LIBCPP_HIDE_FROM_ABI
explicit __shared_ptr_emplace(_Alloc __a
, _Args
&&... __args
) : __storage_(std::move(__a
)) {
262 using _TpAlloc
= typename __allocator_traits_rebind
<_Alloc
, __remove_cv_t
<_Tp
> >::type
;
263 _TpAlloc
__tmp(*__get_alloc());
264 allocator_traits
<_TpAlloc
>::construct(__tmp
, __get_elem(), std::forward
<_Args
>(__args
)...);
267 _LIBCPP_HIDE_FROM_ABI _Alloc
* __get_alloc() _NOEXCEPT
{ return __storage_
.__get_alloc(); }
269 _LIBCPP_HIDE_FROM_ABI _Tp
* __get_elem() _NOEXCEPT
{ return __storage_
.__get_elem(); }
272 template <class _Allocator
= _Alloc
,
273 __enable_if_t
<is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
274 _LIBCPP_HIDE_FROM_ABI
void __on_zero_shared_impl() _NOEXCEPT
{
275 __get_elem()->~_Tp();
278 template <class _Allocator
= _Alloc
,
279 __enable_if_t
<!is_same
<typename
_Allocator::value_type
, __for_overwrite_tag
>::value
, int> = 0>
280 _LIBCPP_HIDE_FROM_ABI
void __on_zero_shared_impl() _NOEXCEPT
{
281 using _TpAlloc
= typename __allocator_traits_rebind
<_Allocator
, __remove_cv_t
<_Tp
> >::type
;
282 _TpAlloc
__tmp(*__get_alloc());
283 allocator_traits
<_TpAlloc
>::destroy(__tmp
, __get_elem());
286 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
{ __on_zero_shared_impl(); }
288 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
{
289 using _ControlBlockAlloc
= typename __allocator_traits_rebind
<_Alloc
, __shared_ptr_emplace
>::type
;
290 using _ControlBlockPointer
= typename allocator_traits
<_ControlBlockAlloc
>::pointer
;
291 _ControlBlockAlloc
__tmp(*__get_alloc());
292 __storage_
.~_Storage();
293 allocator_traits
<_ControlBlockAlloc
>::deallocate(__tmp
, pointer_traits
<_ControlBlockPointer
>::pointer_to(*this), 1);
296 // This class implements the control block for non-array shared pointers created
297 // through `std::allocate_shared` and `std::make_shared`.
299 // In previous versions of the library, we used a compressed pair to store
300 // both the _Alloc and the _Tp. This implies using EBO, which is incompatible
301 // with Allocator construction for _Tp. To allow implementing P0674 in C++20,
302 // we now use a properly aligned char buffer while making sure that we maintain
303 // the same layout that we had when we used a compressed pair.
304 using _CompressedPair
= __compressed_pair
<_Alloc
, _Tp
>;
305 struct _ALIGNAS_TYPE(_CompressedPair
) _Storage
{
306 char __blob_
[sizeof(_CompressedPair
)];
308 _LIBCPP_HIDE_FROM_ABI
explicit _Storage(_Alloc
&& __a
) { ::new ((void*)__get_alloc()) _Alloc(std::move(__a
)); }
309 _LIBCPP_HIDE_FROM_ABI
~_Storage() { __get_alloc()->~_Alloc(); }
310 _LIBCPP_HIDE_FROM_ABI _Alloc
* __get_alloc() _NOEXCEPT
{
311 _CompressedPair
* __as_pair
= reinterpret_cast<_CompressedPair
*>(__blob_
);
312 typename
_CompressedPair::_Base1
* __first
= _CompressedPair::__get_first_base(__as_pair
);
313 _Alloc
* __alloc
= reinterpret_cast<_Alloc
*>(__first
);
316 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp
* __get_elem() _NOEXCEPT
{
317 _CompressedPair
* __as_pair
= reinterpret_cast<_CompressedPair
*>(__blob_
);
318 typename
_CompressedPair::_Base2
* __second
= _CompressedPair::__get_second_base(__as_pair
);
319 _Tp
* __elem
= reinterpret_cast<_Tp
*>(__second
);
324 static_assert(_LIBCPP_ALIGNOF(_Storage
) == _LIBCPP_ALIGNOF(_CompressedPair
), "");
325 static_assert(sizeof(_Storage
) == sizeof(_CompressedPair
), "");
329 struct __shared_ptr_dummy_rebind_allocator_type
;
331 class _LIBCPP_TEMPLATE_VIS allocator
<__shared_ptr_dummy_rebind_allocator_type
> {
333 template <class _Other
>
335 typedef allocator
<_Other
> other
;
340 class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
;
342 // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.general-6
343 // A pointer type Y* is said to be compatible with a pointer type T*
344 // when either Y* is convertible to T* or Y is U[N] and T is cv U[].
345 #if _LIBCPP_STD_VER >= 17
346 template <class _Yp
, class _Tp
>
347 struct __bounded_convertible_to_unbounded
: false_type
{};
349 template <class _Up
, std::size_t _Np
, class _Tp
>
350 struct __bounded_convertible_to_unbounded
<_Up
[_Np
], _Tp
> : is_same
<__remove_cv_t
<_Tp
>, _Up
[]> {};
352 template <class _Yp
, class _Tp
>
353 struct __compatible_with
: _Or
< is_convertible
<_Yp
*, _Tp
*>, __bounded_convertible_to_unbounded
<_Yp
, _Tp
> > {};
355 template <class _Yp
, class _Tp
>
356 struct __compatible_with
: is_convertible
<_Yp
*, _Tp
*> {};
357 #endif // _LIBCPP_STD_VER >= 17
359 // Constructors that take raw pointers have a different set of "compatible" constraints
360 // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.const-9.1
361 // - If T is an array type, then either T is U[N] and Y(*)[N] is convertible to T*,
362 // or T is U[] and Y(*)[] is convertible to T*.
363 // - If T is not an array type, then Y* is convertible to T*.
364 #if _LIBCPP_STD_VER >= 17
365 template <class _Yp
, class _Tp
, class = void>
366 struct __raw_pointer_compatible_with
: _And
< _Not
<is_array
<_Tp
>>, is_convertible
<_Yp
*, _Tp
*> > {};
368 template <class _Yp
, class _Up
, std::size_t _Np
>
369 struct __raw_pointer_compatible_with
<_Yp
, _Up
[_Np
], __enable_if_t
< is_convertible
<_Yp (*)[_Np
], _Up (*)[_Np
]>::value
> >
372 template <class _Yp
, class _Up
>
373 struct __raw_pointer_compatible_with
<_Yp
, _Up
[], __enable_if_t
< is_convertible
<_Yp (*)[], _Up (*)[]>::value
> >
377 template <class _Yp
, class _Tp
>
378 struct __raw_pointer_compatible_with
: is_convertible
<_Yp
*, _Tp
*> {};
379 #endif // _LIBCPP_STD_VER >= 17
381 template <class _Ptr
, class = void>
382 struct __is_deletable
: false_type
{};
383 template <class _Ptr
>
384 struct __is_deletable
<_Ptr
, decltype(delete std::declval
<_Ptr
>())> : true_type
{};
386 template <class _Ptr
, class = void>
387 struct __is_array_deletable
: false_type
{};
388 template <class _Ptr
>
389 struct __is_array_deletable
<_Ptr
, decltype(delete[] std::declval
<_Ptr
>())> : true_type
{};
391 template <class _Dp
, class _Pt
, class = decltype(std::declval
<_Dp
>()(std::declval
<_Pt
>()))>
392 true_type
__well_formed_deleter_test(int);
394 template <class, class>
395 false_type
__well_formed_deleter_test(...);
397 template <class _Dp
, class _Pt
>
398 struct __well_formed_deleter
: decltype(std::__well_formed_deleter_test
<_Dp
, _Pt
>(0)) {};
400 template <class _Dp
, class _Yp
, class _Tp
>
401 struct __shared_ptr_deleter_ctor_reqs
{
402 static const bool value
= __raw_pointer_compatible_with
<_Yp
, _Tp
>::value
&& is_move_constructible
<_Dp
>::value
&&
403 __well_formed_deleter
<_Dp
, _Yp
*>::value
;
407 using __shared_ptr_nullptr_deleter_ctor_reqs
= _And
<is_move_constructible
<_Dp
>, __well_formed_deleter
<_Dp
, nullptr_t
> >;
409 #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
410 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
412 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
416 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
{
417 struct __nullptr_sfinae_tag
{};
420 #if _LIBCPP_STD_VER >= 17
421 typedef weak_ptr
<_Tp
> weak_type
;
422 typedef remove_extent_t
<_Tp
> element_type
;
424 typedef _Tp element_type
;
427 // A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
428 // any bookkeeping, so it's always trivially relocatable.
429 using __trivially_relocatable
= shared_ptr
;
432 element_type
* __ptr_
;
433 __shared_weak_count
* __cntrl_
;
436 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
shared_ptr() _NOEXCEPT
: __ptr_(nullptr), __cntrl_(nullptr) {}
438 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
shared_ptr(nullptr_t
) _NOEXCEPT
: __ptr_(nullptr), __cntrl_(nullptr) {}
441 __enable_if_t
< _And
< __raw_pointer_compatible_with
<_Yp
, _Tp
>
442 // In C++03 we get errors when trying to do SFINAE with the
443 // delete operator, so we always pretend that it's deletable.
444 // The same happens on GCC.
445 #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC)
447 _If
<is_array
<_Tp
>::value
, __is_array_deletable
<_Yp
*>, __is_deletable
<_Yp
*> >
451 _LIBCPP_HIDE_FROM_ABI
explicit shared_ptr(_Yp
* __p
) : __ptr_(__p
) {
452 unique_ptr
<_Yp
> __hold(__p
);
453 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
454 typedef __shared_ptr_pointer
<_Yp
*, __shared_ptr_default_delete
<_Tp
, _Yp
>, _AllocT
> _CntrlBlk
;
455 __cntrl_
= new _CntrlBlk(__p
, __shared_ptr_default_delete
<_Tp
, _Yp
>(), _AllocT());
457 __enable_weak_this(__p
, __p
);
460 template <class _Yp
, class _Dp
, __enable_if_t
<__shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
, int> = 0>
461 _LIBCPP_HIDE_FROM_ABI
shared_ptr(_Yp
* __p
, _Dp __d
) : __ptr_(__p
) {
462 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
464 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
465 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
466 typedef __shared_ptr_pointer
<_Yp
*, _Dp
, _AllocT
> _CntrlBlk
;
467 #ifndef _LIBCPP_CXX03_LANG
468 __cntrl_
= new _CntrlBlk(__p
, std::move(__d
), _AllocT());
470 __cntrl_
= new _CntrlBlk(__p
, __d
, _AllocT());
471 #endif // not _LIBCPP_CXX03_LANG
472 __enable_weak_this(__p
, __p
);
473 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
478 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
484 __enable_if_t
<__shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
, int> = 0>
485 _LIBCPP_HIDE_FROM_ABI
shared_ptr(_Yp
* __p
, _Dp __d
, _Alloc __a
) : __ptr_(__p
) {
486 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
488 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
489 typedef __shared_ptr_pointer
<_Yp
*, _Dp
, _Alloc
> _CntrlBlk
;
490 typedef typename __allocator_traits_rebind
<_Alloc
, _CntrlBlk
>::type _A2
;
491 typedef __allocator_destructor
<_A2
> _D2
;
493 unique_ptr
<_CntrlBlk
, _D2
> __hold2(__a2
.allocate(1), _D2(__a2
, 1));
494 ::new ((void*)std::addressof(*__hold2
.get()))
495 #ifndef _LIBCPP_CXX03_LANG
496 _CntrlBlk(__p
, std::move(__d
), __a
);
498 _CntrlBlk(__p
, __d
, __a
);
499 #endif // not _LIBCPP_CXX03_LANG
500 __cntrl_
= std::addressof(*__hold2
.release());
501 __enable_weak_this(__p
, __p
);
502 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
507 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
511 _LIBCPP_HIDE_FROM_ABI
shared_ptr(
514 __enable_if_t
<__shared_ptr_nullptr_deleter_ctor_reqs
<_Dp
>::value
, __nullptr_sfinae_tag
> = __nullptr_sfinae_tag())
516 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
518 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
519 typedef typename __shared_ptr_default_allocator
<_Tp
>::type _AllocT
;
520 typedef __shared_ptr_pointer
<nullptr_t
, _Dp
, _AllocT
> _CntrlBlk
;
521 #ifndef _LIBCPP_CXX03_LANG
522 __cntrl_
= new _CntrlBlk(__p
, std::move(__d
), _AllocT());
524 __cntrl_
= new _CntrlBlk(__p
, __d
, _AllocT());
525 #endif // not _LIBCPP_CXX03_LANG
526 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
531 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
534 template <class _Dp
, class _Alloc
>
535 _LIBCPP_HIDE_FROM_ABI
shared_ptr(
539 __enable_if_t
<__shared_ptr_nullptr_deleter_ctor_reqs
<_Dp
>::value
, __nullptr_sfinae_tag
> = __nullptr_sfinae_tag())
541 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
543 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
544 typedef __shared_ptr_pointer
<nullptr_t
, _Dp
, _Alloc
> _CntrlBlk
;
545 typedef typename __allocator_traits_rebind
<_Alloc
, _CntrlBlk
>::type _A2
;
546 typedef __allocator_destructor
<_A2
> _D2
;
548 unique_ptr
<_CntrlBlk
, _D2
> __hold2(__a2
.allocate(1), _D2(__a2
, 1));
549 ::new ((void*)std::addressof(*__hold2
.get()))
550 #ifndef _LIBCPP_CXX03_LANG
551 _CntrlBlk(__p
, std::move(__d
), __a
);
553 _CntrlBlk(__p
, __d
, __a
);
554 #endif // not _LIBCPP_CXX03_LANG
555 __cntrl_
= std::addressof(*__hold2
.release());
556 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
561 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
565 _LIBCPP_HIDE_FROM_ABI
shared_ptr(const shared_ptr
<_Yp
>& __r
, element_type
* __p
) _NOEXCEPT
567 __cntrl_(__r
.__cntrl_
) {
569 __cntrl_
->__add_shared();
573 // We don't backport because it is an evolutionary change.
574 #if _LIBCPP_STD_VER >= 20
576 _LIBCPP_HIDE_FROM_ABI
shared_ptr(shared_ptr
<_Yp
>&& __r
, element_type
* __p
) noexcept
577 : __ptr_(__p
), __cntrl_(__r
.__cntrl_
) {
578 __r
.__ptr_
= nullptr;
579 __r
.__cntrl_
= nullptr;
583 _LIBCPP_HIDE_FROM_ABI
shared_ptr(const shared_ptr
& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
585 __cntrl_
->__add_shared();
588 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
589 _LIBCPP_HIDE_FROM_ABI
shared_ptr(const shared_ptr
<_Yp
>& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
591 __cntrl_
->__add_shared();
594 _LIBCPP_HIDE_FROM_ABI
shared_ptr(shared_ptr
&& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
595 __r
.__ptr_
= nullptr;
596 __r
.__cntrl_
= nullptr;
599 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
600 _LIBCPP_HIDE_FROM_ABI
shared_ptr(shared_ptr
<_Yp
>&& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
601 __r
.__ptr_
= nullptr;
602 __r
.__cntrl_
= nullptr;
605 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
606 _LIBCPP_HIDE_FROM_ABI
explicit shared_ptr(const weak_ptr
<_Yp
>& __r
)
607 : __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
? __r
.__cntrl_
->lock() : __r
.__cntrl_
) {
608 if (__cntrl_
== nullptr)
609 __throw_bad_weak_ptr();
612 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
613 template <class _Yp
, __enable_if_t
<is_convertible
<_Yp
*, element_type
*>::value
, int> = 0>
614 _LIBCPP_HIDE_FROM_ABI
shared_ptr(auto_ptr
<_Yp
>&& __r
) : __ptr_(__r
.get()) {
615 typedef __shared_ptr_pointer
<_Yp
*, default_delete
<_Yp
>, allocator
<__remove_cv_t
<_Yp
> > > _CntrlBlk
;
616 __cntrl_
= new _CntrlBlk(__r
.get(), default_delete
<_Yp
>(), allocator
<__remove_cv_t
<_Yp
> >());
617 __enable_weak_this(__r
.get(), __r
.get());
624 __enable_if_t
<!is_lvalue_reference
<_Dp
>::value
&& __compatible_with
<_Yp
, _Tp
>::value
&&
625 is_convertible
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, element_type
*>::value
,
627 _LIBCPP_HIDE_FROM_ABI
shared_ptr(unique_ptr
<_Yp
, _Dp
>&& __r
) : __ptr_(__r
.get()) {
628 #if _LIBCPP_STD_VER >= 14
629 if (__ptr_
== nullptr)
634 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
635 typedef __shared_ptr_pointer
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, _Dp
, _AllocT
> _CntrlBlk
;
636 __cntrl_
= new _CntrlBlk(__r
.get(), std::move(__r
.get_deleter()), _AllocT());
637 __enable_weak_this(__r
.get(), __r
.get());
645 __enable_if_t
<is_lvalue_reference
<_Dp
>::value
&& __compatible_with
<_Yp
, _Tp
>::value
&&
646 is_convertible
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, element_type
*>::value
,
648 _LIBCPP_HIDE_FROM_ABI
shared_ptr(unique_ptr
<_Yp
, _Dp
>&& __r
) : __ptr_(__r
.get()) {
649 #if _LIBCPP_STD_VER >= 14
650 if (__ptr_
== nullptr)
655 typedef typename __shared_ptr_default_allocator
<_Yp
>::type _AllocT
;
656 typedef __shared_ptr_pointer
<typename unique_ptr
<_Yp
, _Dp
>::pointer
,
657 reference_wrapper
<__libcpp_remove_reference_t
<_Dp
> >,
660 __cntrl_
= new _CntrlBlk(__r
.get(), std::ref(__r
.get_deleter()), _AllocT());
661 __enable_weak_this(__r
.get(), __r
.get());
666 _LIBCPP_HIDE_FROM_ABI
~shared_ptr() {
668 __cntrl_
->__release_shared();
671 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(const shared_ptr
& __r
) _NOEXCEPT
{
672 shared_ptr(__r
).swap(*this);
676 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
677 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(const shared_ptr
<_Yp
>& __r
) _NOEXCEPT
{
678 shared_ptr(__r
).swap(*this);
682 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(shared_ptr
&& __r
) _NOEXCEPT
{
683 shared_ptr(std::move(__r
)).swap(*this);
687 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
688 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(shared_ptr
<_Yp
>&& __r
) {
689 shared_ptr(std::move(__r
)).swap(*this);
693 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
695 __enable_if_t
<!is_array
<_Yp
>::value
&& is_convertible
<_Yp
*, typename shared_ptr
<_Tp
>::element_type
*>::value
,
697 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(auto_ptr
<_Yp
>&& __r
) {
698 shared_ptr(std::move(__r
)).swap(*this);
705 __enable_if_t
<_And
< __compatible_with
<_Yp
, _Tp
>,
706 is_convertible
<typename unique_ptr
<_Yp
, _Dp
>::pointer
, element_type
*> >::value
,
708 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>& operator=(unique_ptr
<_Yp
, _Dp
>&& __r
) {
709 shared_ptr(std::move(__r
)).swap(*this);
713 _LIBCPP_HIDE_FROM_ABI
void swap(shared_ptr
& __r
) _NOEXCEPT
{
714 std::swap(__ptr_
, __r
.__ptr_
);
715 std::swap(__cntrl_
, __r
.__cntrl_
);
718 _LIBCPP_HIDE_FROM_ABI
void reset() _NOEXCEPT
{ shared_ptr().swap(*this); }
720 template <class _Yp
, __enable_if_t
<__raw_pointer_compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
721 _LIBCPP_HIDE_FROM_ABI
void reset(_Yp
* __p
) {
722 shared_ptr(__p
).swap(*this);
725 template <class _Yp
, class _Dp
, __enable_if_t
<__shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
, int> = 0>
726 _LIBCPP_HIDE_FROM_ABI
void reset(_Yp
* __p
, _Dp __d
) {
727 shared_ptr(__p
, __d
).swap(*this);
733 __enable_if_t
<__shared_ptr_deleter_ctor_reqs
<_Dp
, _Yp
, _Tp
>::value
, int> = 0>
734 _LIBCPP_HIDE_FROM_ABI
void reset(_Yp
* __p
, _Dp __d
, _Alloc __a
) {
735 shared_ptr(__p
, __d
, __a
).swap(*this);
738 _LIBCPP_HIDE_FROM_ABI element_type
* get() const _NOEXCEPT
{ return __ptr_
; }
740 _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t
<element_type
> operator*() const _NOEXCEPT
{ return *__ptr_
; }
742 _LIBCPP_HIDE_FROM_ABI element_type
* operator->() const _NOEXCEPT
{
743 static_assert(!is_array
<_Tp
>::value
, "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
747 _LIBCPP_HIDE_FROM_ABI
long use_count() const _NOEXCEPT
{ return __cntrl_
? __cntrl_
->use_count() : 0; }
749 #if _LIBCPP_STD_VER < 20 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE)
750 _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI
bool unique() const _NOEXCEPT
{ return use_count() == 1; }
753 _LIBCPP_HIDE_FROM_ABI
explicit operator bool() const _NOEXCEPT
{ return get() != nullptr; }
756 _LIBCPP_HIDE_FROM_ABI
bool owner_before(shared_ptr
<_Up
> const& __p
) const _NOEXCEPT
{
757 return __cntrl_
< __p
.__cntrl_
;
761 _LIBCPP_HIDE_FROM_ABI
bool owner_before(weak_ptr
<_Up
> const& __p
) const _NOEXCEPT
{
762 return __cntrl_
< __p
.__cntrl_
;
765 _LIBCPP_HIDE_FROM_ABI
bool __owner_equivalent(const shared_ptr
& __p
) const { return __cntrl_
== __p
.__cntrl_
; }
767 #if _LIBCPP_STD_VER >= 17
768 _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t
<element_type
> operator[](ptrdiff_t __i
) const {
769 static_assert(is_array
<_Tp
>::value
, "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
774 #ifndef _LIBCPP_HAS_NO_RTTI
776 _LIBCPP_HIDE_FROM_ABI _Dp
* __get_deleter() const _NOEXCEPT
{
777 return static_cast<_Dp
*>(__cntrl_
? const_cast<void*>(__cntrl_
->__get_deleter(typeid(_Dp
))) : nullptr);
779 #endif // _LIBCPP_HAS_NO_RTTI
781 template <class _Yp
, class _CntrlBlk
>
782 _LIBCPP_HIDE_FROM_ABI
static shared_ptr
<_Tp
> __create_with_control_block(_Yp
* __p
, _CntrlBlk
* __cntrl
) _NOEXCEPT
{
785 __r
.__cntrl_
= __cntrl
;
786 __r
.__enable_weak_this(__r
.__ptr_
, __r
.__ptr_
);
791 template <class _Yp
, bool = is_function
<_Yp
>::value
>
792 struct __shared_ptr_default_allocator
{
793 typedef allocator
<__remove_cv_t
<_Yp
> > type
;
797 struct __shared_ptr_default_allocator
<_Yp
, true> {
798 typedef allocator
<__shared_ptr_dummy_rebind_allocator_type
> type
;
803 __enable_if_t
<is_convertible
<_OrigPtr
*, const enable_shared_from_this
<_Yp
>*>::value
, int> = 0>
804 _LIBCPP_HIDE_FROM_ABI
void __enable_weak_this(const enable_shared_from_this
<_Yp
>* __e
, _OrigPtr
* __ptr
) _NOEXCEPT
{
805 typedef __remove_cv_t
<_Yp
> _RawYp
;
806 if (__e
&& __e
->__weak_this_
.expired()) {
807 __e
->__weak_this_
= shared_ptr
<_RawYp
>(*this, const_cast<_RawYp
*>(static_cast<const _Yp
*>(__ptr
)));
811 _LIBCPP_HIDE_FROM_ABI
void __enable_weak_this(...) _NOEXCEPT
{}
813 template <class, class _Yp
>
814 struct __shared_ptr_default_delete
: default_delete
<_Yp
> {};
816 template <class _Yp
, class _Un
, size_t _Sz
>
817 struct __shared_ptr_default_delete
<_Yp
[_Sz
], _Un
> : default_delete
<_Yp
[]> {};
819 template <class _Yp
, class _Un
>
820 struct __shared_ptr_default_delete
<_Yp
[], _Un
> : default_delete
<_Yp
[]> {};
823 friend class _LIBCPP_TEMPLATE_VIS shared_ptr
;
825 friend class _LIBCPP_TEMPLATE_VIS weak_ptr
;
828 #if _LIBCPP_STD_VER >= 17
830 shared_ptr(weak_ptr
<_Tp
>) -> shared_ptr
<_Tp
>;
831 template <class _Tp
, class _Dp
>
832 shared_ptr(unique_ptr
<_Tp
, _Dp
>) -> shared_ptr
<_Tp
>;
836 // std::allocate_shared and std::make_shared
838 template <class _Tp
, class _Alloc
, class... _Args
, __enable_if_t
<!is_array
<_Tp
>::value
, int> = 0>
839 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, _Args
&&... __args
) {
840 using _ControlBlock
= __shared_ptr_emplace
<_Tp
, _Alloc
>;
841 using _ControlBlockAllocator
= typename __allocator_traits_rebind
<_Alloc
, _ControlBlock
>::type
;
842 __allocation_guard
<_ControlBlockAllocator
> __guard(__a
, 1);
843 ::new ((void*)std::addressof(*__guard
.__get())) _ControlBlock(__a
, std::forward
<_Args
>(__args
)...);
844 auto __control_block
= __guard
.__release_ptr();
845 return shared_ptr
<_Tp
>::__create_with_control_block(
846 (*__control_block
).__get_elem(), std::addressof(*__control_block
));
849 template <class _Tp
, class... _Args
, __enable_if_t
<!is_array
<_Tp
>::value
, int> = 0>
850 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared(_Args
&&... __args
) {
851 return std::allocate_shared
<_Tp
>(allocator
<__remove_cv_t
<_Tp
> >(), std::forward
<_Args
>(__args
)...);
854 #if _LIBCPP_STD_VER >= 20
856 template <class _Tp
, class _Alloc
, __enable_if_t
<!is_array
<_Tp
>::value
, int> = 0>
857 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared_for_overwrite(const _Alloc
& __a
) {
858 using _ForOverwriteAllocator
= __allocator_traits_rebind_t
<_Alloc
, __for_overwrite_tag
>;
859 _ForOverwriteAllocator
__alloc(__a
);
860 return std::allocate_shared
<_Tp
>(__alloc
);
863 template <class _Tp
, __enable_if_t
<!is_array
<_Tp
>::value
, int> = 0>
864 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared_for_overwrite() {
865 return std::allocate_shared_for_overwrite
<_Tp
>(allocator
<__remove_cv_t
<_Tp
>>());
868 #endif // _LIBCPP_STD_VER >= 20
870 #if _LIBCPP_STD_VER >= 17
872 template <size_t _Alignment
>
873 struct __sp_aligned_storage
{
874 alignas(_Alignment
) char __storage
[_Alignment
];
877 template <class _Tp
, class _Alloc
>
878 struct __unbounded_array_control_block
;
880 template <class _Tp
, class _Alloc
>
881 struct __unbounded_array_control_block
<_Tp
[], _Alloc
> : __shared_weak_count
{
882 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
* __get_data() noexcept
{ return __data_
; }
884 _LIBCPP_HIDE_FROM_ABI
explicit __unbounded_array_control_block(
885 _Alloc
const& __alloc
, size_t __count
, _Tp
const& __arg
)
886 : __alloc_(__alloc
), __count_(__count
) {
887 std::__uninitialized_allocator_fill_n_multidimensional(__alloc_
, std::begin(__data_
), __count_
, __arg
);
890 _LIBCPP_HIDE_FROM_ABI
explicit __unbounded_array_control_block(_Alloc
const& __alloc
, size_t __count
)
891 : __alloc_(__alloc
), __count_(__count
) {
892 # if _LIBCPP_STD_VER >= 20
893 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
894 // We are purposefully not using an allocator-aware default construction because the spec says so.
895 // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
896 std::uninitialized_default_construct_n(std::begin(__data_
), __count_
);
898 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::begin(__data_
), __count_
);
901 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::begin(__data_
), __count_
);
905 // Returns the number of bytes required to store a control block followed by the given number
906 // of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment.
907 _LIBCPP_HIDE_FROM_ABI
static constexpr size_t __bytes_for(size_t __elements
) {
908 // When there's 0 elements, the control block alone is enough since it holds one element.
909 // Otherwise, we allocate one fewer element than requested because the control block already
910 // holds one. Also, we use the bitwise formula below to ensure that we allocate enough bytes
911 // for the whole allocation to be a multiple of _Tp's alignment. That formula is taken from [1].
913 // [1]: https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding
914 size_t __bytes
= __elements
== 0 ? sizeof(__unbounded_array_control_block
)
915 : (__elements
- 1) * sizeof(_Tp
) + sizeof(__unbounded_array_control_block
);
916 constexpr size_t __align
= alignof(_Tp
);
917 return (__bytes
+ __align
- 1) & ~(__align
- 1);
920 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
921 ~__unbounded_array_control_block() override
{
922 } // can't be `= default` because of the sometimes-non-trivial union member __data_
925 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
{
926 # if _LIBCPP_STD_VER >= 20
927 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
928 std::__reverse_destroy(__data_
, __data_
+ __count_
);
930 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
931 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ __count_
);
934 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
935 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ __count_
);
939 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
{
940 using _AlignedStorage
= __sp_aligned_storage
<alignof(__unbounded_array_control_block
)>;
941 using _StorageAlloc
= __allocator_traits_rebind_t
<_Alloc
, _AlignedStorage
>;
942 using _PointerTraits
= pointer_traits
<typename allocator_traits
<_StorageAlloc
>::pointer
>;
944 _StorageAlloc
__tmp(__alloc_
);
946 size_t __size
= __unbounded_array_control_block::__bytes_for(__count_
);
947 _AlignedStorage
* __storage
= reinterpret_cast<_AlignedStorage
*>(this);
948 allocator_traits
<_StorageAlloc
>::deallocate(
949 __tmp
, _PointerTraits::pointer_to(*__storage
), __size
/ sizeof(_AlignedStorage
));
952 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_
;
959 template <class _Array
, class _Alloc
, class... _Arg
>
960 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Array
>
961 __allocate_shared_unbounded_array(const _Alloc
& __a
, size_t __n
, _Arg
&&... __arg
) {
962 static_assert(__libcpp_is_unbounded_array
<_Array
>::value
);
963 // We compute the number of bytes necessary to hold the control block and the
964 // array elements. Then, we allocate an array of properly-aligned dummy structs
965 // large enough to hold the control block and array. This allows shifting the
966 // burden of aligning memory properly from us to the allocator.
967 using _ControlBlock
= __unbounded_array_control_block
<_Array
, _Alloc
>;
968 using _AlignedStorage
= __sp_aligned_storage
<alignof(_ControlBlock
)>;
969 using _StorageAlloc
= __allocator_traits_rebind_t
<_Alloc
, _AlignedStorage
>;
970 __allocation_guard
<_StorageAlloc
> __guard(__a
, _ControlBlock::__bytes_for(__n
) / sizeof(_AlignedStorage
));
971 _ControlBlock
* __control_block
= reinterpret_cast<_ControlBlock
*>(std::addressof(*__guard
.__get()));
972 std::__construct_at(__control_block
, __a
, __n
, std::forward
<_Arg
>(__arg
)...);
973 __guard
.__release_ptr();
974 return shared_ptr
<_Array
>::__create_with_control_block(__control_block
->__get_data(), __control_block
);
977 template <class _Tp
, class _Alloc
>
978 struct __bounded_array_control_block
;
980 template <class _Tp
, size_t _Count
, class _Alloc
>
981 struct __bounded_array_control_block
<_Tp
[_Count
], _Alloc
> : __shared_weak_count
{
982 _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
* __get_data() noexcept
{ return __data_
; }
984 _LIBCPP_HIDE_FROM_ABI
explicit __bounded_array_control_block(_Alloc
const& __alloc
, _Tp
const& __arg
)
985 : __alloc_(__alloc
) {
986 std::__uninitialized_allocator_fill_n_multidimensional(__alloc_
, std::addressof(__data_
[0]), _Count
, __arg
);
989 _LIBCPP_HIDE_FROM_ABI
explicit __bounded_array_control_block(_Alloc
const& __alloc
) : __alloc_(__alloc
) {
990 # if _LIBCPP_STD_VER >= 20
991 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
992 // We are purposefully not using an allocator-aware default construction because the spec says so.
993 // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
994 std::uninitialized_default_construct_n(std::addressof(__data_
[0]), _Count
);
996 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::addressof(__data_
[0]), _Count
);
999 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_
, std::addressof(__data_
[0]), _Count
);
1003 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
1004 ~__bounded_array_control_block() override
{
1005 } // can't be `= default` because of the sometimes-non-trivial union member __data_
1008 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared() _NOEXCEPT override
{
1009 # if _LIBCPP_STD_VER >= 20
1010 if constexpr (is_same_v
<typename
_Alloc::value_type
, __for_overwrite_tag
>) {
1011 std::__reverse_destroy(__data_
, __data_
+ _Count
);
1013 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
1014 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ _Count
);
1017 __allocator_traits_rebind_t
<_Alloc
, _Tp
> __value_alloc(__alloc_
);
1018 std::__allocator_destroy_multidimensional(__value_alloc
, __data_
, __data_
+ _Count
);
1022 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
void __on_zero_shared_weak() _NOEXCEPT override
{
1023 using _ControlBlockAlloc
= __allocator_traits_rebind_t
<_Alloc
, __bounded_array_control_block
>;
1024 using _PointerTraits
= pointer_traits
<typename allocator_traits
<_ControlBlockAlloc
>::pointer
>;
1026 _ControlBlockAlloc
__tmp(__alloc_
);
1028 allocator_traits
<_ControlBlockAlloc
>::deallocate(__tmp
, _PointerTraits::pointer_to(*this), 1);
1031 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_
;
1033 _Tp __data_
[_Count
];
1037 template <class _Array
, class _Alloc
, class... _Arg
>
1038 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Array
> __allocate_shared_bounded_array(const _Alloc
& __a
, _Arg
&&... __arg
) {
1039 static_assert(__libcpp_is_bounded_array
<_Array
>::value
);
1040 using _ControlBlock
= __bounded_array_control_block
<_Array
, _Alloc
>;
1041 using _ControlBlockAlloc
= __allocator_traits_rebind_t
<_Alloc
, _ControlBlock
>;
1043 __allocation_guard
<_ControlBlockAlloc
> __guard(__a
, 1);
1044 _ControlBlock
* __control_block
= reinterpret_cast<_ControlBlock
*>(std::addressof(*__guard
.__get()));
1045 std::__construct_at(__control_block
, __a
, std::forward
<_Arg
>(__arg
)...);
1046 __guard
.__release_ptr();
1047 return shared_ptr
<_Array
>::__create_with_control_block(__control_block
->__get_data(), __control_block
);
1050 #endif // _LIBCPP_STD_VER >= 17
1052 #if _LIBCPP_STD_VER >= 20
1054 // bounded array variants
1055 template <class _Tp
, class _Alloc
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
1056 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
) {
1057 return std::__allocate_shared_bounded_array
<_Tp
>(__a
);
1060 template <class _Tp
, class _Alloc
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
1061 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, const remove_extent_t
<_Tp
>& __u
) {
1062 return std::__allocate_shared_bounded_array
<_Tp
>(__a
, __u
);
1065 template <class _Tp
, class _Alloc
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
1066 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared_for_overwrite(const _Alloc
& __a
) {
1067 using _ForOverwriteAllocator
= __allocator_traits_rebind_t
<_Alloc
, __for_overwrite_tag
>;
1068 _ForOverwriteAllocator
__alloc(__a
);
1069 return std::__allocate_shared_bounded_array
<_Tp
>(__alloc
);
1072 template <class _Tp
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
1073 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared() {
1074 return std::__allocate_shared_bounded_array
<_Tp
>(allocator
<_Tp
>());
1077 template <class _Tp
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
1078 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared(const remove_extent_t
<_Tp
>& __u
) {
1079 return std::__allocate_shared_bounded_array
<_Tp
>(allocator
<_Tp
>(), __u
);
1082 template <class _Tp
, __enable_if_t
<is_bounded_array
<_Tp
>::value
, int> = 0>
1083 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared_for_overwrite() {
1084 return std::__allocate_shared_bounded_array
<_Tp
>(allocator
<__for_overwrite_tag
>());
1087 // unbounded array variants
1088 template <class _Tp
, class _Alloc
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
1089 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, size_t __n
) {
1090 return std::__allocate_shared_unbounded_array
<_Tp
>(__a
, __n
);
1093 template <class _Tp
, class _Alloc
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
1094 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared(const _Alloc
& __a
, size_t __n
, const remove_extent_t
<_Tp
>& __u
) {
1095 return std::__allocate_shared_unbounded_array
<_Tp
>(__a
, __n
, __u
);
1098 template <class _Tp
, class _Alloc
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
1099 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> allocate_shared_for_overwrite(const _Alloc
& __a
, size_t __n
) {
1100 using _ForOverwriteAllocator
= __allocator_traits_rebind_t
<_Alloc
, __for_overwrite_tag
>;
1101 _ForOverwriteAllocator
__alloc(__a
);
1102 return std::__allocate_shared_unbounded_array
<_Tp
>(__alloc
, __n
);
1105 template <class _Tp
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
1106 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared(size_t __n
) {
1107 return std::__allocate_shared_unbounded_array
<_Tp
>(allocator
<_Tp
>(), __n
);
1110 template <class _Tp
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
1111 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared(size_t __n
, const remove_extent_t
<_Tp
>& __u
) {
1112 return std::__allocate_shared_unbounded_array
<_Tp
>(allocator
<_Tp
>(), __n
, __u
);
1115 template <class _Tp
, __enable_if_t
<is_unbounded_array
<_Tp
>::value
, int> = 0>
1116 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> make_shared_for_overwrite(size_t __n
) {
1117 return std::__allocate_shared_unbounded_array
<_Tp
>(allocator
<__for_overwrite_tag
>(), __n
);
1120 #endif // _LIBCPP_STD_VER >= 20
1122 template <class _Tp
, class _Up
>
1123 inline _LIBCPP_HIDE_FROM_ABI
bool operator==(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1124 return __x
.get() == __y
.get();
1127 #if _LIBCPP_STD_VER <= 17
1129 template <class _Tp
, class _Up
>
1130 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1131 return !(__x
== __y
);
1134 template <class _Tp
, class _Up
>
1135 inline _LIBCPP_HIDE_FROM_ABI
bool operator<(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1136 # if _LIBCPP_STD_VER <= 11
1137 typedef typename common_type
<_Tp
*, _Up
*>::type _Vp
;
1138 return less
<_Vp
>()(__x
.get(), __y
.get());
1140 return less
<>()(__x
.get(), __y
.get());
1144 template <class _Tp
, class _Up
>
1145 inline _LIBCPP_HIDE_FROM_ABI
bool operator>(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1149 template <class _Tp
, class _Up
>
1150 inline _LIBCPP_HIDE_FROM_ABI
bool operator<=(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1151 return !(__y
< __x
);
1154 template <class _Tp
, class _Up
>
1155 inline _LIBCPP_HIDE_FROM_ABI
bool operator>=(const shared_ptr
<_Tp
>& __x
, const shared_ptr
<_Up
>& __y
) _NOEXCEPT
{
1156 return !(__x
< __y
);
1159 #endif // _LIBCPP_STD_VER <= 17
1161 #if _LIBCPP_STD_VER >= 20
1162 template <class _Tp
, class _Up
>
1163 _LIBCPP_HIDE_FROM_ABI strong_ordering
operator<=>(shared_ptr
<_Tp
> const& __x
, shared_ptr
<_Up
> const& __y
) noexcept
{
1164 return compare_three_way()(__x
.get(), __y
.get());
1168 template <class _Tp
>
1169 inline _LIBCPP_HIDE_FROM_ABI
bool operator==(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1173 #if _LIBCPP_STD_VER <= 17
1175 template <class _Tp
>
1176 inline _LIBCPP_HIDE_FROM_ABI
bool operator==(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1180 template <class _Tp
>
1181 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1182 return static_cast<bool>(__x
);
1185 template <class _Tp
>
1186 inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1187 return static_cast<bool>(__x
);
1190 template <class _Tp
>
1191 inline _LIBCPP_HIDE_FROM_ABI
bool operator<(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1192 return less
<typename shared_ptr
<_Tp
>::element_type
*>()(__x
.get(), nullptr);
1195 template <class _Tp
>
1196 inline _LIBCPP_HIDE_FROM_ABI
bool operator<(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1197 return less
<typename shared_ptr
<_Tp
>::element_type
*>()(nullptr, __x
.get());
1200 template <class _Tp
>
1201 inline _LIBCPP_HIDE_FROM_ABI
bool operator>(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1202 return nullptr < __x
;
1205 template <class _Tp
>
1206 inline _LIBCPP_HIDE_FROM_ABI
bool operator>(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1207 return __x
< nullptr;
1210 template <class _Tp
>
1211 inline _LIBCPP_HIDE_FROM_ABI
bool operator<=(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1212 return !(nullptr < __x
);
1215 template <class _Tp
>
1216 inline _LIBCPP_HIDE_FROM_ABI
bool operator<=(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1217 return !(__x
< nullptr);
1220 template <class _Tp
>
1221 inline _LIBCPP_HIDE_FROM_ABI
bool operator>=(const shared_ptr
<_Tp
>& __x
, nullptr_t
) _NOEXCEPT
{
1222 return !(__x
< nullptr);
1225 template <class _Tp
>
1226 inline _LIBCPP_HIDE_FROM_ABI
bool operator>=(nullptr_t
, const shared_ptr
<_Tp
>& __x
) _NOEXCEPT
{
1227 return !(nullptr < __x
);
1230 #endif // _LIBCPP_STD_VER <= 17
1232 #if _LIBCPP_STD_VER >= 20
1233 template <class _Tp
>
1234 _LIBCPP_HIDE_FROM_ABI strong_ordering
operator<=>(shared_ptr
<_Tp
> const& __x
, nullptr_t
) noexcept
{
1235 return compare_three_way()(__x
.get(), static_cast<typename shared_ptr
<_Tp
>::element_type
*>(nullptr));
1239 template <class _Tp
>
1240 inline _LIBCPP_HIDE_FROM_ABI
void swap(shared_ptr
<_Tp
>& __x
, shared_ptr
<_Tp
>& __y
) _NOEXCEPT
{
1244 template <class _Tp
, class _Up
>
1245 inline _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> static_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
{
1246 return shared_ptr
<_Tp
>(__r
, static_cast< typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1250 // We don't backport because it is an evolutionary change.
1251 #if _LIBCPP_STD_VER >= 20
1252 template <class _Tp
, class _Up
>
1253 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> static_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1254 return shared_ptr
<_Tp
>(std::move(__r
), static_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1258 template <class _Tp
, class _Up
>
1259 inline _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> dynamic_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
{
1260 typedef typename shared_ptr
<_Tp
>::element_type _ET
;
1261 _ET
* __p
= dynamic_cast<_ET
*>(__r
.get());
1262 return __p
? shared_ptr
<_Tp
>(__r
, __p
) : shared_ptr
<_Tp
>();
1266 // We don't backport because it is an evolutionary change.
1267 #if _LIBCPP_STD_VER >= 20
1268 template <class _Tp
, class _Up
>
1269 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> dynamic_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1270 auto* __p
= dynamic_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get());
1271 return __p
? shared_ptr
<_Tp
>(std::move(__r
), __p
) : shared_ptr
<_Tp
>();
1275 template <class _Tp
, class _Up
>
1276 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> const_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
{
1277 typedef typename shared_ptr
<_Tp
>::element_type _RTp
;
1278 return shared_ptr
<_Tp
>(__r
, const_cast<_RTp
*>(__r
.get()));
1282 // We don't backport because it is an evolutionary change.
1283 #if _LIBCPP_STD_VER >= 20
1284 template <class _Tp
, class _Up
>
1285 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> const_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1286 return shared_ptr
<_Tp
>(std::move(__r
), const_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1290 template <class _Tp
, class _Up
>
1291 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> reinterpret_pointer_cast(const shared_ptr
<_Up
>& __r
) _NOEXCEPT
{
1292 return shared_ptr
<_Tp
>(__r
, reinterpret_cast< typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1296 // We don't backport because it is an evolutionary change.
1297 #if _LIBCPP_STD_VER >= 20
1298 template <class _Tp
, class _Up
>
1299 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> reinterpret_pointer_cast(shared_ptr
<_Up
>&& __r
) noexcept
{
1300 return shared_ptr
<_Tp
>(std::move(__r
), reinterpret_cast<typename shared_ptr
<_Tp
>::element_type
*>(__r
.get()));
1304 #ifndef _LIBCPP_HAS_NO_RTTI
1306 template <class _Dp
, class _Tp
>
1307 inline _LIBCPP_HIDE_FROM_ABI _Dp
* get_deleter(const shared_ptr
<_Tp
>& __p
) _NOEXCEPT
{
1308 return __p
.template __get_deleter
<_Dp
>();
1311 #endif // _LIBCPP_HAS_NO_RTTI
1313 template <class _Tp
>
1314 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
{
1316 #if _LIBCPP_STD_VER >= 17
1317 typedef remove_extent_t
<_Tp
> element_type
;
1319 typedef _Tp element_type
;
1322 // A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
1323 // any bookkeeping, so it's always trivially relocatable.
1324 using __trivially_relocatable
= weak_ptr
;
1327 element_type
* __ptr_
;
1328 __shared_weak_count
* __cntrl_
;
1331 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
weak_ptr() _NOEXCEPT
;
1333 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1334 _LIBCPP_HIDE_FROM_ABI
weak_ptr(shared_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1336 _LIBCPP_HIDE_FROM_ABI
weak_ptr(weak_ptr
const& __r
) _NOEXCEPT
;
1338 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1339 _LIBCPP_HIDE_FROM_ABI
weak_ptr(weak_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1341 _LIBCPP_HIDE_FROM_ABI
weak_ptr(weak_ptr
&& __r
) _NOEXCEPT
;
1343 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1344 _LIBCPP_HIDE_FROM_ABI
weak_ptr(weak_ptr
<_Yp
>&& __r
) _NOEXCEPT
;
1346 _LIBCPP_HIDE_FROM_ABI
~weak_ptr();
1348 _LIBCPP_HIDE_FROM_ABI weak_ptr
& operator=(weak_ptr
const& __r
) _NOEXCEPT
;
1349 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1350 _LIBCPP_HIDE_FROM_ABI weak_ptr
& operator=(weak_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1352 _LIBCPP_HIDE_FROM_ABI weak_ptr
& operator=(weak_ptr
&& __r
) _NOEXCEPT
;
1353 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1354 _LIBCPP_HIDE_FROM_ABI weak_ptr
& operator=(weak_ptr
<_Yp
>&& __r
) _NOEXCEPT
;
1356 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> = 0>
1357 _LIBCPP_HIDE_FROM_ABI weak_ptr
& operator=(shared_ptr
<_Yp
> const& __r
) _NOEXCEPT
;
1359 _LIBCPP_HIDE_FROM_ABI
void swap(weak_ptr
& __r
) _NOEXCEPT
;
1360 _LIBCPP_HIDE_FROM_ABI
void reset() _NOEXCEPT
;
1362 _LIBCPP_HIDE_FROM_ABI
long use_count() const _NOEXCEPT
{ return __cntrl_
? __cntrl_
->use_count() : 0; }
1363 _LIBCPP_HIDE_FROM_ABI
bool expired() const _NOEXCEPT
{ return __cntrl_
== nullptr || __cntrl_
->use_count() == 0; }
1364 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> lock() const _NOEXCEPT
;
1365 template <class _Up
>
1366 _LIBCPP_HIDE_FROM_ABI
bool owner_before(const shared_ptr
<_Up
>& __r
) const _NOEXCEPT
{
1367 return __cntrl_
< __r
.__cntrl_
;
1369 template <class _Up
>
1370 _LIBCPP_HIDE_FROM_ABI
bool owner_before(const weak_ptr
<_Up
>& __r
) const _NOEXCEPT
{
1371 return __cntrl_
< __r
.__cntrl_
;
1374 template <class _Up
>
1375 friend class _LIBCPP_TEMPLATE_VIS weak_ptr
;
1376 template <class _Up
>
1377 friend class _LIBCPP_TEMPLATE_VIS shared_ptr
;
1380 #if _LIBCPP_STD_VER >= 17
1381 template <class _Tp
>
1382 weak_ptr(shared_ptr
<_Tp
>) -> weak_ptr
<_Tp
>;
1385 template <class _Tp
>
1386 inline _LIBCPP_CONSTEXPR weak_ptr
<_Tp
>::weak_ptr() _NOEXCEPT
: __ptr_(nullptr), __cntrl_(nullptr) {}
1388 template <class _Tp
>
1389 inline weak_ptr
<_Tp
>::weak_ptr(weak_ptr
const& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
1391 __cntrl_
->__add_weak();
1394 template <class _Tp
>
1395 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1396 inline weak_ptr
<_Tp
>::weak_ptr(shared_ptr
<_Yp
> const& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
1398 __cntrl_
->__add_weak();
1401 template <class _Tp
>
1402 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1403 inline weak_ptr
<_Tp
>::weak_ptr(weak_ptr
<_Yp
> const& __r
) _NOEXCEPT
: __ptr_(nullptr), __cntrl_(nullptr) {
1404 shared_ptr
<_Yp
> __s
= __r
.lock();
1405 *this = weak_ptr
<_Tp
>(__s
);
1408 template <class _Tp
>
1409 inline weak_ptr
<_Tp
>::weak_ptr(weak_ptr
&& __r
) _NOEXCEPT
: __ptr_(__r
.__ptr_
), __cntrl_(__r
.__cntrl_
) {
1410 __r
.__ptr_
= nullptr;
1411 __r
.__cntrl_
= nullptr;
1414 template <class _Tp
>
1415 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1416 inline weak_ptr
<_Tp
>::weak_ptr(weak_ptr
<_Yp
>&& __r
) _NOEXCEPT
: __ptr_(nullptr), __cntrl_(nullptr) {
1417 shared_ptr
<_Yp
> __s
= __r
.lock();
1418 *this = weak_ptr
<_Tp
>(__s
);
1422 template <class _Tp
>
1423 weak_ptr
<_Tp
>::~weak_ptr() {
1425 __cntrl_
->__release_weak();
1428 template <class _Tp
>
1429 inline weak_ptr
<_Tp
>& weak_ptr
<_Tp
>::operator=(weak_ptr
const& __r
) _NOEXCEPT
{
1430 weak_ptr(__r
).swap(*this);
1434 template <class _Tp
>
1435 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1436 inline weak_ptr
<_Tp
>& weak_ptr
<_Tp
>::operator=(weak_ptr
<_Yp
> const& __r
) _NOEXCEPT
{
1437 weak_ptr(__r
).swap(*this);
1441 template <class _Tp
>
1442 inline weak_ptr
<_Tp
>& weak_ptr
<_Tp
>::operator=(weak_ptr
&& __r
) _NOEXCEPT
{
1443 weak_ptr(std::move(__r
)).swap(*this);
1447 template <class _Tp
>
1448 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1449 inline weak_ptr
<_Tp
>& weak_ptr
<_Tp
>::operator=(weak_ptr
<_Yp
>&& __r
) _NOEXCEPT
{
1450 weak_ptr(std::move(__r
)).swap(*this);
1454 template <class _Tp
>
1455 template <class _Yp
, __enable_if_t
<__compatible_with
<_Yp
, _Tp
>::value
, int> >
1456 inline weak_ptr
<_Tp
>& weak_ptr
<_Tp
>::operator=(shared_ptr
<_Yp
> const& __r
) _NOEXCEPT
{
1457 weak_ptr(__r
).swap(*this);
1461 template <class _Tp
>
1462 inline void weak_ptr
<_Tp
>::swap(weak_ptr
& __r
) _NOEXCEPT
{
1463 std::swap(__ptr_
, __r
.__ptr_
);
1464 std::swap(__cntrl_
, __r
.__cntrl_
);
1467 template <class _Tp
>
1468 inline _LIBCPP_HIDE_FROM_ABI
void swap(weak_ptr
<_Tp
>& __x
, weak_ptr
<_Tp
>& __y
) _NOEXCEPT
{
1472 template <class _Tp
>
1473 inline void weak_ptr
<_Tp
>::reset() _NOEXCEPT
{
1474 weak_ptr().swap(*this);
1477 template <class _Tp
>
1478 shared_ptr
<_Tp
> weak_ptr
<_Tp
>::lock() const _NOEXCEPT
{
1479 shared_ptr
<_Tp
> __r
;
1480 __r
.__cntrl_
= __cntrl_
? __cntrl_
->lock() : __cntrl_
;
1482 __r
.__ptr_
= __ptr_
;
1486 #if _LIBCPP_STD_VER >= 17
1487 template <class _Tp
= void>
1490 template <class _Tp
>
1494 template <class _Tp
>
1495 struct _LIBCPP_TEMPLATE_VIS owner_less
<shared_ptr
<_Tp
> > : __binary_function
<shared_ptr
<_Tp
>, shared_ptr
<_Tp
>, bool> {
1496 _LIBCPP_HIDE_FROM_ABI
bool operator()(shared_ptr
<_Tp
> const& __x
, shared_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1497 return __x
.owner_before(__y
);
1499 _LIBCPP_HIDE_FROM_ABI
bool operator()(shared_ptr
<_Tp
> const& __x
, weak_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1500 return __x
.owner_before(__y
);
1502 _LIBCPP_HIDE_FROM_ABI
bool operator()(weak_ptr
<_Tp
> const& __x
, shared_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1503 return __x
.owner_before(__y
);
1507 template <class _Tp
>
1508 struct _LIBCPP_TEMPLATE_VIS owner_less
<weak_ptr
<_Tp
> > : __binary_function
<weak_ptr
<_Tp
>, weak_ptr
<_Tp
>, bool> {
1509 _LIBCPP_HIDE_FROM_ABI
bool operator()(weak_ptr
<_Tp
> const& __x
, weak_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1510 return __x
.owner_before(__y
);
1512 _LIBCPP_HIDE_FROM_ABI
bool operator()(shared_ptr
<_Tp
> const& __x
, weak_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1513 return __x
.owner_before(__y
);
1515 _LIBCPP_HIDE_FROM_ABI
bool operator()(weak_ptr
<_Tp
> const& __x
, shared_ptr
<_Tp
> const& __y
) const _NOEXCEPT
{
1516 return __x
.owner_before(__y
);
1520 #if _LIBCPP_STD_VER >= 17
1522 struct _LIBCPP_TEMPLATE_VIS owner_less
<void> {
1523 template <class _Tp
, class _Up
>
1524 _LIBCPP_HIDE_FROM_ABI
bool operator()(shared_ptr
<_Tp
> const& __x
, shared_ptr
<_Up
> const& __y
) const _NOEXCEPT
{
1525 return __x
.owner_before(__y
);
1527 template <class _Tp
, class _Up
>
1528 _LIBCPP_HIDE_FROM_ABI
bool operator()(shared_ptr
<_Tp
> const& __x
, weak_ptr
<_Up
> const& __y
) const _NOEXCEPT
{
1529 return __x
.owner_before(__y
);
1531 template <class _Tp
, class _Up
>
1532 _LIBCPP_HIDE_FROM_ABI
bool operator()(weak_ptr
<_Tp
> const& __x
, shared_ptr
<_Up
> const& __y
) const _NOEXCEPT
{
1533 return __x
.owner_before(__y
);
1535 template <class _Tp
, class _Up
>
1536 _LIBCPP_HIDE_FROM_ABI
bool operator()(weak_ptr
<_Tp
> const& __x
, weak_ptr
<_Up
> const& __y
) const _NOEXCEPT
{
1537 return __x
.owner_before(__y
);
1539 typedef void is_transparent
;
1543 template <class _Tp
>
1544 class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
{
1545 mutable weak_ptr
<_Tp
> __weak_this_
;
1548 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
enable_shared_from_this() _NOEXCEPT
{}
1549 _LIBCPP_HIDE_FROM_ABI
enable_shared_from_this(enable_shared_from_this
const&) _NOEXCEPT
{}
1550 _LIBCPP_HIDE_FROM_ABI enable_shared_from_this
& operator=(enable_shared_from_this
const&) _NOEXCEPT
{ return *this; }
1551 _LIBCPP_HIDE_FROM_ABI
~enable_shared_from_this() {}
1554 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> shared_from_this() { return shared_ptr
<_Tp
>(__weak_this_
); }
1555 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
const> shared_from_this() const { return shared_ptr
<const _Tp
>(__weak_this_
); }
1557 #if _LIBCPP_STD_VER >= 17
1558 _LIBCPP_HIDE_FROM_ABI weak_ptr
<_Tp
> weak_from_this() _NOEXCEPT
{ return __weak_this_
; }
1560 _LIBCPP_HIDE_FROM_ABI weak_ptr
<const _Tp
> weak_from_this() const _NOEXCEPT
{ return __weak_this_
; }
1561 #endif // _LIBCPP_STD_VER >= 17
1563 template <class _Up
>
1564 friend class shared_ptr
;
1567 template <class _Tp
>
1568 struct _LIBCPP_TEMPLATE_VIS hash
;
1570 template <class _Tp
>
1571 struct _LIBCPP_TEMPLATE_VIS hash
<shared_ptr
<_Tp
> > {
1572 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1573 _LIBCPP_DEPRECATED_IN_CXX17
typedef shared_ptr
<_Tp
> argument_type
;
1574 _LIBCPP_DEPRECATED_IN_CXX17
typedef size_t result_type
;
1577 _LIBCPP_HIDE_FROM_ABI
size_t operator()(const shared_ptr
<_Tp
>& __ptr
) const _NOEXCEPT
{
1578 return hash
<typename shared_ptr
<_Tp
>::element_type
*>()(__ptr
.get());
1582 template <class _CharT
, class _Traits
, class _Yp
>
1583 inline _LIBCPP_HIDE_FROM_ABI basic_ostream
<_CharT
, _Traits
>&
1584 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
, shared_ptr
<_Yp
> const& __p
);
1586 #if !defined(_LIBCPP_HAS_NO_THREADS)
1588 class _LIBCPP_EXPORTED_FROM_ABI __sp_mut
{
1592 void lock() _NOEXCEPT
;
1593 void unlock() _NOEXCEPT
;
1596 _LIBCPP_CONSTEXPR
__sp_mut(void*) _NOEXCEPT
;
1597 __sp_mut(const __sp_mut
&);
1598 __sp_mut
& operator=(const __sp_mut
&);
1600 friend _LIBCPP_EXPORTED_FROM_ABI __sp_mut
& __get_sp_mut(const void*);
1603 _LIBCPP_EXPORTED_FROM_ABI __sp_mut
& __get_sp_mut(const void*);
1605 template <class _Tp
>
1606 inline _LIBCPP_HIDE_FROM_ABI
bool atomic_is_lock_free(const shared_ptr
<_Tp
>*) {
1610 template <class _Tp
>
1611 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> atomic_load(const shared_ptr
<_Tp
>* __p
) {
1612 __sp_mut
& __m
= std::__get_sp_mut(__p
);
1614 shared_ptr
<_Tp
> __q
= *__p
;
1619 template <class _Tp
>
1620 inline _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> atomic_load_explicit(const shared_ptr
<_Tp
>* __p
, memory_order
) {
1621 return std::atomic_load(__p
);
1624 template <class _Tp
>
1625 _LIBCPP_HIDE_FROM_ABI
void atomic_store(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
) {
1626 __sp_mut
& __m
= std::__get_sp_mut(__p
);
1632 template <class _Tp
>
1633 inline _LIBCPP_HIDE_FROM_ABI
void atomic_store_explicit(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
, memory_order
) {
1634 std::atomic_store(__p
, __r
);
1637 template <class _Tp
>
1638 _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
> atomic_exchange(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
) {
1639 __sp_mut
& __m
= std::__get_sp_mut(__p
);
1646 template <class _Tp
>
1647 inline _LIBCPP_HIDE_FROM_ABI shared_ptr
<_Tp
>
1648 atomic_exchange_explicit(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
> __r
, memory_order
) {
1649 return std::atomic_exchange(__p
, __r
);
1652 template <class _Tp
>
1653 _LIBCPP_HIDE_FROM_ABI
bool
1654 atomic_compare_exchange_strong(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
, shared_ptr
<_Tp
> __w
) {
1655 shared_ptr
<_Tp
> __temp
;
1656 __sp_mut
& __m
= std::__get_sp_mut(__p
);
1658 if (__p
->__owner_equivalent(*__v
)) {
1659 std::swap(__temp
, *__p
);
1664 std::swap(__temp
, *__v
);
1670 template <class _Tp
>
1671 inline _LIBCPP_HIDE_FROM_ABI
bool
1672 atomic_compare_exchange_weak(shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
, shared_ptr
<_Tp
> __w
) {
1673 return std::atomic_compare_exchange_strong(__p
, __v
, __w
);
1676 template <class _Tp
>
1677 inline _LIBCPP_HIDE_FROM_ABI
bool atomic_compare_exchange_strong_explicit(
1678 shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
, shared_ptr
<_Tp
> __w
, memory_order
, memory_order
) {
1679 return std::atomic_compare_exchange_strong(__p
, __v
, __w
);
1682 template <class _Tp
>
1683 inline _LIBCPP_HIDE_FROM_ABI
bool atomic_compare_exchange_weak_explicit(
1684 shared_ptr
<_Tp
>* __p
, shared_ptr
<_Tp
>* __v
, shared_ptr
<_Tp
> __w
, memory_order
, memory_order
) {
1685 return std::atomic_compare_exchange_weak(__p
, __v
, __w
);
1688 #endif // !defined(_LIBCPP_HAS_NO_THREADS)
1690 _LIBCPP_END_NAMESPACE_STD
1694 #endif // _LIBCPP___MEMORY_SHARED_PTR_H