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