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 <__availability>
14 #include <__compare/compare_three_way.h>
15 #include <__compare/ordering.h>
16 #include <__config>
17 #include <__functional/binary_function.h>
18 #include <__functional/operations.h>
19 #include <__functional/reference_wrapper.h>
20 #include <__iterator/access.h>
21 #include <__memory/addressof.h>
22 #include <__memory/allocation_guard.h>
23 #include <__memory/allocator.h>
24 #include <__memory/allocator_destructor.h>
25 #include <__memory/allocator_traits.h>
26 #include <__memory/auto_ptr.h>
27 #include <__memory/compressed_pair.h>
28 #include <__memory/construct_at.h>
29 #include <__memory/pointer_traits.h>
30 #include <__memory/uninitialized_algorithms.h>
31 #include <__memory/unique_ptr.h>
32 #include <__type_traits/add_lvalue_reference.h>
33 #include <__type_traits/conditional.h>
34 #include <__type_traits/conjunction.h>
35 #include <__type_traits/disjunction.h>
36 #include <__type_traits/is_array.h>
37 #include <__type_traits/is_bounded_array.h>
38 #include <__type_traits/is_convertible.h>
39 #include <__type_traits/is_move_constructible.h>
40 #include <__type_traits/is_reference.h>
41 #include <__type_traits/is_unbounded_array.h>
42 #include <__type_traits/nat.h>
43 #include <__type_traits/negation.h>
44 #include <__type_traits/remove_extent.h>
45 #include <__type_traits/remove_reference.h>
46 #include <__utility/declval.h>
47 #include <__utility/forward.h>
48 #include <__utility/move.h>
49 #include <__utility/swap.h>
50 #include <__verbose_abort>
51 #include <cstddef>
52 #include <iosfwd>
53 #include <new>
54 #include <stdexcept>
55 #include <typeinfo>
56 #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
57 # include <__atomic/memory_order.h>
58 #endif
59
60 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
61 # pragma GCC system_header
62 #endif
63
64 _LIBCPP_BEGIN_NAMESPACE_STD
65
66 // NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
67 // should be sufficient for thread safety.
68 // See https://llvm.org/PR22803
69 #if defined(__clang__) && __has_builtin(__atomic_add_fetch) \
70 && defined(__ATOMIC_RELAXED) \
71 && defined(__ATOMIC_ACQ_REL)
72 # define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
73 #elif defined(_LIBCPP_COMPILER_GCC)
74 # define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
75 #endif
76
77 template <class _ValueType>
78 inline _LIBCPP_INLINE_VISIBILITY
__libcpp_relaxed_load(_ValueType const * __value)79 _ValueType __libcpp_relaxed_load(_ValueType const* __value) {
80 #if !defined(_LIBCPP_HAS_NO_THREADS) && \
81 defined(__ATOMIC_RELAXED) && \
82 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
83 return __atomic_load_n(__value, __ATOMIC_RELAXED);
84 #else
85 return *__value;
86 #endif
87 }
88
89 template <class _ValueType>
90 inline _LIBCPP_INLINE_VISIBILITY
__libcpp_acquire_load(_ValueType const * __value)91 _ValueType __libcpp_acquire_load(_ValueType const* __value) {
92 #if !defined(_LIBCPP_HAS_NO_THREADS) && \
93 defined(__ATOMIC_ACQUIRE) && \
94 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
95 return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
96 #else
97 return *__value;
98 #endif
99 }
100
101 template <class _Tp>
102 inline _LIBCPP_INLINE_VISIBILITY _Tp
__libcpp_atomic_refcount_increment(_Tp & __t)103 __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT
104 {
105 #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
106 return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
107 #else
108 return __t += 1;
109 #endif
110 }
111
112 template <class _Tp>
113 inline _LIBCPP_INLINE_VISIBILITY _Tp
__libcpp_atomic_refcount_decrement(_Tp & __t)114 __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
115 {
116 #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
117 return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
118 #else
119 return __t -= 1;
120 #endif
121 }
122
123 class _LIBCPP_EXCEPTION_ABI bad_weak_ptr
124 : public std::exception
125 {
126 public:
127 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr() _NOEXCEPT = default;
128 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
129 ~bad_weak_ptr() _NOEXCEPT override;
130 const char* what() const _NOEXCEPT override;
131 };
132
133 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
__throw_bad_weak_ptr()134 void __throw_bad_weak_ptr()
135 {
136 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
137 throw bad_weak_ptr();
138 #else
139 _LIBCPP_VERBOSE_ABORT("bad_weak_ptr was thrown in -fno-exceptions mode");
140 #endif
141 }
142
143 template<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
144
145 class _LIBCPP_TYPE_VIS __shared_count
146 {
147 __shared_count(const __shared_count&);
148 __shared_count& operator=(const __shared_count&);
149
150 protected:
151 long __shared_owners_;
152 virtual ~__shared_count();
153 private:
154 virtual void __on_zero_shared() _NOEXCEPT = 0;
155
156 public:
157 _LIBCPP_INLINE_VISIBILITY
158 explicit __shared_count(long __refs = 0) _NOEXCEPT
__shared_owners_(__refs)159 : __shared_owners_(__refs) {}
160
161 #if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
162 void __add_shared() noexcept;
163 bool __release_shared() noexcept;
164 #else
165 _LIBCPP_INLINE_VISIBILITY
__add_shared()166 void __add_shared() _NOEXCEPT {
167 __libcpp_atomic_refcount_increment(__shared_owners_);
168 }
169 _LIBCPP_INLINE_VISIBILITY
__release_shared()170 bool __release_shared() _NOEXCEPT {
171 if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
172 __on_zero_shared();
173 return true;
174 }
175 return false;
176 }
177 #endif
178 _LIBCPP_INLINE_VISIBILITY
use_count()179 long use_count() const _NOEXCEPT {
180 return __libcpp_relaxed_load(&__shared_owners_) + 1;
181 }
182 };
183
184 class _LIBCPP_TYPE_VIS __shared_weak_count
185 : private __shared_count
186 {
187 long __shared_weak_owners_;
188
189 public:
190 _LIBCPP_INLINE_VISIBILITY
191 explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
__shared_count(__refs)192 : __shared_count(__refs),
193 __shared_weak_owners_(__refs) {}
194 protected:
195 ~__shared_weak_count() override;
196
197 public:
198 #if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
199 void __add_shared() noexcept;
200 void __add_weak() noexcept;
201 void __release_shared() noexcept;
202 #else
203 _LIBCPP_INLINE_VISIBILITY
204 void __add_shared() _NOEXCEPT {
205 __shared_count::__add_shared();
206 }
207 _LIBCPP_INLINE_VISIBILITY
208 void __add_weak() _NOEXCEPT {
209 __libcpp_atomic_refcount_increment(__shared_weak_owners_);
210 }
211 _LIBCPP_INLINE_VISIBILITY
212 void __release_shared() _NOEXCEPT {
213 if (__shared_count::__release_shared())
214 __release_weak();
215 }
216 #endif
217 void __release_weak() _NOEXCEPT;
218 _LIBCPP_INLINE_VISIBILITY
use_count()219 long use_count() const _NOEXCEPT {return __shared_count::use_count();}
220 __shared_weak_count* lock() _NOEXCEPT;
221
222 virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
223 private:
224 virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
225 };
226
227 template <class _Tp, class _Dp, class _Alloc>
228 class __shared_ptr_pointer
229 : public __shared_weak_count
230 {
231 __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
232 public:
233 _LIBCPP_INLINE_VISIBILITY
__shared_ptr_pointer(_Tp __p,_Dp __d,_Alloc __a)234 __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
235 : __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
236
237 #ifndef _LIBCPP_HAS_NO_RTTI
238 _LIBCPP_HIDE_FROM_ABI_VIRTUAL const void* __get_deleter(const type_info&) const _NOEXCEPT override;
239 #endif
240
241 private:
242 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;
243 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override;
244 };
245
246 #ifndef _LIBCPP_HAS_NO_RTTI
247
248 template <class _Tp, class _Dp, class _Alloc>
249 const void*
__get_deleter(const type_info & __t)250 __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
251 {
252 return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
253 }
254
255 #endif // _LIBCPP_HAS_NO_RTTI
256
257 template <class _Tp, class _Dp, class _Alloc>
258 void
__on_zero_shared()259 __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT
260 {
261 __data_.first().second()(__data_.first().first());
262 __data_.first().second().~_Dp();
263 }
264
265 template <class _Tp, class _Dp, class _Alloc>
266 void
__on_zero_shared_weak()267 __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
268 {
269 typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;
270 typedef allocator_traits<_Al> _ATraits;
271 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
272
273 _Al __a(__data_.second());
274 __data_.second().~_Alloc();
275 __a.deallocate(_PTraits::pointer_to(*this), 1);
276 }
277
278 // This tag is used to instantiate an allocator type. The various shared_ptr control blocks
279 // detect that the allocator has been instantiated for this type and perform alternative
280 // initialization/destruction based on that.
281 struct __for_overwrite_tag {};
282
283 template <class _Tp, class _Alloc>
284 struct __shared_ptr_emplace
285 : __shared_weak_count
286 {
287 template<class ..._Args>
288 _LIBCPP_HIDE_FROM_ABI
__shared_ptr_emplace__shared_ptr_emplace289 explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
290 : __storage_(_VSTD::move(__a))
291 {
292 #if _LIBCPP_STD_VER >= 20
293 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
294 static_assert(sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");
295 ::new ((void*)__get_elem()) _Tp;
296 } else {
297 using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
298 _TpAlloc __tmp(*__get_alloc());
299 allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
300 }
301 #else
302 ::new ((void*)__get_elem()) _Tp(_VSTD::forward<_Args>(__args)...);
303 #endif
304 }
305
306 _LIBCPP_HIDE_FROM_ABI
__get_alloc__shared_ptr_emplace307 _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
308
309 _LIBCPP_HIDE_FROM_ABI
__get_elem__shared_ptr_emplace310 _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
311
312 private:
__on_zero_shared__shared_ptr_emplace313 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
314 #if _LIBCPP_STD_VER >= 20
315 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
316 __get_elem()->~_Tp();
317 } else {
318 using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
319 _TpAlloc __tmp(*__get_alloc());
320 allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
321 }
322 #else
323 __get_elem()->~_Tp();
324 #endif
325 }
326
__on_zero_shared_weak__shared_ptr_emplace327 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
328 using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
329 using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;
330 _ControlBlockAlloc __tmp(*__get_alloc());
331 __storage_.~_Storage();
332 allocator_traits<_ControlBlockAlloc>::deallocate(__tmp,
333 pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1);
334 }
335
336 // This class implements the control block for non-array shared pointers created
337 // through `std::allocate_shared` and `std::make_shared`.
338 //
339 // In previous versions of the library, we used a compressed pair to store
340 // both the _Alloc and the _Tp. This implies using EBO, which is incompatible
341 // with Allocator construction for _Tp. To allow implementing P0674 in C++20,
342 // we now use a properly aligned char buffer while making sure that we maintain
343 // the same layout that we had when we used a compressed pair.
344 using _CompressedPair = __compressed_pair<_Alloc, _Tp>;
_ALIGNAS_TYPE__shared_ptr_emplace345 struct _ALIGNAS_TYPE(_CompressedPair) _Storage {
346 char __blob_[sizeof(_CompressedPair)];
347
348 _LIBCPP_HIDE_FROM_ABI explicit _Storage(_Alloc&& __a) {
349 ::new ((void*)__get_alloc()) _Alloc(_VSTD::move(__a));
350 }
351 _LIBCPP_HIDE_FROM_ABI ~_Storage() {
352 __get_alloc()->~_Alloc();
353 }
354 _LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT {
355 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
356 typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair);
357 _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first);
358 return __alloc;
359 }
360 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {
361 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
362 typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair);
363 _Tp *__elem = reinterpret_cast<_Tp*>(__second);
364 return __elem;
365 }
366 };
367
368 static_assert(_LIBCPP_ALIGNOF(_Storage) == _LIBCPP_ALIGNOF(_CompressedPair), "");
369 static_assert(sizeof(_Storage) == sizeof(_CompressedPair), "");
370 _Storage __storage_;
371 };
372
373 struct __shared_ptr_dummy_rebind_allocator_type;
374 template <>
375 class _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type>
376 {
377 public:
378 template <class _Other>
379 struct rebind
380 {
381 typedef allocator<_Other> other;
382 };
383 };
384
385 template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
386
387 // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.general-6
388 // A pointer type Y* is said to be compatible with a pointer type T*
389 // when either Y* is convertible to T* or Y is U[N] and T is cv U[].
390 #if _LIBCPP_STD_VER >= 17
391 template <class _Yp, class _Tp>
392 struct __bounded_convertible_to_unbounded : false_type {};
393
394 template <class _Up, std::size_t _Np, class _Tp>
395 struct __bounded_convertible_to_unbounded<_Up[_Np], _Tp>
396 : is_same<__remove_cv_t<_Tp>, _Up[]> {};
397
398 template <class _Yp, class _Tp>
399 struct __compatible_with
400 : _Or<
401 is_convertible<_Yp*, _Tp*>,
402 __bounded_convertible_to_unbounded<_Yp, _Tp>
403 > {};
404 #else
405 template <class _Yp, class _Tp>
406 struct __compatible_with
407 : is_convertible<_Yp*, _Tp*> {};
408 #endif // _LIBCPP_STD_VER >= 17
409
410 // Constructors that take raw pointers have a different set of "compatible" constraints
411 // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.const-9.1
412 // - If T is an array type, then either T is U[N] and Y(*)[N] is convertible to T*,
413 // or T is U[] and Y(*)[] is convertible to T*.
414 // - If T is not an array type, then Y* is convertible to T*.
415 #if _LIBCPP_STD_VER >= 17
416 template <class _Yp, class _Tp, class = void>
417 struct __raw_pointer_compatible_with : _And<
418 _Not<is_array<_Tp>>,
419 is_convertible<_Yp*, _Tp*>
420 > {};
421
422 template <class _Yp, class _Up, std::size_t _Np>
423 struct __raw_pointer_compatible_with<_Yp, _Up[_Np], __enable_if_t<
424 is_convertible<_Yp(*)[_Np], _Up(*)[_Np]>::value> >
425 : true_type {};
426
427 template <class _Yp, class _Up>
428 struct __raw_pointer_compatible_with<_Yp, _Up[], __enable_if_t<
429 is_convertible<_Yp(*)[], _Up(*)[]>::value> >
430 : true_type {};
431
432 #else
433 template <class _Yp, class _Tp>
434 struct __raw_pointer_compatible_with
435 : is_convertible<_Yp*, _Tp*> {};
436 #endif // _LIBCPP_STD_VER >= 17
437
438
439 template <class _Ptr, class = void>
440 struct __is_deletable : false_type { };
441 template <class _Ptr>
442 struct __is_deletable<_Ptr, decltype(delete std::declval<_Ptr>())> : true_type { };
443
444 template <class _Ptr, class = void>
445 struct __is_array_deletable : false_type { };
446 template <class _Ptr>
447 struct __is_array_deletable<_Ptr, decltype(delete[] std::declval<_Ptr>())> : true_type { };
448
449 template <class _Dp, class _Pt,
450 class = decltype(std::declval<_Dp>()(std::declval<_Pt>()))>
451 true_type __well_formed_deleter_test(int);
452
453 template <class, class>
454 false_type __well_formed_deleter_test(...);
455
456 template <class _Dp, class _Pt>
457 struct __well_formed_deleter : decltype(std::__well_formed_deleter_test<_Dp, _Pt>(0)) {};
458
459 template<class _Dp, class _Yp, class _Tp>
460 struct __shared_ptr_deleter_ctor_reqs
461 {
462 static const bool value = __raw_pointer_compatible_with<_Yp, _Tp>::value &&
463 is_move_constructible<_Dp>::value &&
464 __well_formed_deleter<_Dp, _Yp*>::value;
465 };
466
467 #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
468 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
469 #else
470 # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
471 #endif
472
473 template<class _Tp>
474 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
475 {
476 public:
477 #if _LIBCPP_STD_VER >= 17
478 typedef weak_ptr<_Tp> weak_type;
479 typedef remove_extent_t<_Tp> element_type;
480 #else
481 typedef _Tp element_type;
482 #endif
483
484 private:
485 element_type* __ptr_;
486 __shared_weak_count* __cntrl_;
487
488 public:
489 _LIBCPP_HIDE_FROM_ABI
490 _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT
491 : __ptr_(nullptr),
492 __cntrl_(nullptr)
493 { }
494
495 _LIBCPP_HIDE_FROM_ABI
496 _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT
497 : __ptr_(nullptr),
498 __cntrl_(nullptr)
499 { }
500
501 template<class _Yp, class = __enable_if_t<
502 _And<
503 __raw_pointer_compatible_with<_Yp, _Tp>
504 // In C++03 we get errors when trying to do SFINAE with the
505 // delete operator, so we always pretend that it's deletable.
506 // The same happens on GCC.
507 #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC)
508 , _If<is_array<_Tp>::value, __is_array_deletable<_Yp*>, __is_deletable<_Yp*> >
509 #endif
510 >::value
511 > >
512 _LIBCPP_HIDE_FROM_ABI explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
513 unique_ptr<_Yp> __hold(__p);
514 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
515 typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT> _CntrlBlk;
516 __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
517 __hold.release();
518 __enable_weak_this(__p, __p);
519 }
520
521 template<class _Yp, class _Dp, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
522 _LIBCPP_HIDE_FROM_ABI
523 shared_ptr(_Yp* __p, _Dp __d)
524 : __ptr_(__p)
525 {
526 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
527 try
528 {
529 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
530 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
531 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk;
532 #ifndef _LIBCPP_CXX03_LANG
533 __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
534 #else
535 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
536 #endif // not _LIBCPP_CXX03_LANG
537 __enable_weak_this(__p, __p);
538 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
539 }
540 catch (...)
541 {
542 __d(__p);
543 throw;
544 }
545 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
546 }
547
548 template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
549 _LIBCPP_HIDE_FROM_ABI
550 shared_ptr(_Yp* __p, _Dp __d, _Alloc __a)
551 : __ptr_(__p)
552 {
553 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
554 try
555 {
556 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
557 typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
558 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
559 typedef __allocator_destructor<_A2> _D2;
560 _A2 __a2(__a);
561 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
562 ::new ((void*)_VSTD::addressof(*__hold2.get()))
563 #ifndef _LIBCPP_CXX03_LANG
564 _CntrlBlk(__p, _VSTD::move(__d), __a);
565 #else
566 _CntrlBlk(__p, __d, __a);
567 #endif // not _LIBCPP_CXX03_LANG
568 __cntrl_ = _VSTD::addressof(*__hold2.release());
569 __enable_weak_this(__p, __p);
570 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
571 }
572 catch (...)
573 {
574 __d(__p);
575 throw;
576 }
577 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
578 }
579
580 template<class _Dp>
581 _LIBCPP_HIDE_FROM_ABI
582 shared_ptr(nullptr_t __p, _Dp __d)
583 : __ptr_(nullptr)
584 {
585 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
586 try
587 {
588 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
589 typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
590 typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk;
591 #ifndef _LIBCPP_CXX03_LANG
592 __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
593 #else
594 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
595 #endif // not _LIBCPP_CXX03_LANG
596 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
597 }
598 catch (...)
599 {
600 __d(__p);
601 throw;
602 }
603 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
604 }
605
606 template<class _Dp, class _Alloc>
607 _LIBCPP_HIDE_FROM_ABI
608 shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
609 : __ptr_(nullptr)
610 {
611 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
612 try
613 {
614 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
615 typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
616 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
617 typedef __allocator_destructor<_A2> _D2;
618 _A2 __a2(__a);
619 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
620 ::new ((void*)_VSTD::addressof(*__hold2.get()))
621 #ifndef _LIBCPP_CXX03_LANG
622 _CntrlBlk(__p, _VSTD::move(__d), __a);
623 #else
624 _CntrlBlk(__p, __d, __a);
625 #endif // not _LIBCPP_CXX03_LANG
626 __cntrl_ = _VSTD::addressof(*__hold2.release());
627 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
628 }
629 catch (...)
630 {
631 __d(__p);
632 throw;
633 }
634 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
635 }
636
637 template<class _Yp>
638 _LIBCPP_HIDE_FROM_ABI
639 shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
640 : __ptr_(__p),
641 __cntrl_(__r.__cntrl_)
642 {
643 if (__cntrl_)
644 __cntrl_->__add_shared();
645 }
646
647 _LIBCPP_HIDE_FROM_ABI
648 shared_ptr(const shared_ptr& __r) _NOEXCEPT
649 : __ptr_(__r.__ptr_),
650 __cntrl_(__r.__cntrl_)
651 {
652 if (__cntrl_)
653 __cntrl_->__add_shared();
654 }
655
656 template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
657 _LIBCPP_HIDE_FROM_ABI
658 shared_ptr(const shared_ptr<_Yp>& __r) _NOEXCEPT
659 : __ptr_(__r.__ptr_),
660 __cntrl_(__r.__cntrl_)
661 {
662 if (__cntrl_)
663 __cntrl_->__add_shared();
664 }
665
666 _LIBCPP_HIDE_FROM_ABI
667 shared_ptr(shared_ptr&& __r) _NOEXCEPT
668 : __ptr_(__r.__ptr_),
669 __cntrl_(__r.__cntrl_)
670 {
671 __r.__ptr_ = nullptr;
672 __r.__cntrl_ = nullptr;
673 }
674
675 template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
676 _LIBCPP_HIDE_FROM_ABI
677 shared_ptr(shared_ptr<_Yp>&& __r) _NOEXCEPT
678 : __ptr_(__r.__ptr_),
679 __cntrl_(__r.__cntrl_)
680 {
681 __r.__ptr_ = nullptr;
682 __r.__cntrl_ = nullptr;
683 }
684
685 template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
686 _LIBCPP_HIDE_FROM_ABI
687 explicit shared_ptr(const weak_ptr<_Yp>& __r)
688 : __ptr_(__r.__ptr_),
689 __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
690 {
691 if (__cntrl_ == nullptr)
692 __throw_bad_weak_ptr();
693 }
694
695 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
696 template<class _Yp, class = __enable_if_t<is_convertible<_Yp*, element_type*>::value> >
697 _LIBCPP_HIDE_FROM_ABI
698 shared_ptr(auto_ptr<_Yp>&& __r)
699 : __ptr_(__r.get())
700 {
701 typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
702 __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
703 __enable_weak_this(__r.get(), __r.get());
704 __r.release();
705 }
706 #endif
707
708 template <class _Yp, class _Dp, class = __enable_if_t<
709 !is_lvalue_reference<_Dp>::value &&
710 __compatible_with<_Yp, _Tp>::value &&
711 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
712 > >
713 _LIBCPP_HIDE_FROM_ABI
714 shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
715 : __ptr_(__r.get())
716 {
717 #if _LIBCPP_STD_VER >= 14
718 if (__ptr_ == nullptr)
719 __cntrl_ = nullptr;
720 else
721 #endif
722 {
723 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
724 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT> _CntrlBlk;
725 __cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT());
726 __enable_weak_this(__r.get(), __r.get());
727 }
728 __r.release();
729 }
730
731 template <class _Yp, class _Dp, class = void, class = __enable_if_t<
732 is_lvalue_reference<_Dp>::value &&
733 __compatible_with<_Yp, _Tp>::value &&
734 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
735 > >
736 _LIBCPP_HIDE_FROM_ABI
737 shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
738 : __ptr_(__r.get())
739 {
740 #if _LIBCPP_STD_VER >= 14
741 if (__ptr_ == nullptr)
742 __cntrl_ = nullptr;
743 else
744 #endif
745 {
746 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
747 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer,
748 reference_wrapper<__libcpp_remove_reference_t<_Dp> >,
749 _AllocT> _CntrlBlk;
750 __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
751 __enable_weak_this(__r.get(), __r.get());
752 }
753 __r.release();
754 }
755
756 _LIBCPP_HIDE_FROM_ABI
757 ~shared_ptr()
758 {
759 if (__cntrl_)
760 __cntrl_->__release_shared();
761 }
762
763 _LIBCPP_HIDE_FROM_ABI
764 shared_ptr<_Tp>& operator=(const shared_ptr& __r) _NOEXCEPT
765 {
766 shared_ptr(__r).swap(*this);
767 return *this;
768 }
769
770 template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
771 _LIBCPP_HIDE_FROM_ABI
772 shared_ptr<_Tp>& operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
773 {
774 shared_ptr(__r).swap(*this);
775 return *this;
776 }
777
778 _LIBCPP_HIDE_FROM_ABI
779 shared_ptr<_Tp>& operator=(shared_ptr&& __r) _NOEXCEPT
780 {
781 shared_ptr(_VSTD::move(__r)).swap(*this);
782 return *this;
783 }
784
785 template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
786 _LIBCPP_HIDE_FROM_ABI
787 shared_ptr<_Tp>& operator=(shared_ptr<_Yp>&& __r)
788 {
789 shared_ptr(_VSTD::move(__r)).swap(*this);
790 return *this;
791 }
792
793 #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
794 template<class _Yp, class = __enable_if_t<
795 !is_array<_Yp>::value &&
796 is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value
797 > >
798 _LIBCPP_HIDE_FROM_ABI
799 shared_ptr<_Tp>& operator=(auto_ptr<_Yp>&& __r)
800 {
801 shared_ptr(_VSTD::move(__r)).swap(*this);
802 return *this;
803 }
804 #endif
805
806 template <class _Yp, class _Dp, class = __enable_if_t<_And<
807 __compatible_with<_Yp, _Tp>,
808 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>
809 >::value> >
810 _LIBCPP_HIDE_FROM_ABI
811 shared_ptr<_Tp>& operator=(unique_ptr<_Yp, _Dp>&& __r)
812 {
813 shared_ptr(_VSTD::move(__r)).swap(*this);
814 return *this;
815 }
816
817 _LIBCPP_HIDE_FROM_ABI
818 void swap(shared_ptr& __r) _NOEXCEPT
819 {
820 _VSTD::swap(__ptr_, __r.__ptr_);
821 _VSTD::swap(__cntrl_, __r.__cntrl_);
822 }
823
824 _LIBCPP_HIDE_FROM_ABI
825 void reset() _NOEXCEPT
826 {
827 shared_ptr().swap(*this);
828 }
829
830 template<class _Yp, class = __enable_if_t<
831 __raw_pointer_compatible_with<_Yp, _Tp>::value
832 > >
833 _LIBCPP_HIDE_FROM_ABI
834 void reset(_Yp* __p)
835 {
836 shared_ptr(__p).swap(*this);
837 }
838
839 template<class _Yp, class _Dp, class = __enable_if_t<
840 __shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
841 _LIBCPP_HIDE_FROM_ABI
842 void reset(_Yp* __p, _Dp __d)
843 {
844 shared_ptr(__p, __d).swap(*this);
845 }
846
847 template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<
848 __shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
849 _LIBCPP_HIDE_FROM_ABI
850 void reset(_Yp* __p, _Dp __d, _Alloc __a)
851 {
852 shared_ptr(__p, __d, __a).swap(*this);
853 }
854
855 _LIBCPP_HIDE_FROM_ABI
856 element_type* get() const _NOEXCEPT
857 {
858 return __ptr_;
859 }
860
861 _LIBCPP_HIDE_FROM_ABI
862 __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT
863 {
864 return *__ptr_;
865 }
866
867 _LIBCPP_HIDE_FROM_ABI
868 element_type* operator->() const _NOEXCEPT
869 {
870 static_assert(!is_array<_Tp>::value,
871 "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
872 return __ptr_;
873 }
874
875 _LIBCPP_HIDE_FROM_ABI
876 long use_count() const _NOEXCEPT
877 {
878 return __cntrl_ ? __cntrl_->use_count() : 0;
879 }
880
881 _LIBCPP_HIDE_FROM_ABI
882 bool unique() const _NOEXCEPT
883 {
884 return use_count() == 1;
885 }
886
887 _LIBCPP_HIDE_FROM_ABI
888 explicit operator bool() const _NOEXCEPT
889 {
890 return get() != nullptr;
891 }
892
893 template <class _Up>
894 _LIBCPP_HIDE_FROM_ABI
895 bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT
896 {
897 return __cntrl_ < __p.__cntrl_;
898 }
899
900 template <class _Up>
901 _LIBCPP_HIDE_FROM_ABI
902 bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT
903 {
904 return __cntrl_ < __p.__cntrl_;
905 }
906
907 _LIBCPP_HIDE_FROM_ABI
908 bool __owner_equivalent(const shared_ptr& __p) const
909 {
910 return __cntrl_ == __p.__cntrl_;
911 }
912
913 #if _LIBCPP_STD_VER >= 17
914 _LIBCPP_HIDE_FROM_ABI
915 __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const
916 {
917 static_assert(is_array<_Tp>::value,
918 "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
919 return __ptr_[__i];
920 }
921 #endif
922
923 #ifndef _LIBCPP_HAS_NO_RTTI
924 template <class _Dp>
925 _LIBCPP_HIDE_FROM_ABI
926 _Dp* __get_deleter() const _NOEXCEPT
927 {
928 return static_cast<_Dp*>(__cntrl_
929 ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
930 : nullptr);
931 }
932 #endif // _LIBCPP_HAS_NO_RTTI
933
934 template<class _Yp, class _CntrlBlk>
935 _LIBCPP_HIDE_FROM_ABI
936 static shared_ptr<_Tp> __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT
937 {
938 shared_ptr<_Tp> __r;
939 __r.__ptr_ = __p;
940 __r.__cntrl_ = __cntrl;
941 __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
942 return __r;
943 }
944
945 private:
946 template <class _Yp, bool = is_function<_Yp>::value>
947 struct __shared_ptr_default_allocator
948 {
949 typedef allocator<_Yp> type;
950 };
951
952 template <class _Yp>
953 struct __shared_ptr_default_allocator<_Yp, true>
954 {
955 typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
956 };
957
958 template <class _Yp, class _OrigPtr, class = __enable_if_t<
959 is_convertible<_OrigPtr*, const enable_shared_from_this<_Yp>*>::value
960 > >
961 _LIBCPP_HIDE_FROM_ABI
962 void __enable_weak_this(const enable_shared_from_this<_Yp>* __e, _OrigPtr* __ptr) _NOEXCEPT
963 {
964 typedef __remove_cv_t<_Yp> _RawYp;
965 if (__e && __e->__weak_this_.expired())
966 {
967 __e->__weak_this_ = shared_ptr<_RawYp>(*this,
968 const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
969 }
970 }
971
972 _LIBCPP_HIDE_FROM_ABI void __enable_weak_this(...) _NOEXCEPT { }
973
974 template <class, class _Yp>
975 struct __shared_ptr_default_delete
976 : default_delete<_Yp>
977 { };
978
979 template <class _Yp, class _Un, size_t _Sz>
980 struct __shared_ptr_default_delete<_Yp[_Sz], _Un>
981 : default_delete<_Yp[]>
982 { };
983
984 template <class _Yp, class _Un>
985 struct __shared_ptr_default_delete<_Yp[], _Un>
986 : default_delete<_Yp[]>
987 { };
988
989 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
990 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
991 };
992
993 #if _LIBCPP_STD_VER >= 17
994 template<class _Tp>
995 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
996 template<class _Tp, class _Dp>
997 shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
998 #endif
999
1000 //
1001 // std::allocate_shared and std::make_shared
1002 //
1003 template<class _Tp, class _Alloc, class ..._Args, class = __enable_if_t<!is_array<_Tp>::value> >
1004 _LIBCPP_HIDE_FROM_ABI
1005 shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args)
1006 {
1007 using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
1008 using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
1009 __allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
1010 ::new ((void*)_VSTD::addressof(*__guard.__get())) _ControlBlock(__a, _VSTD::forward<_Args>(__args)...);
1011 auto __control_block = __guard.__release_ptr();
1012 return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block));
1013 }
1014
1015 template<class _Tp, class ..._Args, class = __enable_if_t<!is_array<_Tp>::value> >
1016 _LIBCPP_HIDE_FROM_ABI
1017 shared_ptr<_Tp> make_shared(_Args&& ...__args)
1018 {
1019 return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
1020 }
1021
1022 #if _LIBCPP_STD_VER >= 20
1023
1024 template<class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0>
1025 _LIBCPP_HIDE_FROM_ABI
1026 shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a)
1027 {
1028 using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
1029 _ForOverwriteAllocator __alloc(__a);
1030 return std::allocate_shared<_Tp>(__alloc);
1031 }
1032
1033 template<class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
1034 _LIBCPP_HIDE_FROM_ABI
1035 shared_ptr<_Tp> make_shared_for_overwrite()
1036 {
1037 return std::allocate_shared_for_overwrite<_Tp>(allocator<_Tp>());
1038 }
1039
1040 #endif // _LIBCPP_STD_VER >= 20
1041
1042 #if _LIBCPP_STD_VER >= 17
1043
1044 template <size_t _Alignment>
1045 struct __sp_aligned_storage {
1046 alignas(_Alignment) char __storage[_Alignment];
1047 };
1048
1049 template <class _Tp, class _Alloc>
1050 struct __unbounded_array_control_block;
1051
1052 template <class _Tp, class _Alloc>
1053 struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
1054 {
1055 _LIBCPP_HIDE_FROM_ABI constexpr
1056 _Tp* __get_data() noexcept { return __data_; }
1057
1058 _LIBCPP_HIDE_FROM_ABI
1059 explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count, _Tp const& __arg)
1060 : __alloc_(__alloc), __count_(__count)
1061 {
1062 std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::begin(__data_), __count_, __arg);
1063 }
1064
1065 _LIBCPP_HIDE_FROM_ABI
1066 explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count)
1067 : __alloc_(__alloc), __count_(__count)
1068 {
1069 #if _LIBCPP_STD_VER >= 20
1070 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
1071 // We are purposefully not using an allocator-aware default construction because the spec says so.
1072 // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
1073 std::uninitialized_default_construct_n(std::begin(__data_), __count_);
1074 } else {
1075 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_);
1076 }
1077 #else
1078 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_);
1079 #endif
1080 }
1081
1082 // Returns the number of bytes required to store a control block followed by the given number
1083 // of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment.
1084 _LIBCPP_HIDE_FROM_ABI
1085 static constexpr size_t __bytes_for(size_t __elements) {
1086 // When there's 0 elements, the control block alone is enough since it holds one element.
1087 // Otherwise, we allocate one fewer element than requested because the control block already
1088 // holds one. Also, we use the bitwise formula below to ensure that we allocate enough bytes
1089 // for the whole allocation to be a multiple of _Tp's alignment. That formula is taken from [1].
1090 //
1091 // [1]: https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding
1092 size_t __bytes = __elements == 0 ? sizeof(__unbounded_array_control_block)
1093 : (__elements - 1) * sizeof(_Tp) + sizeof(__unbounded_array_control_block);
1094 constexpr size_t __align = alignof(_Tp);
1095 return (__bytes + __align - 1) & ~(__align - 1);
1096 }
1097
1098 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
1099 ~__unbounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
1100
1101 private:
1102 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
1103 #if _LIBCPP_STD_VER >= 20
1104 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
1105 std::__reverse_destroy(__data_, __data_ + __count_);
1106 } else {
1107 __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
1108 std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_);
1109 }
1110 #else
1111 __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
1112 std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_);
1113 #endif
1114 }
1115
1116 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
1117 using _AlignedStorage = __sp_aligned_storage<alignof(__unbounded_array_control_block)>;
1118 using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>;
1119 using _PointerTraits = pointer_traits<typename allocator_traits<_StorageAlloc>::pointer>;
1120
1121 _StorageAlloc __tmp(__alloc_);
1122 __alloc_.~_Alloc();
1123 size_t __size = __unbounded_array_control_block::__bytes_for(__count_);
1124 _AlignedStorage* __storage = reinterpret_cast<_AlignedStorage*>(this);
1125 allocator_traits<_StorageAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*__storage), __size);
1126 }
1127
1128 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
1129 size_t __count_;
1130 union {
1131 _Tp __data_[1];
1132 };
1133 };
1134
1135 template<class _Array, class _Alloc, class... _Arg>
1136 _LIBCPP_HIDE_FROM_ABI
1137 shared_ptr<_Array> __allocate_shared_unbounded_array(const _Alloc& __a, size_t __n, _Arg&& ...__arg)
1138 {
1139 static_assert(__libcpp_is_unbounded_array<_Array>::value);
1140 // We compute the number of bytes necessary to hold the control block and the
1141 // array elements. Then, we allocate an array of properly-aligned dummy structs
1142 // large enough to hold the control block and array. This allows shifting the
1143 // burden of aligning memory properly from us to the allocator.
1144 using _ControlBlock = __unbounded_array_control_block<_Array, _Alloc>;
1145 using _AlignedStorage = __sp_aligned_storage<alignof(_ControlBlock)>;
1146 using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>;
1147 __allocation_guard<_StorageAlloc> __guard(__a, _ControlBlock::__bytes_for(__n) / sizeof(_AlignedStorage));
1148 _ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get()));
1149 std::__construct_at(__control_block, __a, __n, std::forward<_Arg>(__arg)...);
1150 __guard.__release_ptr();
1151 return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
1152 }
1153
1154 template <class _Tp, class _Alloc>
1155 struct __bounded_array_control_block;
1156
1157 template <class _Tp, size_t _Count, class _Alloc>
1158 struct __bounded_array_control_block<_Tp[_Count], _Alloc>
1159 : __shared_weak_count
1160 {
1161 _LIBCPP_HIDE_FROM_ABI constexpr
1162 _Tp* __get_data() noexcept { return __data_; }
1163
1164 _LIBCPP_HIDE_FROM_ABI
1165 explicit __bounded_array_control_block(_Alloc const& __alloc, _Tp const& __arg) : __alloc_(__alloc) {
1166 std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count, __arg);
1167 }
1168
1169 _LIBCPP_HIDE_FROM_ABI
1170 explicit __bounded_array_control_block(_Alloc const& __alloc) : __alloc_(__alloc) {
1171 #if _LIBCPP_STD_VER >= 20
1172 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
1173 // We are purposefully not using an allocator-aware default construction because the spec says so.
1174 // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
1175 std::uninitialized_default_construct_n(std::addressof(__data_[0]), _Count);
1176 } else {
1177 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count);
1178 }
1179 #else
1180 std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count);
1181 #endif
1182 }
1183
1184 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
1185 ~__bounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
1186
1187 private:
1188 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
1189 #if _LIBCPP_STD_VER >= 20
1190 if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
1191 std::__reverse_destroy(__data_, __data_ + _Count);
1192 } else {
1193 __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
1194 std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count);
1195 }
1196 #else
1197 __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
1198 std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count);
1199 #endif
1200 }
1201
1202 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
1203 using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, __bounded_array_control_block>;
1204 using _PointerTraits = pointer_traits<typename allocator_traits<_ControlBlockAlloc>::pointer>;
1205
1206 _ControlBlockAlloc __tmp(__alloc_);
1207 __alloc_.~_Alloc();
1208 allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*this), sizeof(*this));
1209 }
1210
1211 _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
1212 union {
1213 _Tp __data_[_Count];
1214 };
1215 };
1216
1217 template<class _Array, class _Alloc, class... _Arg>
1218 _LIBCPP_HIDE_FROM_ABI
1219 shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&& ...__arg)
1220 {
1221 static_assert(__libcpp_is_bounded_array<_Array>::value);
1222 using _ControlBlock = __bounded_array_control_block<_Array, _Alloc>;
1223 using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, _ControlBlock>;
1224
1225 __allocation_guard<_ControlBlockAlloc> __guard(__a, 1);
1226 _ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get()));
1227 std::__construct_at(__control_block, __a, std::forward<_Arg>(__arg)...);
1228 __guard.__release_ptr();
1229 return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
1230 }
1231
1232 #endif // _LIBCPP_STD_VER >= 17
1233
1234 #if _LIBCPP_STD_VER >= 20
1235
1236 // bounded array variants
1237 template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1238 _LIBCPP_HIDE_FROM_ABI
1239 shared_ptr<_Tp> allocate_shared(const _Alloc& __a)
1240 {
1241 return std::__allocate_shared_bounded_array<_Tp>(__a);
1242 }
1243
1244 template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1245 _LIBCPP_HIDE_FROM_ABI
1246 shared_ptr<_Tp> allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u)
1247 {
1248 return std::__allocate_shared_bounded_array<_Tp>(__a, __u);
1249 }
1250
1251 template<class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
1252 _LIBCPP_HIDE_FROM_ABI
1253 shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a)
1254 {
1255 using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
1256 _ForOverwriteAllocator __alloc(__a);
1257 return std::__allocate_shared_bounded_array<_Tp>(__alloc);
1258 }
1259
1260 template<class _Tp, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1261 _LIBCPP_HIDE_FROM_ABI
1262 shared_ptr<_Tp> make_shared()
1263 {
1264 return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>());
1265 }
1266
1267 template<class _Tp, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1268 _LIBCPP_HIDE_FROM_ABI
1269 shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u)
1270 {
1271 return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u);
1272 }
1273
1274 template<class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
1275 _LIBCPP_HIDE_FROM_ABI
1276 shared_ptr<_Tp> make_shared_for_overwrite()
1277 {
1278 return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>());
1279 }
1280
1281 // unbounded array variants
1282 template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1283 _LIBCPP_HIDE_FROM_ABI
1284 shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n)
1285 {
1286 return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
1287 }
1288
1289 template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1290 _LIBCPP_HIDE_FROM_ABI
1291 shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u)
1292 {
1293 return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
1294 }
1295
1296 template<class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
1297 _LIBCPP_HIDE_FROM_ABI
1298 shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n)
1299 {
1300 using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
1301 _ForOverwriteAllocator __alloc(__a);
1302 return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n);
1303 }
1304
1305 template<class _Tp, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1306 _LIBCPP_HIDE_FROM_ABI
1307 shared_ptr<_Tp> make_shared(size_t __n)
1308 {
1309 return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n);
1310 }
1311
1312 template<class _Tp, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1313 _LIBCPP_HIDE_FROM_ABI
1314 shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u)
1315 {
1316 return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u);
1317 }
1318
1319 template<class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
1320 _LIBCPP_HIDE_FROM_ABI
1321 shared_ptr<_Tp> make_shared_for_overwrite(size_t __n)
1322 {
1323 return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n);
1324 }
1325
1326 #endif // _LIBCPP_STD_VER >= 20
1327
1328 template<class _Tp, class _Up>
1329 inline _LIBCPP_INLINE_VISIBILITY
1330 bool
1331 operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1332 {
1333 return __x.get() == __y.get();
1334 }
1335
1336 #if _LIBCPP_STD_VER <= 17
1337
1338 template<class _Tp, class _Up>
1339 inline _LIBCPP_INLINE_VISIBILITY
1340 bool
1341 operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1342 {
1343 return !(__x == __y);
1344 }
1345
1346 template<class _Tp, class _Up>
1347 inline _LIBCPP_INLINE_VISIBILITY
1348 bool
1349 operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1350 {
1351 #if _LIBCPP_STD_VER <= 11
1352 typedef typename common_type<_Tp*, _Up*>::type _Vp;
1353 return less<_Vp>()(__x.get(), __y.get());
1354 #else
1355 return less<>()(__x.get(), __y.get());
1356 #endif
1357
1358 }
1359
1360 template<class _Tp, class _Up>
1361 inline _LIBCPP_INLINE_VISIBILITY
1362 bool
1363 operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1364 {
1365 return __y < __x;
1366 }
1367
1368 template<class _Tp, class _Up>
1369 inline _LIBCPP_INLINE_VISIBILITY
1370 bool
1371 operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1372 {
1373 return !(__y < __x);
1374 }
1375
1376 template<class _Tp, class _Up>
1377 inline _LIBCPP_INLINE_VISIBILITY
1378 bool
1379 operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1380 {
1381 return !(__x < __y);
1382 }
1383
1384 #endif // _LIBCPP_STD_VER <= 17
1385
1386 #if _LIBCPP_STD_VER >= 20
1387 template<class _Tp, class _Up>
1388 _LIBCPP_HIDE_FROM_ABI strong_ordering
1389 operator<=>(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) noexcept
1390 {
1391 return compare_three_way()(__x.get(), __y.get());
1392 }
1393 #endif
1394
1395 template<class _Tp>
1396 inline _LIBCPP_INLINE_VISIBILITY
1397 bool
1398 operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1399 {
1400 return !__x;
1401 }
1402
1403 #if _LIBCPP_STD_VER <= 17
1404
1405 template<class _Tp>
1406 inline _LIBCPP_INLINE_VISIBILITY
1407 bool
1408 operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1409 {
1410 return !__x;
1411 }
1412
1413 template<class _Tp>
1414 inline _LIBCPP_INLINE_VISIBILITY
1415 bool
1416 operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1417 {
1418 return static_cast<bool>(__x);
1419 }
1420
1421 template<class _Tp>
1422 inline _LIBCPP_INLINE_VISIBILITY
1423 bool
1424 operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1425 {
1426 return static_cast<bool>(__x);
1427 }
1428
1429 template<class _Tp>
1430 inline _LIBCPP_INLINE_VISIBILITY
1431 bool
1432 operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1433 {
1434 return less<_Tp*>()(__x.get(), nullptr);
1435 }
1436
1437 template<class _Tp>
1438 inline _LIBCPP_INLINE_VISIBILITY
1439 bool
1440 operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1441 {
1442 return less<_Tp*>()(nullptr, __x.get());
1443 }
1444
1445 template<class _Tp>
1446 inline _LIBCPP_INLINE_VISIBILITY
1447 bool
1448 operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1449 {
1450 return nullptr < __x;
1451 }
1452
1453 template<class _Tp>
1454 inline _LIBCPP_INLINE_VISIBILITY
1455 bool
1456 operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1457 {
1458 return __x < nullptr;
1459 }
1460
1461 template<class _Tp>
1462 inline _LIBCPP_INLINE_VISIBILITY
1463 bool
1464 operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1465 {
1466 return !(nullptr < __x);
1467 }
1468
1469 template<class _Tp>
1470 inline _LIBCPP_INLINE_VISIBILITY
1471 bool
1472 operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1473 {
1474 return !(__x < nullptr);
1475 }
1476
1477 template<class _Tp>
1478 inline _LIBCPP_INLINE_VISIBILITY
1479 bool
1480 operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1481 {
1482 return !(__x < nullptr);
1483 }
1484
1485 template<class _Tp>
1486 inline _LIBCPP_INLINE_VISIBILITY
1487 bool
1488 operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1489 {
1490 return !(nullptr < __x);
1491 }
1492
1493 #endif // _LIBCPP_STD_VER <= 17
1494
1495 #if _LIBCPP_STD_VER >= 20
1496 template<class _Tp>
1497 _LIBCPP_HIDE_FROM_ABI strong_ordering
1498 operator<=>(shared_ptr<_Tp> const& __x, nullptr_t) noexcept
1499 {
1500 return compare_three_way()(__x.get(), static_cast<typename shared_ptr<_Tp>::element_type*>(nullptr));
1501 }
1502 #endif
1503
1504 template<class _Tp>
1505 inline _LIBCPP_INLINE_VISIBILITY
1506 void
1507 swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
1508 {
1509 __x.swap(__y);
1510 }
1511
1512 template<class _Tp, class _Up>
1513 inline _LIBCPP_INLINE_VISIBILITY
1514 shared_ptr<_Tp>
1515 static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
1516 {
1517 return shared_ptr<_Tp>(__r,
1518 static_cast<
1519 typename shared_ptr<_Tp>::element_type*>(__r.get()));
1520 }
1521
1522 template<class _Tp, class _Up>
1523 inline _LIBCPP_INLINE_VISIBILITY
1524 shared_ptr<_Tp>
1525 dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
1526 {
1527 typedef typename shared_ptr<_Tp>::element_type _ET;
1528 _ET* __p = dynamic_cast<_ET*>(__r.get());
1529 return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
1530 }
1531
1532 template<class _Tp, class _Up>
1533 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
1534 const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
1535 {
1536 typedef typename shared_ptr<_Tp>::element_type _RTp;
1537 return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
1538 }
1539
1540 template<class _Tp, class _Up>
1541 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
1542 reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
1543 {
1544 return shared_ptr<_Tp>(__r,
1545 reinterpret_cast<
1546 typename shared_ptr<_Tp>::element_type*>(__r.get()));
1547 }
1548
1549 #ifndef _LIBCPP_HAS_NO_RTTI
1550
1551 template<class _Dp, class _Tp>
1552 inline _LIBCPP_INLINE_VISIBILITY
1553 _Dp*
1554 get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
1555 {
1556 return __p.template __get_deleter<_Dp>();
1557 }
1558
1559 #endif // _LIBCPP_HAS_NO_RTTI
1560
1561 template<class _Tp>
1562 class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
1563 {
1564 public:
1565 #if _LIBCPP_STD_VER >= 17
1566 typedef remove_extent_t<_Tp> element_type;
1567 #else
1568 typedef _Tp element_type;
1569 #endif
1570
1571 private:
1572 element_type* __ptr_;
1573 __shared_weak_count* __cntrl_;
1574
1575 public:
1576 _LIBCPP_INLINE_VISIBILITY
1577 _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
1578 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r,
1579 typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0)
1580 _NOEXCEPT;
1581 _LIBCPP_INLINE_VISIBILITY
1582 weak_ptr(weak_ptr const& __r) _NOEXCEPT;
1583 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r,
1584 typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0)
1585 _NOEXCEPT;
1586
1587 _LIBCPP_INLINE_VISIBILITY
1588 weak_ptr(weak_ptr&& __r) _NOEXCEPT;
1589 template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
1590 typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0)
1591 _NOEXCEPT;
1592 _LIBCPP_HIDE_FROM_ABI ~weak_ptr();
1593
1594 _LIBCPP_INLINE_VISIBILITY
1595 weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
1596 template<class _Yp>
1597 typename enable_if
1598 <
1599 __compatible_with<_Yp, _Tp>::value,
1600 weak_ptr&
1601 >::type
1602 _LIBCPP_INLINE_VISIBILITY
1603 operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
1604
1605 _LIBCPP_INLINE_VISIBILITY
1606 weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
1607 template<class _Yp>
1608 typename enable_if
1609 <
1610 __compatible_with<_Yp, _Tp>::value,
1611 weak_ptr&
1612 >::type
1613 _LIBCPP_INLINE_VISIBILITY
1614 operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
1615
1616 template<class _Yp>
1617 typename enable_if
1618 <
1619 __compatible_with<_Yp, _Tp>::value,
1620 weak_ptr&
1621 >::type
1622 _LIBCPP_INLINE_VISIBILITY
1623 operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
1624
1625 _LIBCPP_INLINE_VISIBILITY
1626 void swap(weak_ptr& __r) _NOEXCEPT;
1627 _LIBCPP_INLINE_VISIBILITY
1628 void reset() _NOEXCEPT;
1629
1630 _LIBCPP_INLINE_VISIBILITY
1631 long use_count() const _NOEXCEPT
1632 {return __cntrl_ ? __cntrl_->use_count() : 0;}
1633 _LIBCPP_INLINE_VISIBILITY
1634 bool expired() const _NOEXCEPT
1635 {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;}
1636 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;
1637 template<class _Up>
1638 _LIBCPP_INLINE_VISIBILITY
1639 bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT
1640 {return __cntrl_ < __r.__cntrl_;}
1641 template<class _Up>
1642 _LIBCPP_INLINE_VISIBILITY
1643 bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT
1644 {return __cntrl_ < __r.__cntrl_;}
1645
1646 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
1647 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
1648 };
1649
1650 #if _LIBCPP_STD_VER >= 17
1651 template<class _Tp>
1652 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
1653 #endif
1654
1655 template<class _Tp>
1656 inline
1657 _LIBCPP_CONSTEXPR
1658 weak_ptr<_Tp>::weak_ptr() _NOEXCEPT
1659 : __ptr_(nullptr),
1660 __cntrl_(nullptr)
1661 {
1662 }
1663
1664 template<class _Tp>
1665 inline
1666 weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT
1667 : __ptr_(__r.__ptr_),
1668 __cntrl_(__r.__cntrl_)
1669 {
1670 if (__cntrl_)
1671 __cntrl_->__add_weak();
1672 }
1673
1674 template<class _Tp>
1675 template<class _Yp>
1676 inline
1677 weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
1678 typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type)
1679 _NOEXCEPT
1680 : __ptr_(__r.__ptr_),
1681 __cntrl_(__r.__cntrl_)
1682 {
1683 if (__cntrl_)
1684 __cntrl_->__add_weak();
1685 }
1686
1687 template<class _Tp>
1688 template<class _Yp>
1689 inline
1690 weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
1691 typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type)
1692 _NOEXCEPT
1693 : __ptr_(__r.__ptr_),
1694 __cntrl_(__r.__cntrl_)
1695 {
1696 if (__cntrl_)
1697 __cntrl_->__add_weak();
1698 }
1699
1700 template<class _Tp>
1701 inline
1702 weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
1703 : __ptr_(__r.__ptr_),
1704 __cntrl_(__r.__cntrl_)
1705 {
1706 __r.__ptr_ = nullptr;
1707 __r.__cntrl_ = nullptr;
1708 }
1709
1710 template<class _Tp>
1711 template<class _Yp>
1712 inline
1713 weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
1714 typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type)
1715 _NOEXCEPT
1716 : __ptr_(__r.__ptr_),
1717 __cntrl_(__r.__cntrl_)
1718 {
1719 __r.__ptr_ = nullptr;
1720 __r.__cntrl_ = nullptr;
1721 }
1722
1723 template<class _Tp>
1724 weak_ptr<_Tp>::~weak_ptr()
1725 {
1726 if (__cntrl_)
1727 __cntrl_->__release_weak();
1728 }
1729
1730 template<class _Tp>
1731 inline
1732 weak_ptr<_Tp>&
1733 weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
1734 {
1735 weak_ptr(__r).swap(*this);
1736 return *this;
1737 }
1738
1739 template<class _Tp>
1740 template<class _Yp>
1741 inline
1742 typename enable_if
1743 <
1744 __compatible_with<_Yp, _Tp>::value,
1745 weak_ptr<_Tp>&
1746 >::type
1747 weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
1748 {
1749 weak_ptr(__r).swap(*this);
1750 return *this;
1751 }
1752
1753 template<class _Tp>
1754 inline
1755 weak_ptr<_Tp>&
1756 weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
1757 {
1758 weak_ptr(_VSTD::move(__r)).swap(*this);
1759 return *this;
1760 }
1761
1762 template<class _Tp>
1763 template<class _Yp>
1764 inline
1765 typename enable_if
1766 <
1767 __compatible_with<_Yp, _Tp>::value,
1768 weak_ptr<_Tp>&
1769 >::type
1770 weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
1771 {
1772 weak_ptr(_VSTD::move(__r)).swap(*this);
1773 return *this;
1774 }
1775
1776 template<class _Tp>
1777 template<class _Yp>
1778 inline
1779 typename enable_if
1780 <
1781 __compatible_with<_Yp, _Tp>::value,
1782 weak_ptr<_Tp>&
1783 >::type
1784 weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
1785 {
1786 weak_ptr(__r).swap(*this);
1787 return *this;
1788 }
1789
1790 template<class _Tp>
1791 inline
1792 void
1793 weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
1794 {
1795 _VSTD::swap(__ptr_, __r.__ptr_);
1796 _VSTD::swap(__cntrl_, __r.__cntrl_);
1797 }
1798
1799 template<class _Tp>
1800 inline _LIBCPP_INLINE_VISIBILITY
1801 void
1802 swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
1803 {
1804 __x.swap(__y);
1805 }
1806
1807 template<class _Tp>
1808 inline
1809 void
1810 weak_ptr<_Tp>::reset() _NOEXCEPT
1811 {
1812 weak_ptr().swap(*this);
1813 }
1814
1815 template<class _Tp>
1816 shared_ptr<_Tp>
1817 weak_ptr<_Tp>::lock() const _NOEXCEPT
1818 {
1819 shared_ptr<_Tp> __r;
1820 __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
1821 if (__r.__cntrl_)
1822 __r.__ptr_ = __ptr_;
1823 return __r;
1824 }
1825
1826 #if _LIBCPP_STD_VER >= 17
1827 template <class _Tp = void> struct owner_less;
1828 #else
1829 template <class _Tp> struct owner_less;
1830 #endif
1831
1832
1833 template <class _Tp>
1834 struct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> >
1835 : __binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
1836 {
1837 _LIBCPP_INLINE_VISIBILITY
1838 bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
1839 {return __x.owner_before(__y);}
1840 _LIBCPP_INLINE_VISIBILITY
1841 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT
1842 {return __x.owner_before(__y);}
1843 _LIBCPP_INLINE_VISIBILITY
1844 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
1845 {return __x.owner_before(__y);}
1846 };
1847
1848 template <class _Tp>
1849 struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
1850 : __binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
1851 {
1852 _LIBCPP_INLINE_VISIBILITY
1853 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT
1854 {return __x.owner_before(__y);}
1855 _LIBCPP_INLINE_VISIBILITY
1856 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT
1857 {return __x.owner_before(__y);}
1858 _LIBCPP_INLINE_VISIBILITY
1859 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
1860 {return __x.owner_before(__y);}
1861 };
1862
1863 #if _LIBCPP_STD_VER >= 17
1864 template <>
1865 struct _LIBCPP_TEMPLATE_VIS owner_less<void>
1866 {
1867 template <class _Tp, class _Up>
1868 _LIBCPP_INLINE_VISIBILITY
1869 bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
1870 {return __x.owner_before(__y);}
1871 template <class _Tp, class _Up>
1872 _LIBCPP_INLINE_VISIBILITY
1873 bool operator()( shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT
1874 {return __x.owner_before(__y);}
1875 template <class _Tp, class _Up>
1876 _LIBCPP_INLINE_VISIBILITY
1877 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
1878 {return __x.owner_before(__y);}
1879 template <class _Tp, class _Up>
1880 _LIBCPP_INLINE_VISIBILITY
1881 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT
1882 {return __x.owner_before(__y);}
1883 typedef void is_transparent;
1884 };
1885 #endif
1886
1887 template<class _Tp>
1888 class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
1889 {
1890 mutable weak_ptr<_Tp> __weak_this_;
1891 protected:
1892 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1893 enable_shared_from_this() _NOEXCEPT {}
1894 _LIBCPP_INLINE_VISIBILITY
1895 enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
1896 _LIBCPP_INLINE_VISIBILITY
1897 enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
1898 {return *this;}
1899 _LIBCPP_INLINE_VISIBILITY
1900 ~enable_shared_from_this() {}
1901 public:
1902 _LIBCPP_INLINE_VISIBILITY
1903 shared_ptr<_Tp> shared_from_this()
1904 {return shared_ptr<_Tp>(__weak_this_);}
1905 _LIBCPP_INLINE_VISIBILITY
1906 shared_ptr<_Tp const> shared_from_this() const
1907 {return shared_ptr<const _Tp>(__weak_this_);}
1908
1909 #if _LIBCPP_STD_VER >= 17
1910 _LIBCPP_INLINE_VISIBILITY
1911 weak_ptr<_Tp> weak_from_this() _NOEXCEPT
1912 { return __weak_this_; }
1913
1914 _LIBCPP_INLINE_VISIBILITY
1915 weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
1916 { return __weak_this_; }
1917 #endif // _LIBCPP_STD_VER >= 17
1918
1919 template <class _Up> friend class shared_ptr;
1920 };
1921
1922 template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
1923
1924 template <class _Tp>
1925 struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >
1926 {
1927 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1928 _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> argument_type;
1929 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
1930 #endif
1931
1932 _LIBCPP_INLINE_VISIBILITY
1933 size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT
1934 {
1935 return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
1936 }
1937 };
1938
1939 template<class _CharT, class _Traits, class _Yp>
1940 inline _LIBCPP_INLINE_VISIBILITY
1941 basic_ostream<_CharT, _Traits>&
1942 operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
1943
1944
1945 #if !defined(_LIBCPP_HAS_NO_THREADS)
1946
1947 class _LIBCPP_TYPE_VIS __sp_mut
1948 {
1949 void* __lx_;
1950 public:
1951 void lock() _NOEXCEPT;
1952 void unlock() _NOEXCEPT;
1953
1954 private:
1955 _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;
1956 __sp_mut(const __sp_mut&);
1957 __sp_mut& operator=(const __sp_mut&);
1958
1959 friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
1960 };
1961
1962 _LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1963 __sp_mut& __get_sp_mut(const void*);
1964
1965 template <class _Tp>
1966 inline _LIBCPP_INLINE_VISIBILITY
1967 bool
1968 atomic_is_lock_free(const shared_ptr<_Tp>*)
1969 {
1970 return false;
1971 }
1972
1973 template <class _Tp>
1974 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1975 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
1976 atomic_load(const shared_ptr<_Tp>* __p)
1977 {
1978 __sp_mut& __m = std::__get_sp_mut(__p);
1979 __m.lock();
1980 shared_ptr<_Tp> __q = *__p;
1981 __m.unlock();
1982 return __q;
1983 }
1984
1985 template <class _Tp>
1986 inline _LIBCPP_INLINE_VISIBILITY
1987 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1988 shared_ptr<_Tp>
1989 atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
1990 {
1991 return std::atomic_load(__p);
1992 }
1993
1994 template <class _Tp>
1995 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1996 _LIBCPP_HIDE_FROM_ABI void
1997 atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
1998 {
1999 __sp_mut& __m = std::__get_sp_mut(__p);
2000 __m.lock();
2001 __p->swap(__r);
2002 __m.unlock();
2003 }
2004
2005 template <class _Tp>
2006 inline _LIBCPP_INLINE_VISIBILITY
2007 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2008 void
2009 atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
2010 {
2011 std::atomic_store(__p, __r);
2012 }
2013
2014 template <class _Tp>
2015 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2016 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
2017 atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
2018 {
2019 __sp_mut& __m = std::__get_sp_mut(__p);
2020 __m.lock();
2021 __p->swap(__r);
2022 __m.unlock();
2023 return __r;
2024 }
2025
2026 template <class _Tp>
2027 inline _LIBCPP_INLINE_VISIBILITY
2028 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2029 shared_ptr<_Tp>
2030 atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
2031 {
2032 return std::atomic_exchange(__p, __r);
2033 }
2034
2035 template <class _Tp>
2036 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2037 _LIBCPP_HIDE_FROM_ABI bool
2038 atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
2039 {
2040 shared_ptr<_Tp> __temp;
2041 __sp_mut& __m = std::__get_sp_mut(__p);
2042 __m.lock();
2043 if (__p->__owner_equivalent(*__v))
2044 {
2045 _VSTD::swap(__temp, *__p);
2046 *__p = __w;
2047 __m.unlock();
2048 return true;
2049 }
2050 _VSTD::swap(__temp, *__v);
2051 *__v = *__p;
2052 __m.unlock();
2053 return false;
2054 }
2055
2056 template <class _Tp>
2057 inline _LIBCPP_INLINE_VISIBILITY
2058 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2059 bool
2060 atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
2061 {
2062 return std::atomic_compare_exchange_strong(__p, __v, __w);
2063 }
2064
2065 template <class _Tp>
2066 inline _LIBCPP_INLINE_VISIBILITY
2067 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2068 bool
2069 atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
2070 shared_ptr<_Tp> __w, memory_order, memory_order)
2071 {
2072 return std::atomic_compare_exchange_strong(__p, __v, __w);
2073 }
2074
2075 template <class _Tp>
2076 inline _LIBCPP_INLINE_VISIBILITY
2077 _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2078 bool
2079 atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
2080 shared_ptr<_Tp> __w, memory_order, memory_order)
2081 {
2082 return std::atomic_compare_exchange_weak(__p, __v, __w);
2083 }
2084
2085 #endif // !defined(_LIBCPP_HAS_NO_THREADS)
2086
2087 _LIBCPP_END_NAMESPACE_STD
2088
2089 #endif // _LIBCPP___MEMORY_SHARED_PTR_H
2090