1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
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
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_SHARED_PTR_H
11#define _LIBCPP___MEMORY_SHARED_PTR_H
12
13#include <__atomic/memory_order.h>
14#include <__compare/compare_three_way.h>
15#include <__compare/ordering.h>
16#include <__config>
17#include <__cstddef/nullptr_t.h>
18#include <__cstddef/ptrdiff_t.h>
19#include <__exception/exception.h>
20#include <__functional/binary_function.h>
21#include <__functional/hash.h>
22#include <__functional/operations.h>
23#include <__functional/reference_wrapper.h>
24#include <__fwd/ostream.h>
25#include <__iterator/access.h>
26#include <__memory/addressof.h>
27#include <__memory/allocation_guard.h>
28#include <__memory/allocator.h>
29#include <__memory/allocator_destructor.h>
30#include <__memory/allocator_traits.h>
31#include <__memory/auto_ptr.h>
32#include <__memory/construct_at.h>
33#include <__memory/destroy.h>
34#include <__memory/pointer_traits.h>
35#include <__memory/shared_count.h>
36#include <__memory/uninitialized_algorithms.h>
37#include <__memory/uninitialized_multidimensional_algorithms.h>
38#include <__memory/unique_ptr.h>
39#include <__new/exceptions.h>
40#include <__type_traits/add_reference.h>
41#include <__type_traits/conditional.h>
42#include <__type_traits/conjunction.h>
43#include <__type_traits/enable_if.h>
44#include <__type_traits/is_array.h>
45#include <__type_traits/is_constructible.h>
46#include <__type_traits/is_convertible.h>
47#include <__type_traits/is_function.h>
48#include <__type_traits/is_reference.h>
49#include <__type_traits/is_same.h>
50#include <__type_traits/nat.h>
51#include <__type_traits/remove_cv.h>
52#include <__type_traits/remove_extent.h>
53#include <__type_traits/remove_pointer.h>
54#include <__type_traits/remove_reference.h>
55#include <__type_traits/void_t.h>
56#include <__utility/declval.h>
57#include <__utility/exception_guard.h>
58#include <__utility/forward.h>
59#include <__utility/move.h>
60#include <__utility/swap.h>
61#include <__verbose_abort>
62#include <typeinfo>
63
64#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
65# pragma GCC system_header
66#endif
67
68_LIBCPP_PUSH_MACROS
69#include <__undef_macros>
70
71_LIBCPP_BEGIN_NAMESPACE_STD
72_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
73
74class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr : public std::exception {
75public:
76 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr() _NOEXCEPT = default;
77 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
78 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr& operator=(const bad_weak_ptr&) _NOEXCEPT = default;
79 ~bad_weak_ptr() _NOEXCEPT override;
80 [[__nodiscard__]] const char* what() const _NOEXCEPT override;
81};
82
83[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_weak_ptr() {
84#if _LIBCPP_HAS_EXCEPTIONS
85 throw bad_weak_ptr();
86#else
87 _LIBCPP_VERBOSE_ABORT("bad_weak_ptr was thrown in -fno-exceptions mode");
88#endif
89}
90
91template <class _Tp>
92class weak_ptr;
93
94template <class _Tp, class _Dp, class _Alloc>
95class _LIBCPP_HIDE_STRUCT_FROM_ABI __shared_ptr_pointer final : public __shared_weak_count {
96 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
97 _LIBCPP_NO_UNIQUE_ADDRESS _Dp __deleter_;
98 _LIBCPP_NO_UNIQUE_ADDRESS _Tp __ptr_;
99
100public:
101 _LIBCPP_HIDE_FROM_ABI __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
102 : __alloc_(std::move(__a)), __deleter_(std::move(__d)), __ptr_(__p) {}
103
104#if _LIBCPP_HAS_RTTI
105 _LIBCPP_HIDE_FROM_ABI_VIRTUAL const void* __get_deleter(const type_info& __t) const _NOEXCEPT override {
106 return __t == typeid(_Dp) ? std::addressof(__deleter_) : nullptr;
107 }
108#endif
109
110private:
111 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
112 __deleter_(__ptr_);
113 __ptr_.~_Tp();
114 __deleter_.~_Dp();
115 }
116
117 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
118 using __alloc_t = __allocator_traits_rebind_t<_Alloc, __shared_ptr_pointer>;
119
120 __alloc_t __a(__alloc_);
121 __alloc_.~_Alloc();
122 __a.deallocate(pointer_traits<typename allocator_traits<__alloc_t>::pointer>::pointer_to(*this), 1);
123 }
124};
125
126// This tag is used to instantiate an allocator type. The various shared_ptr control blocks
127// detect that the allocator has been instantiated for this type and perform alternative
128// initialization/destruction based on that.
129struct __for_overwrite_tag {};
130
131template <class _Tp, class _Alloc>
132struct _LIBCPP_HIDE_STRUCT_FROM_ABI __shared_ptr_emplace : __shared_weak_count {
133 using __alloc_traits _LIBCPP_NODEBUG = allocator_traits<_Alloc>;
134 using __value_type _LIBCPP_NODEBUG = __remove_cv_t<_Tp>;
135
136 template <class... _Args>
137 _LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&... __args) : __alloc_(std::move(__a)) {
138 allocator_traits<_Alloc>::construct(__alloc_, __get_elem(), std::forward<_Args>(__args)...);
139 }
140
141 _LIBCPP_HIDE_FROM_ABI __value_type* __get_elem() _NOEXCEPT { return reinterpret_cast<__value_type*>(__buffer_); }
142
143private:
144 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
145 allocator_traits<_Alloc>::destroy(__alloc_, __get_elem());
146 }
147
148 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
149 using __alloc_t = __allocator_traits_rebind_t<_Alloc, __shared_ptr_emplace>;
150 __alloc_t __tmp(__alloc_);
151 __alloc_.~_Alloc();
152 allocator_traits<__alloc_t>::deallocate(
153 __tmp, pointer_traits<typename allocator_traits<__alloc_t>::pointer>::pointer_to(*this), 1);
154 }
155
156 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
157 _ALIGNAS_TYPE(__value_type) char __buffer_[sizeof(__value_type)];
158};
159
160template <class _Tp, class _Alloc>
161struct _LIBCPP_HIDE_STRUCT_FROM_ABI __shared_ptr_emplace_for_overwrite : __shared_weak_count {
162 using __value_type _LIBCPP_NODEBUG = __remove_cv_t<_Tp>;
163
164 _LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace_for_overwrite(_Alloc __a) : __alloc_(std::move(__a)) {}
165
166 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { __value_.~__value_type(); }
167 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
168 using __alloc_t = __allocator_traits_rebind_t<_Alloc, __shared_ptr_emplace_for_overwrite>;
169 using __alloc_traits = allocator_traits<__alloc_t>;
170 __alloc_t __tmp(__alloc_);
171 __alloc_.~_Alloc();
172 __alloc_traits::deallocate(__tmp, pointer_traits<typename __alloc_traits::pointer>::pointer_to(*this), 1);
173 }
174
175 _LIBCPP_HIDE_FROM_ABI __value_type* __get_elem() _NOEXCEPT { return std::addressof(__value_); }
176
177private:
178 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
179 _LIBCPP_NO_UNIQUE_ADDRESS __value_type __value_;
180};
181
182struct __shared_ptr_dummy_rebind_allocator_type;
183template <>
184class allocator<__shared_ptr_dummy_rebind_allocator_type> {
185public:
186 template <class _Other>
187 struct rebind {
188 typedef allocator<_Other> other;
189 };
190};
191
192template <class _Tp>
193class enable_shared_from_this;
194
195// http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.general-6
196// A pointer type Y* is said to be compatible with a pointer type T*
197// when either Y* is convertible to T* or Y is U[N] and T is cv U[].
198#if _LIBCPP_STD_VER >= 17
199template <class _Yp, class _Tp>
200inline const bool __bounded_convertible_to_unbounded_v = false;
201
202template <class _Up, std::size_t _Np, class _Tp>
203inline const bool __bounded_convertible_to_unbounded_v<_Up[_Np], _Tp> = is_same_v<remove_cv_t<_Tp>, _Up[]>;
204
205template <class _Yp, class _Tp>
206inline const bool __compatible_with_v = is_convertible_v<_Yp*, _Tp*> || __bounded_convertible_to_unbounded_v<_Yp, _Tp>;
207#else
208template <class _Yp, class _Tp>
209inline const bool __compatible_with_v = is_convertible<_Yp*, _Tp*>::value;
210#endif // _LIBCPP_STD_VER >= 17
211
212// Constructors that take raw pointers have a different set of "compatible" constraints
213// http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.const-9.1
214// - If T is an array type, then either T is U[N] and Y(*)[N] is convertible to T*,
215// or T is U[] and Y(*)[] is convertible to T*.
216// - If T is not an array type, then Y* is convertible to T*.
217#if _LIBCPP_STD_VER >= 17
218template <class _Yp, class _Tp, class = void>
219inline const bool __raw_pointer_compatible_with_v = !is_array_v<_Tp> && is_convertible_v<_Yp*, _Tp*>;
220
221template <class _Yp, class _Up, std::size_t _Np>
222inline const bool
223 __raw_pointer_compatible_with_v<_Yp, _Up[_Np], enable_if_t<is_convertible_v<_Yp (*)[_Np], _Up (*)[_Np]>>> = true;
224
225template <class _Yp, class _Up>
226inline const bool __raw_pointer_compatible_with_v<_Yp, _Up[], enable_if_t<is_convertible_v<_Yp (*)[], _Up (*)[]>>> =
227 true;
228
229#else
230template <class _Yp, class _Tp>
231inline const bool __raw_pointer_compatible_with_v = is_convertible<_Yp*, _Tp*>::value;
232#endif // _LIBCPP_STD_VER >= 17
233
234template <class _Ptr, class = void>
235inline const bool __is_deletable_v = false;
236template <class _Ptr>
237inline const bool __is_deletable_v<_Ptr, decltype(delete std::declval<_Ptr>())> = true;
238
239template <class _Ptr, class = void>
240inline const bool __is_array_deletable_v = false;
241template <class _Ptr>
242inline const bool __is_array_deletable_v<_Ptr, decltype(delete[] std::declval<_Ptr>())> = true;
243
244template <class _Dp, class _Pt, class = void>
245inline const bool __well_formed_deleter_v = false;
246
247template <class _Dp, class _Pt>
248inline const bool __well_formed_deleter_v<_Dp, _Pt, __void_t<decltype(std::declval<_Dp>()(std::declval<_Pt>()))> > =
249 true;
250
251template <class _Dp, class _Yp, class _Tp>
252inline const bool __shared_ptr_deleter_ctor_reqs_v =
253 __raw_pointer_compatible_with_v<_Yp, _Tp> && is_move_constructible<_Dp>::value &&
254 __well_formed_deleter_v<_Dp, _Yp*>;
255
256template <class _Dp>
257inline const bool __shared_ptr_nullptr_deleter_ctor_reqs_v =
258 is_move_constructible<_Dp>::value && __well_formed_deleter_v<_Dp, nullptr_t>;
259
260#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
261# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
262#else
263# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
264#endif
265
266template <class _Tp>
267class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
268 struct __nullptr_sfinae_tag {};
269
270public:
271#if _LIBCPP_STD_VER >= 17
272 typedef weak_ptr<_Tp> weak_type;
273 typedef remove_extent_t<_Tp> element_type;
274#else
275 typedef _Tp element_type;
276#endif
277
278 // A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
279 // any bookkeeping, so it's always trivially relocatable.
280 using __trivially_relocatable _LIBCPP_NODEBUG = shared_ptr;
281
282private:
283 element_type* __ptr_;
284 __shared_weak_count* __cntrl_;
285
286public:
287 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {}
288
289 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {}
290
291 template <class _Yp,
292 __enable_if_t<__raw_pointer_compatible_with_v<_Yp, _Tp>
293 // In C++03 we get errors when trying to do SFINAE with the
294 // delete operator, so we always pretend that it's deletable.
295 // The same happens on GCC.
296#if !defined(_LIBCPP_CXX03_LANG)
297 && (is_array<_Tp>::value ? __is_array_deletable_v<_Yp*> : __is_deletable_v<_Yp*>)
298#endif
299 ,
300 int> = 0>
301 _LIBCPP_HIDE_FROM_ABI explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
302 unique_ptr<_Yp> __hold(__p);
303 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
304 typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT> _CntrlBlk;
305 __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
306 __hold.release();
307 __enable_weak_this(__p, __p);
308 }
309
310 template <class _Yp, class _Dp, __enable_if_t<__shared_ptr_deleter_ctor_reqs_v<_Dp, _Yp, _Tp>, int> = 0>
311 _LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d) : __ptr_(__p) {
312 auto __guard = std::__make_exception_guard([&] { __d(__p); });
313 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
314 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk;
315#ifndef _LIBCPP_CXX03_LANG
316 __cntrl_ = new _CntrlBlk(__p, std::move(__d), _AllocT());
317#else
318 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
319#endif // not _LIBCPP_CXX03_LANG
320 __enable_weak_this(__p, __p);
321 __guard.__complete();
322 }
323
324 template <class _Yp, class _Dp, class _Alloc, __enable_if_t<__shared_ptr_deleter_ctor_reqs_v<_Dp, _Yp, _Tp>, int> = 0>
325 _LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d, _Alloc __a) : __ptr_(__p) {
326 auto __guard = std::__make_exception_guard([&] { __d(__p); });
327 typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
328 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
329 typedef __allocator_destructor<_A2> _D2;
330 _A2 __a2(__a);
331 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
332 ::new ((void*)std::addressof(*__hold2.get()))
333#ifndef _LIBCPP_CXX03_LANG
334 _CntrlBlk(__p, std::move(__d), __a);
335#else
336 _CntrlBlk(__p, __d, __a);
337#endif // not _LIBCPP_CXX03_LANG
338 __cntrl_ = std::addressof(*__hold2.release());
339 __enable_weak_this(__p, __p);
340 __guard.__complete();
341 }
342
343 template <class _Dp>
344 _LIBCPP_HIDE_FROM_ABI shared_ptr(
345 nullptr_t __p,
346 _Dp __d,
347 __enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs_v<_Dp>, __nullptr_sfinae_tag> = __nullptr_sfinae_tag())
348 : __ptr_(nullptr) {
349 auto __guard = std::__make_exception_guard([&] { __d(__p); });
350 typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
351 typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk;
352#ifndef _LIBCPP_CXX03_LANG
353 __cntrl_ = new _CntrlBlk(__p, std::move(__d), _AllocT());
354#else
355 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
356#endif // not _LIBCPP_CXX03_LANG
357 __guard.__complete();
358 }
359
360 template <class _Dp, class _Alloc>
361 _LIBCPP_HIDE_FROM_ABI shared_ptr(
362 nullptr_t __p,
363 _Dp __d,
364 _Alloc __a,
365 __enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs_v<_Dp>, __nullptr_sfinae_tag> = __nullptr_sfinae_tag())
366 : __ptr_(nullptr) {
367 auto __guard = std::__make_exception_guard([&] { __d(__p); });
368 typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
369 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
370 typedef __allocator_destructor<_A2> _D2;
371 _A2 __a2(__a);
372 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
373 ::new ((void*)std::addressof(*__hold2.get()))
374#ifndef _LIBCPP_CXX03_LANG
375 _CntrlBlk(__p, std::move(__d), __a);
376#else
377 _CntrlBlk(__p, __d, __a);
378#endif // not _LIBCPP_CXX03_LANG
379 __cntrl_ = std::addressof(*__hold2.release());
380 __guard.__complete();
381 }
382
383 template <class _Yp>
384 _LIBCPP_HIDE_FROM_ABI shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT
385 : __ptr_(__p),
386 __cntrl_(__r.__cntrl_) {
387 if (__cntrl_)
388 __cntrl_->__add_shared();
389 }
390
391// LWG-2996
392// We don't backport because it is an evolutionary change.
393#if _LIBCPP_STD_VER >= 20
394 template <class _Yp>
395 _LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept
396 : __ptr_(__p), __cntrl_(__r.__cntrl_) {
397 __r.__ptr_ = nullptr;
398 __r.__cntrl_ = nullptr;
399 }
400#endif
401
402 _LIBCPP_HIDE_FROM_ABI shared_ptr(const shared_ptr& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {
403 if (__cntrl_)
404 __cntrl_->__add_shared();
405 }
406
407 template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
408 _LIBCPP_HIDE_FROM_ABI shared_ptr(const shared_ptr<_Yp>& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {
409 if (__cntrl_)
410 __cntrl_->__add_shared();
411 }
412
413 _LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr&& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {
414 __r.__ptr_ = nullptr;
415 __r.__cntrl_ = nullptr;
416 }
417
418 template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
419 _LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr<_Yp>&& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {
420 __r.__ptr_ = nullptr;
421 __r.__cntrl_ = nullptr;
422 }
423
424 template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
425 _LIBCPP_HIDE_FROM_ABI explicit shared_ptr(const weak_ptr<_Yp>& __r)
426 : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_) {
427 if (__cntrl_ == nullptr)
428 std::__throw_bad_weak_ptr();
429 }
430
431#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
432 template <class _Yp, __enable_if_t<is_convertible<_Yp*, element_type*>::value, int> = 0>
433 _LIBCPP_HIDE_FROM_ABI shared_ptr(auto_ptr<_Yp>&& __r) : __ptr_(__r.get()) {
434 typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<__remove_cv_t<_Yp> > > _CntrlBlk;
435 __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<__remove_cv_t<_Yp> >());
436 __enable_weak_this(__r.get(), __r.get());
437 __r.release();
438 }
439#endif
440
441 template <class _Yp,
442 class _Dp,
443 __enable_if_t<__compatible_with_v<_Yp, _Tp> &&
444 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
445 int> = 0>
446 _LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) : __ptr_(__r.get()) {
447 using _AllocT = typename __shared_ptr_default_allocator<_Yp>::type;
448 using _Deleter = _If<is_lvalue_reference<_Dp>::value, reference_wrapper<__libcpp_remove_reference_t<_Dp> >, _Dp>;
449 using _CntrlBlk = __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Deleter, _AllocT>;
450
451 __cntrl_ = __ptr_ ? new _CntrlBlk(__r.get(), std::forward<_Dp>(__r.get_deleter()), _AllocT()) : nullptr;
452 __enable_weak_this(__r.get(), __r.get());
453 __r.release();
454 }
455
456 _LIBCPP_HIDE_FROM_ABI ~shared_ptr() {
457 if (__cntrl_)
458 __cntrl_->__release_shared();
459 }
460
461 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(const shared_ptr& __r) _NOEXCEPT {
462 shared_ptr(__r).swap(r&: *this);
463 return *this;
464 }
465
466 template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
467 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT {
468 shared_ptr(__r).swap(r&: *this);
469 return *this;
470 }
471
472 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(shared_ptr&& __r) _NOEXCEPT {
473 shared_ptr(std::move(__r)).swap(r&: *this);
474 return *this;
475 }
476
477 template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
478 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(shared_ptr<_Yp>&& __r) _NOEXCEPT {
479 shared_ptr(std::move(__r)).swap(r&: *this);
480 return *this;
481 }
482
483#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
484 template <class _Yp,
485 __enable_if_t<!is_array<_Yp>::value && is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
486 int> = 0>
487 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(auto_ptr<_Yp>&& __r) {
488 shared_ptr(std::move(__r)).swap(*this);
489 return *this;
490 }
491#endif
492
493 template <class _Yp,
494 class _Dp,
495 __enable_if_t<__compatible_with_v<_Yp, _Tp> &&
496 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
497 int> = 0>
498 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(unique_ptr<_Yp, _Dp>&& __r) {
499 shared_ptr(std::move(__r)).swap(r&: *this);
500 return *this;
501 }
502
503 _LIBCPP_HIDE_FROM_ABI void swap(shared_ptr& __r) _NOEXCEPT {
504 std::swap(__ptr_, __r.__ptr_);
505 std::swap(x&: __cntrl_, y&: __r.__cntrl_);
506 }
507
508 _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT { shared_ptr().swap(r&: *this); }
509
510 template <class _Yp, __enable_if_t<__raw_pointer_compatible_with_v<_Yp, _Tp>, int> = 0>
511 _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p) {
512 shared_ptr(__p).swap(r&: *this);
513 }
514
515 template <class _Yp, class _Dp, __enable_if_t<__shared_ptr_deleter_ctor_reqs_v<_Dp, _Yp, _Tp>, int> = 0>
516 _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p, _Dp __d) {
517 shared_ptr(__p, __d).swap(r&: *this);
518 }
519
520 template <class _Yp, class _Dp, class _Alloc, __enable_if_t<__shared_ptr_deleter_ctor_reqs_v<_Dp, _Yp, _Tp>, int> = 0>
521 _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p, _Dp __d, _Alloc __a) {
522 shared_ptr(__p, __d, __a).swap(r&: *this);
523 }
524
525 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; }
526
527 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT {
528 return *__ptr_;
529 }
530
531 _LIBCPP_HIDE_FROM_ABI element_type* operator->() const _NOEXCEPT {
532 static_assert(!is_array<_Tp>::value, "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
533 return __ptr_;
534 }
535
536 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT {
537 return __cntrl_ ? __cntrl_->use_count() : 0;
538 }
539
540#if _LIBCPP_STD_VER < 20 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE)
541 [[__nodiscard__]] _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT {
542 return use_count() == 1;
543 }
544#endif
545
546 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return get() != nullptr; }
547
548 template <class _Up>
549 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT {
550 return __cntrl_ < __p.__cntrl_;
551 }
552
553 template <class _Up>
554 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT {
555 return __cntrl_ < __p.__cntrl_;
556 }
557
558 _LIBCPP_HIDE_FROM_ABI bool __owner_equivalent(const shared_ptr& __p) const { return __cntrl_ == __p.__cntrl_; }
559
560#if _LIBCPP_STD_VER >= 26
561 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t owner_hash() const noexcept {
562 return std::hash<__shared_weak_count*>()(__cntrl_);
563 }
564
565 template <class _Up>
566 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(shared_ptr<_Up> const& __p) const noexcept {
567 return __cntrl_ == __p.__cntrl_;
568 }
569
570 template <class _Up>
571 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(weak_ptr<_Up> const& __p) const noexcept {
572 return __cntrl_ == __p.__cntrl_;
573 }
574#endif
575
576#if _LIBCPP_STD_VER >= 17
577 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const {
578 static_assert(is_array<_Tp>::value, "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
579 return __ptr_[__i];
580 }
581#endif
582
583#if _LIBCPP_HAS_RTTI
584 template <class _Dp>
585 _LIBCPP_HIDE_FROM_ABI _Dp* __get_deleter() const _NOEXCEPT {
586 return static_cast<_Dp*>(__cntrl_ ? const_cast<void*>(__cntrl_->__get_deleter(typeid(_Dp))) : nullptr);
587 }
588#endif // _LIBCPP_HAS_RTTI
589
590 template <class _Yp, class _CntrlBlk>
591 _LIBCPP_HIDE_FROM_ABI static shared_ptr<_Tp> __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT {
592 shared_ptr<_Tp> __r;
593 __r.__ptr_ = __p;
594 __r.__cntrl_ = __cntrl;
595 __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
596 return __r;
597 }
598
599private:
600 template <class _Yp, bool = is_function<_Yp>::value>
601 struct __shared_ptr_default_allocator {
602 typedef allocator<__remove_cv_t<_Yp> > type;
603 };
604
605 template <class _Yp>
606 struct __shared_ptr_default_allocator<_Yp, true> {
607 typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
608 };
609
610 template <class _Yp,
611 class _OrigPtr,
612 __enable_if_t<is_convertible<_OrigPtr*, const enable_shared_from_this<_Yp>*>::value, int> = 0>
613 _LIBCPP_HIDE_FROM_ABI void __enable_weak_this(const enable_shared_from_this<_Yp>* __e, _OrigPtr* __ptr) _NOEXCEPT {
614 typedef __remove_cv_t<_Yp> _RawYp;
615 if (__e && __e->__weak_this_.expired()) {
616 __e->__weak_this_ = shared_ptr<_RawYp>(*this, const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
617 }
618 }
619
620 template <class _Vp>
621 static __type_identity<_Vp> __get_shared_from_this_impl(const enable_shared_from_this<_Vp>*);
622
623 template <class _Vp, class = void>
624 struct __get_shared_from_this {
625 using type _LIBCPP_NODEBUG = __nat;
626 };
627
628 template <class _Vp>
629 struct __get_shared_from_this<_Vp, __void_t<decltype(__get_shared_from_this_impl(static_cast<_Vp*>(nullptr)))> > {
630 using type _LIBCPP_NODEBUG = const enable_shared_from_this<typename decltype(__get_shared_from_this_impl(
631 static_cast<_Vp*>(nullptr)))::type>*;
632 };
633
634 template <
635 class _Yp,
636 class _OrigPtr,
637 __enable_if_t<!is_convertible<_OrigPtr, typename __get_shared_from_this<__remove_pointer_t<_Yp> >::type>::value,
638 int> = 0>
639 _LIBCPP_HIDE_FROM_ABI void __enable_weak_this(_Yp, _OrigPtr) {}
640
641 template <class, class _Yp>
642 struct __shared_ptr_default_delete : default_delete<_Yp> {};
643
644 template <class _Yp, class _Un, size_t _Sz>
645 struct __shared_ptr_default_delete<_Yp[_Sz], _Un> : default_delete<_Yp[]> {};
646
647 template <class _Yp, class _Un>
648 struct __shared_ptr_default_delete<_Yp[], _Un> : default_delete<_Yp[]> {};
649
650 template <class _Up>
651 friend class shared_ptr;
652 template <class _Up>
653 friend class weak_ptr;
654};
655
656#if _LIBCPP_STD_VER >= 17
657template <class _Tp>
658shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
659template <class _Tp, class _Dp>
660shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
661#endif
662
663//
664// std::allocate_shared and std::make_shared
665//
666
667template <class _ControlBlock, class _Tp, class _Alloc, class... _Args>
668_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> __allocate_shared_impl(const _Alloc& __alloc, _Args&&... __args) {
669 using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
670 __allocation_guard<_ControlBlockAllocator> __guard(__alloc, 1);
671 ::new ((void*)std::addressof(*__guard.__get())) _ControlBlock(__alloc, std::forward<_Args>(__args)...);
672 auto __control_block = __guard.__release_ptr();
673 return shared_ptr<_Tp>::__create_with_control_block(
674 __control_block->__get_elem(), std::__to_address(__control_block));
675}
676
677template <class _Tp, class _Alloc, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>
678[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) {
679 using _CanonicalAlloc = __allocator_traits_rebind_t<_Alloc, __remove_cv_t<_Tp> >;
680 using _ControlBlock = __shared_ptr_emplace<_Tp, _CanonicalAlloc>;
681 return std::__allocate_shared_impl<_ControlBlock, _Tp>(_CanonicalAlloc(__a), std::forward<_Args>(__args)...);
682}
683
684template <class _Tp, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>
685[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) {
686 return std::allocate_shared<_Tp>(allocator<__remove_cv_t<_Tp> >(), std::forward<_Args>(__args)...);
687}
688
689#if _LIBCPP_STD_VER >= 20
690
691template <class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0>
692[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
693 using _CanonicalAlloc = __allocator_traits_rebind_t<_Alloc, remove_cv_t<_Tp>>;
694 using _ControlBlock = __shared_ptr_emplace_for_overwrite<_Tp, _CanonicalAlloc>;
695 return std::__allocate_shared_impl<_ControlBlock, _Tp>(_CanonicalAlloc(__a));
696}
697
698template <class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
699[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
700 return std::allocate_shared_for_overwrite<_Tp>(allocator<__remove_cv_t<_Tp>>());
701}
702
703#endif // _LIBCPP_STD_VER >= 20
704
705#if _LIBCPP_STD_VER >= 17
706
707template <size_t _Alignment>
708struct __sp_aligned_storage {
709 alignas(_Alignment) char __storage[_Alignment];
710};
711
712template <class _Tp, class _Alloc>
713struct __unbounded_array_control_block;
714
715template <class _Tp, class _Alloc>
716struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count {
717 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* __get_data() noexcept { return __data_; }
718
719 _LIBCPP_HIDE_FROM_ABI explicit __unbounded_array_control_block(
720 _Alloc const& __alloc, size_t __count, _Tp const& __arg)
721 : __alloc_(__alloc), __count_(__count) {
722 std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::begin(__data_), __count_, __arg);
723 }
724
725 _LIBCPP_HIDE_FROM_ABI explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count)
726 : __alloc_(__alloc), __count_(__count) {
727# if _LIBCPP_STD_VER >= 20
728 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
729 // We are purposefully not using an allocator-aware default construction because the spec says so.
730 // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
731 std::uninitialized_default_construct_n(std::begin(__data_), __count_);
732 } else {
733 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_);
734 }
735# else
736 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_);
737# endif
738 }
739
740 // Returns the number of bytes required to store a control block followed by the given number
741 // of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment.
742 //
743 // Throws std::bad_array_new_length if that number of bytes is not representable as a size_t.
744 _LIBCPP_HIDE_FROM_ABI static constexpr size_t __bytes_for(size_t __elements) {
745 constexpr size_t __align = alignof(__unbounded_array_control_block);
746
747 // When there's 0 elements, the control block alone is enough since it holds one element.
748 // Otherwise, we allocate one fewer element than requested because the control block already
749 // holds one.
750 size_t __bytes = sizeof(__unbounded_array_control_block);
751 if (__elements != 0) {
752 if (__builtin_mul_overflow(__elements - 1, sizeof(_Tp), &__bytes) ||
753 __builtin_add_overflow(__bytes, sizeof(__unbounded_array_control_block), &__bytes))
754 std::__throw_bad_array_new_length();
755 }
756
757 // We use the bitwise formula below to ensure that we allocate enough bytes for the whole
758 // allocation to be a multiple of _Tp's alignment. That formula is taken from [1].
759 //
760 // [1]: https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding
761 if (__builtin_add_overflow(__bytes, __align - 1, &__bytes))
762 std::__throw_bad_array_new_length();
763 return __bytes & ~(__align - 1);
764 }
765
766 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
767 ~__unbounded_array_control_block() override {
768 } // can't be `= default` because of the sometimes-non-trivial union member __data_
769
770private:
771 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
772# if _LIBCPP_STD_VER >= 20
773 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
774 std::__reverse_destroy(__data_, __data_ + __count_);
775 } else {
776 __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
777 std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_);
778 }
779# else
780 __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
781 std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_);
782# endif
783 }
784
785 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
786 using _AlignedStorage = __sp_aligned_storage<alignof(__unbounded_array_control_block)>;
787 using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>;
788 using _PointerTraits = pointer_traits<typename allocator_traits<_StorageAlloc>::pointer>;
789
790 _StorageAlloc __tmp(__alloc_);
791 __alloc_.~_Alloc();
792 size_t __size = __unbounded_array_control_block::__bytes_for(elements: __count_);
793 _AlignedStorage* __storage = reinterpret_cast<_AlignedStorage*>(this);
794 allocator_traits<_StorageAlloc>::deallocate(
795 __tmp, _PointerTraits::pointer_to(*__storage), __size / sizeof(_AlignedStorage));
796 }
797
798 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
799 size_t __count_;
800 union {
801 _Tp __data_[1];
802 };
803};
804
805template <class _Array, class _Alloc, class... _Arg>
806_LIBCPP_HIDE_FROM_ABI shared_ptr<_Array>
807__allocate_shared_unbounded_array(const _Alloc& __a, size_t __n, _Arg&&... __arg) {
808 static_assert(__is_unbounded_array_v<_Array>);
809 // We compute the number of bytes necessary to hold the control block and the
810 // array elements. Then, we allocate an array of properly-aligned dummy structs
811 // large enough to hold the control block and array. This allows shifting the
812 // burden of aligning memory properly from us to the allocator.
813 using _ControlBlock = __unbounded_array_control_block<_Array, _Alloc>;
814 using _AlignedStorage = __sp_aligned_storage<alignof(_ControlBlock)>;
815 using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>;
816 __allocation_guard<_StorageAlloc> __guard(__a, _ControlBlock::__bytes_for(__n) / sizeof(_AlignedStorage));
817 _ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get()));
818 std::__construct_at(__control_block, __a, __n, std::forward<_Arg>(__arg)...);
819 __guard.__release_ptr();
820 return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
821}
822
823template <class _Tp, class _Alloc>
824struct __bounded_array_control_block;
825
826template <class _Tp, size_t _Count, class _Alloc>
827struct __bounded_array_control_block<_Tp[_Count], _Alloc> : __shared_weak_count {
828 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* __get_data() noexcept { return __data_; }
829
830 _LIBCPP_HIDE_FROM_ABI explicit __bounded_array_control_block(_Alloc const& __alloc, _Tp const& __arg)
831 : __alloc_(__alloc) {
832 std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count, __arg);
833 }
834
835 _LIBCPP_HIDE_FROM_ABI explicit __bounded_array_control_block(_Alloc const& __alloc) : __alloc_(__alloc) {
836# if _LIBCPP_STD_VER >= 20
837 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
838 // We are purposefully not using an allocator-aware default construction because the spec says so.
839 // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
840 std::uninitialized_default_construct_n(std::addressof(__data_[0]), _Count);
841 } else {
842 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count);
843 }
844# else
845 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count);
846# endif
847 }
848
849 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
850 ~__bounded_array_control_block() override {
851 } // can't be `= default` because of the sometimes-non-trivial union member __data_
852
853private:
854 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
855# if _LIBCPP_STD_VER >= 20
856 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
857 std::__reverse_destroy(__data_, __data_ + _Count);
858 } else {
859 __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
860 std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count);
861 }
862# else
863 __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
864 std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count);
865# endif
866 }
867
868 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
869 using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, __bounded_array_control_block>;
870 using _PointerTraits = pointer_traits<typename allocator_traits<_ControlBlockAlloc>::pointer>;
871
872 _ControlBlockAlloc __tmp(__alloc_);
873 __alloc_.~_Alloc();
874 allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*this), 1);
875 }
876
877 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
878 union {
879 _Tp __data_[_Count];
880 };
881};
882
883template <class _Array, class _Alloc, class... _Arg>
884_LIBCPP_HIDE_FROM_ABI shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&&... __arg) {
885 static_assert(__is_bounded_array_v<_Array>);
886 using _ControlBlock = __bounded_array_control_block<_Array, _Alloc>;
887 using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, _ControlBlock>;
888
889 __allocation_guard<_ControlBlockAlloc> __guard(__a, 1);
890 _ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get()));
891 std::__construct_at(__control_block, __a, std::forward<_Arg>(__arg)...);
892 __guard.__release_ptr();
893 return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
894}
895
896#endif // _LIBCPP_STD_VER >= 17
897
898#if _LIBCPP_STD_VER >= 20
899
900// bounded array variants
901template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
902[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) {
903 return std::__allocate_shared_bounded_array<_Tp>(__a);
904}
905
906template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
907[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
908allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) {
909 return std::__allocate_shared_bounded_array<_Tp>(__a, __u);
910}
911
912template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
913[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) {
914 using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
915 _ForOverwriteAllocator __alloc(__a);
916 return std::__allocate_shared_bounded_array<_Tp>(__alloc);
917}
918
919template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
920[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() {
921 return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>());
922}
923
924template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
925[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) {
926 return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u);
927}
928
929template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
930[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() {
931 return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>());
932}
933
934// unbounded array variants
935template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
936[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) {
937 return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
938}
939
940template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
941[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
942allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) {
943 return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
944}
945
946template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
947[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) {
948 using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
949 _ForOverwriteAllocator __alloc(__a);
950 return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n);
951}
952
953template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
954[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) {
955 return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n);
956}
957
958template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
959[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) {
960 return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u);
961}
962
963template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
964[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) {
965 return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n);
966}
967
968#endif // _LIBCPP_STD_VER >= 20
969
970template <class _Tp, class _Up>
971inline _LIBCPP_HIDE_FROM_ABI bool operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
972 return __x.get() == __y.get();
973}
974
975#if _LIBCPP_STD_VER <= 17
976
977template <class _Tp, class _Up>
978inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
979 return !(__x == __y);
980}
981
982template <class _Tp, class _Up>
983inline _LIBCPP_HIDE_FROM_ABI bool operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
984# if _LIBCPP_STD_VER <= 11
985 typedef typename common_type<_Tp*, _Up*>::type _Vp;
986 return less<_Vp>()(__x.get(), __y.get());
987# else
988 return less<>()(__x.get(), __y.get());
989# endif
990}
991
992template <class _Tp, class _Up>
993inline _LIBCPP_HIDE_FROM_ABI bool operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
994 return __y < __x;
995}
996
997template <class _Tp, class _Up>
998inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
999 return !(__y < __x);
1000}
1001
1002template <class _Tp, class _Up>
1003inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {
1004 return !(__x < __y);
1005}
1006
1007#endif // _LIBCPP_STD_VER <= 17
1008
1009#if _LIBCPP_STD_VER >= 20
1010template <class _Tp, class _Up>
1011_LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) noexcept {
1012 return compare_three_way()(__x.get(), __y.get());
1013}
1014#endif
1015
1016template <class _Tp>
1017inline _LIBCPP_HIDE_FROM_ABI bool operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {
1018 return !__x;
1019}
1020
1021#if _LIBCPP_STD_VER <= 17
1022
1023template <class _Tp>
1024inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {
1025 return !__x;
1026}
1027
1028template <class _Tp>
1029inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {
1030 return static_cast<bool>(__x);
1031}
1032
1033template <class _Tp>
1034inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {
1035 return static_cast<bool>(__x);
1036}
1037
1038template <class _Tp>
1039inline _LIBCPP_HIDE_FROM_ABI bool operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {
1040 return less<typename shared_ptr<_Tp>::element_type*>()(__x.get(), nullptr);
1041}
1042
1043template <class _Tp>
1044inline _LIBCPP_HIDE_FROM_ABI bool operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {
1045 return less<typename shared_ptr<_Tp>::element_type*>()(nullptr, __x.get());
1046}
1047
1048template <class _Tp>
1049inline _LIBCPP_HIDE_FROM_ABI bool operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {
1050 return nullptr < __x;
1051}
1052
1053template <class _Tp>
1054inline _LIBCPP_HIDE_FROM_ABI bool operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {
1055 return __x < nullptr;
1056}
1057
1058template <class _Tp>
1059inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {
1060 return !(nullptr < __x);
1061}
1062
1063template <class _Tp>
1064inline _LIBCPP_HIDE_FROM_ABI bool operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {
1065 return !(__x < nullptr);
1066}
1067
1068template <class _Tp>
1069inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {
1070 return !(__x < nullptr);
1071}
1072
1073template <class _Tp>
1074inline _LIBCPP_HIDE_FROM_ABI bool operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {
1075 return !(nullptr < __x);
1076}
1077
1078#endif // _LIBCPP_STD_VER <= 17
1079
1080#if _LIBCPP_STD_VER >= 20
1081template <class _Tp>
1082_LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(shared_ptr<_Tp> const& __x, nullptr_t) noexcept {
1083 return compare_three_way()(__x.get(), static_cast<typename shared_ptr<_Tp>::element_type*>(nullptr));
1084}
1085#endif
1086
1087template <class _Tp>
1088inline _LIBCPP_HIDE_FROM_ABI void swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT {
1089 __x.swap(__y);
1090}
1091
1092template <class _Tp, class _Up>
1093[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
1094static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
1095 return shared_ptr<_Tp>(__r, static_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));
1096}
1097
1098// LWG-2996
1099// We don't backport because it is an evolutionary change.
1100#if _LIBCPP_STD_VER >= 20
1101template <class _Tp, class _Up>
1102[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1103 return shared_ptr<_Tp>(std::move(__r), static_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
1104}
1105#endif
1106
1107template <class _Tp, class _Up>
1108[[__nodiscard__]] inline
1109 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
1110 typedef typename shared_ptr<_Tp>::element_type _ET;
1111 _ET* __p = dynamic_cast<_ET*>(__r.get());
1112 return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
1113}
1114
1115// LWG-2996
1116// We don't backport because it is an evolutionary change.
1117#if _LIBCPP_STD_VER >= 20
1118template <class _Tp, class _Up>
1119[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1120 auto* __p = dynamic_cast<typename shared_ptr<_Tp>::element_type*>(__r.get());
1121 return __p ? shared_ptr<_Tp>(std::move(__r), __p) : shared_ptr<_Tp>();
1122}
1123#endif
1124
1125template <class _Tp, class _Up>
1126[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
1127 typedef typename shared_ptr<_Tp>::element_type _RTp;
1128 return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
1129}
1130
1131// LWG-2996
1132// We don't backport because it is an evolutionary change.
1133#if _LIBCPP_STD_VER >= 20
1134template <class _Tp, class _Up>
1135[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1136 return shared_ptr<_Tp>(std::move(__r), const_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
1137}
1138#endif
1139
1140template <class _Tp, class _Up>
1141[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {
1142 return shared_ptr<_Tp>(__r, reinterpret_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));
1143}
1144
1145// LWG-2996
1146// We don't backport because it is an evolutionary change.
1147#if _LIBCPP_STD_VER >= 20
1148template <class _Tp, class _Up>
1149[[nodiscard]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept {
1150 return shared_ptr<_Tp>(std::move(__r), reinterpret_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()));
1151}
1152#endif
1153
1154#if _LIBCPP_HAS_RTTI
1155
1156template <class _Dp, class _Tp>
1157[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT {
1158 return __p.template __get_deleter<_Dp>();
1159}
1160
1161#endif // _LIBCPP_HAS_RTTI
1162
1163template <class _Tp>
1164class _LIBCPP_SHARED_PTR_TRIVIAL_ABI weak_ptr {
1165public:
1166#if _LIBCPP_STD_VER >= 17
1167 typedef remove_extent_t<_Tp> element_type;
1168#else
1169 typedef _Tp element_type;
1170#endif
1171
1172 // A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
1173 // any bookkeeping, so it's always trivially relocatable.
1174 using __trivially_relocatable _LIBCPP_NODEBUG = weak_ptr;
1175
1176private:
1177 element_type* __ptr_;
1178 __shared_weak_count* __cntrl_;
1179
1180public:
1181 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {}
1182
1183 template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
1184 _LIBCPP_HIDE_FROM_ABI weak_ptr(shared_ptr<_Yp> const& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {
1185 if (__cntrl_)
1186 __cntrl_->__add_weak();
1187 }
1188
1189 _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr const& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {
1190 if (__cntrl_)
1191 __cntrl_->__add_weak();
1192 }
1193
1194 template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
1195 _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr<_Yp> const& __r) _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {
1196 shared_ptr<_Yp> __s = __r.lock();
1197 *this = weak_ptr<_Tp>(__s);
1198 }
1199
1200 _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr&& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {
1201 __r.__ptr_ = nullptr;
1202 __r.__cntrl_ = nullptr;
1203 }
1204
1205 template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
1206 _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr<_Yp>&& __r) _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {
1207 shared_ptr<_Yp> __s = __r.lock();
1208 *this = weak_ptr<_Tp>(__s);
1209 __r.reset();
1210 }
1211
1212 _LIBCPP_HIDE_FROM_ABI ~weak_ptr() {
1213 if (__cntrl_)
1214 __cntrl_->__release_weak();
1215 }
1216
1217 _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT {
1218 weak_ptr(__r).swap(r&: *this);
1219 return *this;
1220 }
1221
1222 template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
1223 _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT {
1224 weak_ptr(__r).swap(r&: *this);
1225 return *this;
1226 }
1227
1228 _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT {
1229 weak_ptr(std::move(__r)).swap(r&: *this);
1230 return *this;
1231 }
1232
1233 template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
1234 _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT {
1235 weak_ptr(std::move(__r)).swap(r&: *this);
1236 return *this;
1237 }
1238
1239 template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
1240 _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT {
1241 weak_ptr(__r).swap(r&: *this);
1242 return *this;
1243 }
1244
1245 _LIBCPP_HIDE_FROM_ABI void swap(weak_ptr& __r) _NOEXCEPT {
1246 std::swap(__ptr_, __r.__ptr_);
1247 std::swap(x&: __cntrl_, y&: __r.__cntrl_);
1248 }
1249
1250 _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT { weak_ptr().swap(r&: *this); }
1251
1252 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT {
1253 return __cntrl_ ? __cntrl_->use_count() : 0;
1254 }
1255
1256 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT {
1257 return __cntrl_ == nullptr || __cntrl_->use_count() == 0;
1258 }
1259
1260 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT {
1261 shared_ptr<_Tp> __r;
1262 __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
1263 if (__r.__cntrl_)
1264 __r.__ptr_ = __ptr_;
1265 return __r;
1266 }
1267
1268 template <class _Up>
1269 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT {
1270 return __cntrl_ < __r.__cntrl_;
1271 }
1272 template <class _Up>
1273 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT {
1274 return __cntrl_ < __r.__cntrl_;
1275 }
1276
1277#if _LIBCPP_STD_VER >= 26
1278 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t owner_hash() const noexcept {
1279 return std::hash<__shared_weak_count*>()(__cntrl_);
1280 }
1281
1282 template <class _Up>
1283 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(shared_ptr<_Up> const& __p) const noexcept {
1284 return __cntrl_ == __p.__cntrl_;
1285 }
1286
1287 template <class _Up>
1288 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool owner_equal(weak_ptr<_Up> const& __p) const noexcept {
1289 return __cntrl_ == __p.__cntrl_;
1290 }
1291#endif
1292
1293 template <class _Up>
1294 friend class weak_ptr;
1295 template <class _Up>
1296 friend class shared_ptr;
1297};
1298
1299#if _LIBCPP_STD_VER >= 17
1300template <class _Tp>
1301weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
1302#endif
1303
1304template <class _Tp>
1305inline _LIBCPP_HIDE_FROM_ABI void swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT {
1306 __x.swap(__y);
1307}
1308
1309#if _LIBCPP_STD_VER >= 17
1310template <class _Tp = void>
1311struct owner_less;
1312#else
1313template <class _Tp>
1314struct owner_less;
1315#endif
1316
1317template <class _Tp>
1318struct owner_less<shared_ptr<_Tp> > : __binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool> {
1319 _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT {
1320 return __x.owner_before(__y);
1321 }
1322 _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT {
1323 return __x.owner_before(__y);
1324 }
1325 _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT {
1326 return __x.owner_before(__y);
1327 }
1328};
1329
1330template <class _Tp>
1331struct owner_less<weak_ptr<_Tp> > : __binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool> {
1332 _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT {
1333 return __x.owner_before(__y);
1334 }
1335 _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT {
1336 return __x.owner_before(__y);
1337 }
1338 _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT {
1339 return __x.owner_before(__y);
1340 }
1341};
1342
1343#if _LIBCPP_STD_VER >= 17
1344template <>
1345struct owner_less<void> {
1346 template <class _Tp, class _Up>
1347 _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT {
1348 return __x.owner_before(__y);
1349 }
1350 template <class _Tp, class _Up>
1351 _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT {
1352 return __x.owner_before(__y);
1353 }
1354 template <class _Tp, class _Up>
1355 _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT {
1356 return __x.owner_before(__y);
1357 }
1358 template <class _Tp, class _Up>
1359 _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT {
1360 return __x.owner_before(__y);
1361 }
1362 typedef void is_transparent;
1363};
1364#endif
1365
1366#if _LIBCPP_STD_VER >= 26
1367struct owner_hash {
1368 template <class _Tp>
1369 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(shared_ptr<_Tp> const& __p) const noexcept {
1370 return __p.owner_hash();
1371 }
1372 template <class _Tp>
1373 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(weak_ptr<_Tp> const& __p) const noexcept {
1374 return __p.owner_hash();
1375 }
1376
1377 using is_transparent = void;
1378};
1379
1380struct owner_equal {
1381 template <class _Tp, class _Up>
1382 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
1383 operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept {
1384 return __x.owner_equal(__y);
1385 }
1386 template <class _Tp, class _Up>
1387 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
1388 operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept {
1389 return __x.owner_equal(__y);
1390 }
1391 template <class _Tp, class _Up>
1392 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
1393 operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept {
1394 return __x.owner_equal(__y);
1395 }
1396 template <class _Tp, class _Up>
1397 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
1398 operator()(weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const noexcept {
1399 return __x.owner_equal(__y);
1400 }
1401
1402 using is_transparent = void;
1403};
1404#endif
1405
1406template <class _Tp>
1407class enable_shared_from_this {
1408 mutable weak_ptr<_Tp> __weak_this_;
1409
1410protected:
1411 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR enable_shared_from_this() _NOEXCEPT {}
1412 _LIBCPP_HIDE_FROM_ABI enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
1413 _LIBCPP_HIDE_FROM_ABI enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT { return *this; }
1414 _LIBCPP_HIDE_FROM_ABI ~enable_shared_from_this() {}
1415
1416public:
1417 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); }
1418 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const {
1419 return shared_ptr<const _Tp>(__weak_this_);
1420 }
1421
1422#if _LIBCPP_STD_VER >= 17
1423 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; }
1424
1425 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; }
1426#endif // _LIBCPP_STD_VER >= 17
1427
1428 template <class _Up>
1429 friend class shared_ptr;
1430};
1431
1432template <class _Tp>
1433struct hash;
1434
1435template <class _Tp>
1436struct hash<shared_ptr<_Tp> > {
1437#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1438 _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> argument_type;
1439 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
1440#endif
1441
1442 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT {
1443 return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
1444 }
1445};
1446
1447template <class _CharT, class _Traits, class _Yp>
1448inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
1449operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
1450
1451#if _LIBCPP_HAS_THREADS
1452
1453class _LIBCPP_EXPORTED_FROM_ABI __sp_mut {
1454 void* __lx_;
1455
1456public:
1457 void lock() _NOEXCEPT;
1458 void unlock() _NOEXCEPT;
1459
1460private:
1461 _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;
1462 __sp_mut(const __sp_mut&);
1463 __sp_mut& operator=(const __sp_mut&);
1464
1465 friend _LIBCPP_EXPORTED_FROM_ABI __sp_mut& __get_sp_mut(const void*);
1466};
1467
1468_LIBCPP_EXPORTED_FROM_ABI __sp_mut& __get_sp_mut(const void*);
1469
1470template <class _Tp>
1471inline _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const shared_ptr<_Tp>*) {
1472 return false;
1473}
1474
1475template <class _Tp>
1476_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p) {
1477 __sp_mut& __m = std::__get_sp_mut(__p);
1478 __m.lock();
1479 shared_ptr<_Tp> __q = *__p;
1480 __m.unlock();
1481 return __q;
1482}
1483
1484template <class _Tp>
1485inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order) {
1486 return std::atomic_load(__p);
1487}
1488
1489template <class _Tp>
1490_LIBCPP_HIDE_FROM_ABI void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) {
1491 __sp_mut& __m = std::__get_sp_mut(__p);
1492 __m.lock();
1493 __p->swap(__r);
1494 __m.unlock();
1495}
1496
1497template <class _Tp>
1498inline _LIBCPP_HIDE_FROM_ABI void atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) {
1499 std::atomic_store(__p, __r);
1500}
1501
1502template <class _Tp>
1503_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) {
1504 __sp_mut& __m = std::__get_sp_mut(__p);
1505 __m.lock();
1506 __p->swap(__r);
1507 __m.unlock();
1508 return __r;
1509}
1510
1511template <class _Tp>
1512inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
1513atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) {
1514 return std::atomic_exchange(__p, __r);
1515}
1516
1517template <class _Tp>
1518_LIBCPP_HIDE_FROM_ABI bool
1519atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) {
1520 shared_ptr<_Tp> __temp;
1521 __sp_mut& __m = std::__get_sp_mut(__p);
1522 __m.lock();
1523 if (__p->__owner_equivalent(*__v)) {
1524 std::swap(__temp, *__p);
1525 *__p = __w;
1526 __m.unlock();
1527 return true;
1528 }
1529 std::swap(__temp, *__v);
1530 *__v = *__p;
1531 __m.unlock();
1532 return false;
1533}
1534
1535template <class _Tp>
1536inline _LIBCPP_HIDE_FROM_ABI bool
1537atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) {
1538 return std::atomic_compare_exchange_strong(__p, __v, __w);
1539}
1540
1541template <class _Tp>
1542inline _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit(
1543 shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w, memory_order, memory_order) {
1544 return std::atomic_compare_exchange_strong(__p, __v, __w);
1545}
1546
1547template <class _Tp>
1548inline _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit(
1549 shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w, memory_order, memory_order) {
1550 return std::atomic_compare_exchange_weak(__p, __v, __w);
1551}
1552
1553#endif // _LIBCPP_HAS_THREADS
1554
1555_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
1556_LIBCPP_END_NAMESPACE_STD
1557
1558_LIBCPP_POP_MACROS
1559
1560#endif // _LIBCPP___MEMORY_SHARED_PTR_H
1561