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