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