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