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
49template <class _Alloc>
50class __allocator_destructor
51{
52 typedef _LIBCPP_NODEBUG allocator_traits<_Alloc> __alloc_traits;
53public:
54 typedef _LIBCPP_NODEBUG typename __alloc_traits::pointer pointer;
55 typedef _LIBCPP_NODEBUG typename __alloc_traits::size_type size_type;
56private:
57 _Alloc& __alloc_;
58 size_type __s_;
59public:
60 _LIBCPP_INLINE_VISIBILITY __allocator_destructor(_Alloc& __a, size_type __s)
61 _NOEXCEPT
62 : __alloc_(__a), __s_(__s) {}
63 _LIBCPP_INLINE_VISIBILITY
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
79template <class _ValueType>
80inline _LIBCPP_INLINE_VISIBILITY
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
91template <class _ValueType>
92inline _LIBCPP_INLINE_VISIBILITY
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
103template <class _Tp>
104inline _LIBCPP_INLINE_VISIBILITY _Tp
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
114template <class _Tp>
115inline _LIBCPP_INLINE_VISIBILITY _Tp
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
125class _LIBCPP_EXCEPTION_ABI bad_weak_ptr
126 : public std::exception
127{
128public:
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
136void __throw_bad_weak_ptr()
137{
138#ifndef _LIBCPP_NO_EXCEPTIONS
139 throw bad_weak_ptr();
140#else
141 _VSTD::abort();
142#endif
143}
144
145template<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
146
147class _LIBCPP_TYPE_VIS __shared_count
148{
149 __shared_count(const __shared_count&);
150 __shared_count& operator=(const __shared_count&);
151
152protected:
153 long __shared_owners_;
154 virtual ~__shared_count();
155private:
156 virtual void __on_zero_shared() _NOEXCEPT = 0;
157
158public:
159 _LIBCPP_INLINE_VISIBILITY
160 explicit __shared_count(long __refs = 0) _NOEXCEPT
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
168 void __add_shared() _NOEXCEPT {
169 __libcpp_atomic_refcount_increment(t&: __shared_owners_);
170 }
171 _LIBCPP_INLINE_VISIBILITY
172 bool __release_shared() _NOEXCEPT {
173 if (__libcpp_atomic_refcount_decrement(t&: __shared_owners_) == -1) {
174 __on_zero_shared();
175 return true;
176 }
177 return false;
178 }
179#endif
180 _LIBCPP_INLINE_VISIBILITY
181 long use_count() const _NOEXCEPT {
182 return __libcpp_relaxed_load(value: &__shared_owners_) + 1;
183 }
184};
185
186class _LIBCPP_TYPE_VIS __shared_weak_count
187 : private __shared_count
188{
189 long __shared_weak_owners_;
190
191public:
192 _LIBCPP_INLINE_VISIBILITY
193 explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
194 : __shared_count(__refs),
195 __shared_weak_owners_(__refs) {}
196protected:
197 virtual ~__shared_weak_count();
198
199public:
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(t&: __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
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;
225private:
226 virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
227};
228
229template <class _Tp, class _Dp, class _Alloc>
230class __shared_ptr_pointer
231 : public __shared_weak_count
232{
233 __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
234public:
235 _LIBCPP_INLINE_VISIBILITY
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
243private:
244 virtual void __on_zero_shared() _NOEXCEPT;
245 virtual void __on_zero_shared_weak() _NOEXCEPT;
246};
247
248#ifndef _LIBCPP_NO_RTTI
249
250template <class _Tp, class _Dp, class _Alloc>
251const void*
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
259template <class _Tp, class _Dp, class _Alloc>
260void
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
267template <class _Tp, class _Dp, class _Alloc>
268void
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
280template <class _Tp, class _Alloc>
281struct __shared_ptr_emplace
282 : __shared_weak_count
283{
284 template<class ..._Args>
285 _LIBCPP_HIDE_FROM_ABI
286 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
299 _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
300
301 _LIBCPP_HIDE_FROM_ABI
302 _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
303
304private:
305 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
315 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>;
333 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
361struct __shared_ptr_dummy_rebind_allocator_type;
362template <>
363class _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type>
364{
365public:
366 template <class _Other>
367 struct rebind
368 {
369 typedef allocator<_Other> other;
370 };
371};
372
373template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
374
375template<class _Tp, class _Up>
376struct __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
383template <class _Ptr, class = void>
384struct __is_deletable : false_type { };
385template <class _Ptr>
386struct __is_deletable<_Ptr, decltype(delete declval<_Ptr>())> : true_type { };
387
388template <class _Ptr, class = void>
389struct __is_array_deletable : false_type { };
390template <class _Ptr>
391struct __is_array_deletable<_Ptr, decltype(delete[] declval<_Ptr>())> : true_type { };
392
393template <class _Dp, class _Pt,
394 class = decltype(declval<_Dp>()(declval<_Pt>()))>
395static true_type __well_formed_deleter_test(int);
396
397template <class, class>
398static false_type __well_formed_deleter_test(...);
399
400template <class _Dp, class _Pt>
401struct __well_formed_deleter : decltype(__well_formed_deleter_test<_Dp, _Pt>(0)) {};
402
403template<class _Dp, class _Tp, class _Yp>
404struct __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
417template<class _Tp>
418class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
419{
420public:
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
428private:
429 element_type* __ptr_;
430 __shared_weak_count* __cntrl_;
431
432public:
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
888private:
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
937template<class _Tp>
938shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
939template<class _Tp, class _Dp>
940shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
941#endif
942
943//
944// std::allocate_shared and std::make_shared
945//
946template<class _Tp, class _Alloc, class ..._Args, class = __enable_if_t<!is_array<_Tp>::value> >
947_LIBCPP_HIDE_FROM_ABI
948shared_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
958template<class _Tp, class ..._Args, class = __enable_if_t<!is_array<_Tp>::value> >
959_LIBCPP_HIDE_FROM_ABI
960shared_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
967template <size_t _Alignment>
968struct __sp_aligned_storage {
969 alignas(_Alignment) char __storage[_Alignment];
970};
971
972template <class _Tp, class _Alloc>
973struct __unbounded_array_control_block;
974
975template <class _Tp, class _Alloc>
976struct __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
1014private:
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(elements: __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
1039template<class _Array, class _Alloc, class... _Arg>
1040_LIBCPP_HIDE_FROM_ABI
1041shared_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
1058template <class _Tp, class _Alloc>
1059struct __bounded_array_control_block;
1060
1061template <class _Tp, size_t _Count, class _Alloc>
1062struct __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
1081private:
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
1102template<class _Array, class _Alloc, class... _Arg>
1103_LIBCPP_HIDE_FROM_ABI
1104shared_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
1121template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1122_LIBCPP_HIDE_FROM_ABI
1123shared_ptr<_Tp> allocate_shared(const _Alloc& __a)
1124{
1125 return std::__allocate_shared_bounded_array<_Tp>(__a);
1126}
1127
1128template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1129_LIBCPP_HIDE_FROM_ABI
1130shared_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
1135template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1136_LIBCPP_HIDE_FROM_ABI
1137shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n)
1138{
1139 return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
1140}
1141
1142template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1143_LIBCPP_HIDE_FROM_ABI
1144shared_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
1149template<class _Tp, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1150_LIBCPP_HIDE_FROM_ABI
1151shared_ptr<_Tp> make_shared()
1152{
1153 return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>());
1154}
1155
1156template<class _Tp, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1157_LIBCPP_HIDE_FROM_ABI
1158shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u)
1159{
1160 return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u);
1161}
1162
1163template<class _Tp, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1164_LIBCPP_HIDE_FROM_ABI
1165shared_ptr<_Tp> make_shared(size_t __n)
1166{
1167 return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n);
1168}
1169
1170template<class _Tp, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1171_LIBCPP_HIDE_FROM_ABI
1172shared_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
1179template<class _Tp, class _Up>
1180inline _LIBCPP_INLINE_VISIBILITY
1181bool
1182operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1183{
1184 return __x.get() == __y.get();
1185}
1186
1187template<class _Tp, class _Up>
1188inline _LIBCPP_INLINE_VISIBILITY
1189bool
1190operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1191{
1192 return !(__x == __y);
1193}
1194
1195template<class _Tp, class _Up>
1196inline _LIBCPP_INLINE_VISIBILITY
1197bool
1198operator<(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
1209template<class _Tp, class _Up>
1210inline _LIBCPP_INLINE_VISIBILITY
1211bool
1212operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1213{
1214 return __y < __x;
1215}
1216
1217template<class _Tp, class _Up>
1218inline _LIBCPP_INLINE_VISIBILITY
1219bool
1220operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1221{
1222 return !(__y < __x);
1223}
1224
1225template<class _Tp, class _Up>
1226inline _LIBCPP_INLINE_VISIBILITY
1227bool
1228operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
1229{
1230 return !(__x < __y);
1231}
1232
1233template<class _Tp>
1234inline _LIBCPP_INLINE_VISIBILITY
1235bool
1236operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1237{
1238 return !__x;
1239}
1240
1241template<class _Tp>
1242inline _LIBCPP_INLINE_VISIBILITY
1243bool
1244operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1245{
1246 return !__x;
1247}
1248
1249template<class _Tp>
1250inline _LIBCPP_INLINE_VISIBILITY
1251bool
1252operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1253{
1254 return static_cast<bool>(__x);
1255}
1256
1257template<class _Tp>
1258inline _LIBCPP_INLINE_VISIBILITY
1259bool
1260operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1261{
1262 return static_cast<bool>(__x);
1263}
1264
1265template<class _Tp>
1266inline _LIBCPP_INLINE_VISIBILITY
1267bool
1268operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1269{
1270 return less<_Tp*>()(__x.get(), nullptr);
1271}
1272
1273template<class _Tp>
1274inline _LIBCPP_INLINE_VISIBILITY
1275bool
1276operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1277{
1278 return less<_Tp*>()(nullptr, __x.get());
1279}
1280
1281template<class _Tp>
1282inline _LIBCPP_INLINE_VISIBILITY
1283bool
1284operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1285{
1286 return nullptr < __x;
1287}
1288
1289template<class _Tp>
1290inline _LIBCPP_INLINE_VISIBILITY
1291bool
1292operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1293{
1294 return __x < nullptr;
1295}
1296
1297template<class _Tp>
1298inline _LIBCPP_INLINE_VISIBILITY
1299bool
1300operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1301{
1302 return !(nullptr < __x);
1303}
1304
1305template<class _Tp>
1306inline _LIBCPP_INLINE_VISIBILITY
1307bool
1308operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1309{
1310 return !(__x < nullptr);
1311}
1312
1313template<class _Tp>
1314inline _LIBCPP_INLINE_VISIBILITY
1315bool
1316operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
1317{
1318 return !(__x < nullptr);
1319}
1320
1321template<class _Tp>
1322inline _LIBCPP_INLINE_VISIBILITY
1323bool
1324operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
1325{
1326 return !(nullptr < __x);
1327}
1328
1329template<class _Tp>
1330inline _LIBCPP_INLINE_VISIBILITY
1331void
1332swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
1333{
1334 __x.swap(__y);
1335}
1336
1337template<class _Tp, class _Up>
1338inline _LIBCPP_INLINE_VISIBILITY
1339shared_ptr<_Tp>
1340static_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
1347template<class _Tp, class _Up>
1348inline _LIBCPP_INLINE_VISIBILITY
1349shared_ptr<_Tp>
1350dynamic_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
1357template<class _Tp, class _Up>
1358shared_ptr<_Tp>
1359const_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
1365template<class _Tp, class _Up>
1366shared_ptr<_Tp>
1367reinterpret_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
1376template<class _Dp, class _Tp>
1377inline _LIBCPP_INLINE_VISIBILITY
1378_Dp*
1379get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
1380{
1381 return __p.template __get_deleter<_Dp>();
1382}
1383
1384#endif // _LIBCPP_NO_RTTI
1385
1386template<class _Tp>
1387class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
1388{
1389public:
1390#if _LIBCPP_STD_VER > 14
1391 typedef remove_extent_t<_Tp> element_type;
1392#else
1393 typedef _Tp element_type;
1394#endif
1395
1396private:
1397 element_type* __ptr_;
1398 __shared_weak_count* __cntrl_;
1399
1400public:
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
1476template<class _Tp>
1477weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
1478#endif
1479
1480template<class _Tp>
1481inline
1482_LIBCPP_CONSTEXPR
1483weak_ptr<_Tp>::weak_ptr() _NOEXCEPT
1484 : __ptr_(nullptr),
1485 __cntrl_(nullptr)
1486{
1487}
1488
1489template<class _Tp>
1490inline
1491weak_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
1499template<class _Tp>
1500template<class _Yp>
1501inline
1502weak_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
1512template<class _Tp>
1513template<class _Yp>
1514inline
1515weak_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
1525template<class _Tp>
1526inline
1527weak_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
1535template<class _Tp>
1536template<class _Yp>
1537inline
1538weak_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
1548template<class _Tp>
1549weak_ptr<_Tp>::~weak_ptr()
1550{
1551 if (__cntrl_)
1552 __cntrl_->__release_weak();
1553}
1554
1555template<class _Tp>
1556inline
1557weak_ptr<_Tp>&
1558weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
1559{
1560 weak_ptr(__r).swap(*this);
1561 return *this;
1562}
1563
1564template<class _Tp>
1565template<class _Yp>
1566inline
1567typename enable_if
1568<
1569 __compatible_with<_Yp, _Tp>::value,
1570 weak_ptr<_Tp>&
1571>::type
1572weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
1573{
1574 weak_ptr(__r).swap(*this);
1575 return *this;
1576}
1577
1578template<class _Tp>
1579inline
1580weak_ptr<_Tp>&
1581weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
1582{
1583 weak_ptr(_VSTD::move(__r)).swap(*this);
1584 return *this;
1585}
1586
1587template<class _Tp>
1588template<class _Yp>
1589inline
1590typename enable_if
1591<
1592 __compatible_with<_Yp, _Tp>::value,
1593 weak_ptr<_Tp>&
1594>::type
1595weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
1596{
1597 weak_ptr(_VSTD::move(__r)).swap(*this);
1598 return *this;
1599}
1600
1601template<class _Tp>
1602template<class _Yp>
1603inline
1604typename enable_if
1605<
1606 __compatible_with<_Yp, _Tp>::value,
1607 weak_ptr<_Tp>&
1608>::type
1609weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
1610{
1611 weak_ptr(__r).swap(*this);
1612 return *this;
1613}
1614
1615template<class _Tp>
1616inline
1617void
1618weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
1619{
1620 _VSTD::swap(__ptr_, __r.__ptr_);
1621 _VSTD::swap(__cntrl_, __r.__cntrl_);
1622}
1623
1624template<class _Tp>
1625inline _LIBCPP_INLINE_VISIBILITY
1626void
1627swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
1628{
1629 __x.swap(__y);
1630}
1631
1632template<class _Tp>
1633inline
1634void
1635weak_ptr<_Tp>::reset() _NOEXCEPT
1636{
1637 weak_ptr().swap(*this);
1638}
1639
1640template<class _Tp>
1641shared_ptr<_Tp>
1642weak_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
1652template <class _Tp = void> struct owner_less;
1653#else
1654template <class _Tp> struct owner_less;
1655#endif
1656
1657
1658template <class _Tp>
1659struct _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
1673template <class _Tp>
1674struct _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
1689template <>
1690struct _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
1712template<class _Tp>
1713class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
1714{
1715 mutable weak_ptr<_Tp> __weak_this_;
1716protected:
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() {}
1726public:
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
1747template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
1748
1749template <class _Tp>
1750struct _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
1764template<class _CharT, class _Traits, class _Yp>
1765inline _LIBCPP_INLINE_VISIBILITY
1766basic_ostream<_CharT, _Traits>&
1767operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
1768
1769
1770#if !defined(_LIBCPP_HAS_NO_THREADS)
1771
1772class _LIBCPP_TYPE_VIS __sp_mut
1773{
1774 void* __lx;
1775public:
1776 void lock() _NOEXCEPT;
1777 void unlock() _NOEXCEPT;
1778
1779private:
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
1790template <class _Tp>
1791inline _LIBCPP_INLINE_VISIBILITY
1792bool
1793atomic_is_lock_free(const shared_ptr<_Tp>*)
1794{
1795 return false;
1796}
1797
1798template <class _Tp>
1799_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1800shared_ptr<_Tp>
1801atomic_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
1810template <class _Tp>
1811inline _LIBCPP_INLINE_VISIBILITY
1812_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1813shared_ptr<_Tp>
1814atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
1815{
1816 return atomic_load(__p);
1817}
1818
1819template <class _Tp>
1820_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1821void
1822atomic_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
1830template <class _Tp>
1831inline _LIBCPP_INLINE_VISIBILITY
1832_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1833void
1834atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
1835{
1836 atomic_store(__p, __r);
1837}
1838
1839template <class _Tp>
1840_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1841shared_ptr<_Tp>
1842atomic_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
1851template <class _Tp>
1852inline _LIBCPP_INLINE_VISIBILITY
1853_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1854shared_ptr<_Tp>
1855atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
1856{
1857 return atomic_exchange(__p, __r);
1858}
1859
1860template <class _Tp>
1861_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1862bool
1863atomic_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
1881template <class _Tp>
1882inline _LIBCPP_INLINE_VISIBILITY
1883_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1884bool
1885atomic_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
1890template <class _Tp>
1891inline _LIBCPP_INLINE_VISIBILITY
1892_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1893bool
1894atomic_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
1900template <class _Tp>
1901inline _LIBCPP_INLINE_VISIBILITY
1902_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1903bool
1904atomic_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

source code of flutter_engine/third_party/libcxx/include/__memory/shared_ptr.h