1916fecb4SLouis Dionne // -*- C++ -*- 2916fecb4SLouis Dionne //===----------------------------------------------------------------------===// 3916fecb4SLouis Dionne // 4916fecb4SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5916fecb4SLouis Dionne // See https://llvm.org/LICENSE.txt for license information. 6916fecb4SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7916fecb4SLouis Dionne // 8916fecb4SLouis Dionne //===----------------------------------------------------------------------===// 9916fecb4SLouis Dionne 10916fecb4SLouis Dionne #ifndef _LIBCPP___MEMORY_SHARED_PTR_H 11916fecb4SLouis Dionne #define _LIBCPP___MEMORY_SHARED_PTR_H 12916fecb4SLouis Dionne 133b217f2fSAdrian Vogelsgesang #include <__compare/compare_three_way.h> 143b217f2fSAdrian Vogelsgesang #include <__compare/ordering.h> 158110a731Szoecarver #include <__config> 165acc4a3dSNikolas Klauser #include <__cstddef/nullptr_t.h> 17e99c4906SNikolas Klauser #include <__cstddef/ptrdiff_t.h> 18a65070a7Sphilnik777 #include <__exception/exception.h> 19050b064fSChristopher Di Bella #include <__functional/binary_function.h> 20050b064fSChristopher Di Bella #include <__functional/operations.h> 21050b064fSChristopher Di Bella #include <__functional/reference_wrapper.h> 22a65070a7Sphilnik777 #include <__fwd/ostream.h> 23e27a122bSLouis Dionne #include <__iterator/access.h> 24f992cfbaSLouis Dionne #include <__memory/addressof.h> 25e98060faSLouis Dionne #include <__memory/allocation_guard.h> 26050b064fSChristopher Di Bella #include <__memory/allocator.h> 2759ef4b36SNikolas Klauser #include <__memory/allocator_destructor.h> 284d81a46fSArthur O'Dwyer #include <__memory/allocator_traits.h> 29681cde7dSNikolas Klauser #include <__memory/auto_ptr.h> 30916fecb4SLouis Dionne #include <__memory/compressed_pair.h> 31e27a122bSLouis Dionne #include <__memory/construct_at.h> 32916fecb4SLouis Dionne #include <__memory/pointer_traits.h> 3367b81e21SNikolas Klauser #include <__memory/shared_count.h> 34e27a122bSLouis Dionne #include <__memory/uninitialized_algorithms.h> 35916fecb4SLouis Dionne #include <__memory/unique_ptr.h> 360a4aa8a1SNikolas Klauser #include <__type_traits/add_lvalue_reference.h> 370a4aa8a1SNikolas Klauser #include <__type_traits/conditional.h> 380a4aa8a1SNikolas Klauser #include <__type_traits/conjunction.h> 390a4aa8a1SNikolas Klauser #include <__type_traits/disjunction.h> 40d6832a61SLouis Dionne #include <__type_traits/enable_if.h> 41d6832a61SLouis Dionne #include <__type_traits/integral_constant.h> 420a4aa8a1SNikolas Klauser #include <__type_traits/is_array.h> 430a4aa8a1SNikolas Klauser #include <__type_traits/is_bounded_array.h> 44580f6048SNikolas Klauser #include <__type_traits/is_constructible.h> 4543562287SNikolas Klauser #include <__type_traits/is_convertible.h> 469474e094SLouis Dionne #include <__type_traits/is_function.h> 470a4aa8a1SNikolas Klauser #include <__type_traits/is_reference.h> 48de87dda2SNikolas Klauser #include <__type_traits/is_same.h> 490a4aa8a1SNikolas Klauser #include <__type_traits/is_unbounded_array.h> 500a4aa8a1SNikolas Klauser #include <__type_traits/nat.h> 510a4aa8a1SNikolas Klauser #include <__type_traits/negation.h> 52de87dda2SNikolas Klauser #include <__type_traits/remove_cv.h> 530a4aa8a1SNikolas Klauser #include <__type_traits/remove_extent.h> 540a4aa8a1SNikolas Klauser #include <__type_traits/remove_reference.h> 550a4aa8a1SNikolas Klauser #include <__utility/declval.h> 566adbc83eSChristopher Di Bella #include <__utility/forward.h> 57ea2206d7SArthur O'Dwyer #include <__utility/move.h> 5852915d78SNikolas Klauser #include <__utility/swap.h> 5916d1b0e1SNikolas Klauser #include <__verbose_abort> 604d81a46fSArthur O'Dwyer #include <typeinfo> 61ba87515fSNikolas Klauser #if _LIBCPP_HAS_ATOMIC_HEADER 6270617a1aSNikolas Klauser # include <__atomic/memory_order.h> 63916fecb4SLouis Dionne #endif 64916fecb4SLouis Dionne 65916fecb4SLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 66916fecb4SLouis Dionne # pragma GCC system_header 67916fecb4SLouis Dionne #endif 68916fecb4SLouis Dionne 697b462251SLouis Dionne _LIBCPP_PUSH_MACROS 707b462251SLouis Dionne #include <__undef_macros> 717b462251SLouis Dionne 72916fecb4SLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD 73916fecb4SLouis Dionne 749783f28cSLouis Dionne class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr : public std::exception { 75916fecb4SLouis Dionne public: 7683ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI bad_weak_ptr() _NOEXCEPT = default; 7783ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default; 7870248920SIgor Zhukov _LIBCPP_HIDE_FROM_ABI bad_weak_ptr& operator=(const bad_weak_ptr&) _NOEXCEPT = default; 794262b523SNikolas Klauser ~bad_weak_ptr() _NOEXCEPT override; 804262b523SNikolas Klauser const char* what() const _NOEXCEPT override; 81916fecb4SLouis Dionne }; 82916fecb4SLouis Dionne 83748023dcSNikolas Klauser [[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_weak_ptr() { 84ba87515fSNikolas Klauser #if _LIBCPP_HAS_EXCEPTIONS 85916fecb4SLouis Dionne throw bad_weak_ptr(); 86916fecb4SLouis Dionne #else 87308bcb3fSNikolas Klauser _LIBCPP_VERBOSE_ABORT("bad_weak_ptr was thrown in -fno-exceptions mode"); 88916fecb4SLouis Dionne #endif 89916fecb4SLouis Dionne } 90916fecb4SLouis Dionne 919783f28cSLouis Dionne template <class _Tp> 929783f28cSLouis Dionne class _LIBCPP_TEMPLATE_VIS weak_ptr; 93916fecb4SLouis Dionne 94916fecb4SLouis Dionne template <class _Tp, class _Dp, class _Alloc> 959783f28cSLouis Dionne class __shared_ptr_pointer : public __shared_weak_count { 9627c83382SNikolas Klauser _LIBCPP_COMPRESSED_TRIPLE(_Tp, __ptr_, _Dp, __deleter_, _Alloc, __alloc_); 979783f28cSLouis Dionne 98916fecb4SLouis Dionne public: 999783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a) 10027c83382SNikolas Klauser : __ptr_(__p), __deleter_(std::move(__d)), __alloc_(std::move(__a)) {} 101916fecb4SLouis Dionne 102ba87515fSNikolas Klauser #if _LIBCPP_HAS_RTTI 10383ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL const void* __get_deleter(const type_info&) const _NOEXCEPT override; 104916fecb4SLouis Dionne #endif 105916fecb4SLouis Dionne 106916fecb4SLouis Dionne private: 10783ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; 10883ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override; 109916fecb4SLouis Dionne }; 110916fecb4SLouis Dionne 111ba87515fSNikolas Klauser #if _LIBCPP_HAS_RTTI 112916fecb4SLouis Dionne 113916fecb4SLouis Dionne template <class _Tp, class _Dp, class _Alloc> 1149783f28cSLouis Dionne const void* __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT { 11527c83382SNikolas Klauser return __t == typeid(_Dp) ? std::addressof(__deleter_) : nullptr; 116916fecb4SLouis Dionne } 117916fecb4SLouis Dionne 118ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_RTTI 119916fecb4SLouis Dionne 120916fecb4SLouis Dionne template <class _Tp, class _Dp, class _Alloc> 1219783f28cSLouis Dionne void __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT { 12227c83382SNikolas Klauser __deleter_(__ptr_); 12327c83382SNikolas Klauser __deleter_.~_Dp(); 124916fecb4SLouis Dionne } 125916fecb4SLouis Dionne 126916fecb4SLouis Dionne template <class _Tp, class _Dp, class _Alloc> 1279783f28cSLouis Dionne void __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT { 128916fecb4SLouis Dionne typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al; 129916fecb4SLouis Dionne typedef allocator_traits<_Al> _ATraits; 130916fecb4SLouis Dionne typedef pointer_traits<typename _ATraits::pointer> _PTraits; 131916fecb4SLouis Dionne 13227c83382SNikolas Klauser _Al __a(__alloc_); 13327c83382SNikolas Klauser __alloc_.~_Alloc(); 134916fecb4SLouis Dionne __a.deallocate(_PTraits::pointer_to(*this), 1); 135916fecb4SLouis Dionne } 136916fecb4SLouis Dionne 13758010902SLouis Dionne // This tag is used to instantiate an allocator type. The various shared_ptr control blocks 13858010902SLouis Dionne // detect that the allocator has been instantiated for this type and perform alternative 13958010902SLouis Dionne // initialization/destruction based on that. 14058010902SLouis Dionne struct __for_overwrite_tag {}; 1419af9d39aSHui 142916fecb4SLouis Dionne template <class _Tp, class _Alloc> 1439783f28cSLouis Dionne struct __shared_ptr_emplace : __shared_weak_count { 144*f6958523SNikolas Klauser using __value_type _LIBCPP_NODEBUG = __remove_cv_t<_Tp>; 14519c6958dSA. Jiang 1469783f28cSLouis Dionne template <class... _Args, 1479783f28cSLouis Dionne class _Allocator = _Alloc, 1489783f28cSLouis Dionne __enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0> 1499783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&...) : __storage_(std::move(__a)) { 1509783f28cSLouis Dionne static_assert( 1519783f28cSLouis Dionne sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite"); 15219c6958dSA. Jiang ::new (static_cast<void*>(__get_elem())) __value_type; 15385f27d12SLouis Dionne } 15485f27d12SLouis Dionne 1559783f28cSLouis Dionne template <class... _Args, 1569783f28cSLouis Dionne class _Allocator = _Alloc, 1579783f28cSLouis Dionne __enable_if_t<!is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0> 1589783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&... __args) : __storage_(std::move(__a)) { 15919c6958dSA. Jiang using _TpAlloc = typename __allocator_traits_rebind<_Alloc, __value_type>::type; 160916fecb4SLouis Dionne _TpAlloc __tmp(*__get_alloc()); 16177a00c0dSLouis Dionne allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), std::forward<_Args>(__args)...); 16258010902SLouis Dionne } 163916fecb4SLouis Dionne 1649783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); } 165916fecb4SLouis Dionne 16619c6958dSA. Jiang _LIBCPP_HIDE_FROM_ABI __value_type* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); } 167916fecb4SLouis Dionne 168916fecb4SLouis Dionne private: 1699783f28cSLouis Dionne template <class _Allocator = _Alloc, 1709783f28cSLouis Dionne __enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0> 17185f27d12SLouis Dionne _LIBCPP_HIDE_FROM_ABI void __on_zero_shared_impl() _NOEXCEPT { 17219c6958dSA. Jiang __get_elem()->~__value_type(); 17385f27d12SLouis Dionne } 17485f27d12SLouis Dionne 1759783f28cSLouis Dionne template <class _Allocator = _Alloc, 1769783f28cSLouis Dionne __enable_if_t<!is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0> 17785f27d12SLouis Dionne _LIBCPP_HIDE_FROM_ABI void __on_zero_shared_impl() _NOEXCEPT { 178eb12d9b5SLouis Dionne using _TpAlloc = typename __allocator_traits_rebind<_Allocator, __remove_cv_t<_Tp> >::type; 179916fecb4SLouis Dionne _TpAlloc __tmp(*__get_alloc()); 180916fecb4SLouis Dionne allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem()); 18158010902SLouis Dionne } 18285f27d12SLouis Dionne 1839783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { __on_zero_shared_impl(); } 184916fecb4SLouis Dionne 18583ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override { 186a54d0288SLouis Dionne using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type; 187916fecb4SLouis Dionne using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer; 188916fecb4SLouis Dionne _ControlBlockAlloc __tmp(*__get_alloc()); 189916fecb4SLouis Dionne __storage_.~_Storage(); 1909783f28cSLouis Dionne allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1); 191916fecb4SLouis Dionne } 192916fecb4SLouis Dionne 19327c83382SNikolas Klauser // TODO: It should be possible to refactor this to remove `_Storage` entirely. 194916fecb4SLouis Dionne // This class implements the control block for non-array shared pointers created 195916fecb4SLouis Dionne // through `std::allocate_shared` and `std::make_shared`. 19627c83382SNikolas Klauser struct _Storage { 19727c83382SNikolas Klauser struct _Data { 19819c6958dSA. Jiang _LIBCPP_COMPRESSED_PAIR(_Alloc, __alloc_, __value_type, __elem_); 19927c83382SNikolas Klauser }; 20027c83382SNikolas Klauser 20127c83382SNikolas Klauser _ALIGNAS_TYPE(_Data) char __buffer_[sizeof(_Data)]; 202916fecb4SLouis Dionne 2039783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit _Storage(_Alloc&& __a) { ::new ((void*)__get_alloc()) _Alloc(std::move(__a)); } 2049783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI ~_Storage() { __get_alloc()->~_Alloc(); } 20527c83382SNikolas Klauser 20683ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT { 20727c83382SNikolas Klauser return std::addressof(reinterpret_cast<_Data*>(__buffer_)->__alloc_); 208916fecb4SLouis Dionne } 20927c83382SNikolas Klauser 21019c6958dSA. Jiang _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __value_type* __get_elem() _NOEXCEPT { 21127c83382SNikolas Klauser return std::addressof(reinterpret_cast<_Data*>(__buffer_)->__elem_); 212916fecb4SLouis Dionne } 213916fecb4SLouis Dionne }; 214916fecb4SLouis Dionne 215916fecb4SLouis Dionne _Storage __storage_; 216916fecb4SLouis Dionne }; 217916fecb4SLouis Dionne 218916fecb4SLouis Dionne struct __shared_ptr_dummy_rebind_allocator_type; 219916fecb4SLouis Dionne template <> 2209783f28cSLouis Dionne class _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type> { 221916fecb4SLouis Dionne public: 222916fecb4SLouis Dionne template <class _Other> 2239783f28cSLouis Dionne struct rebind { 224916fecb4SLouis Dionne typedef allocator<_Other> other; 225916fecb4SLouis Dionne }; 226916fecb4SLouis Dionne }; 227916fecb4SLouis Dionne 2289783f28cSLouis Dionne template <class _Tp> 2299783f28cSLouis Dionne class _LIBCPP_TEMPLATE_VIS enable_shared_from_this; 230916fecb4SLouis Dionne 231a38a4654SHui // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.general-6 232a38a4654SHui // A pointer type Y* is said to be compatible with a pointer type T* 233a38a4654SHui // when either Y* is convertible to T* or Y is U[N] and T is cv U[]. 234a38a4654SHui #if _LIBCPP_STD_VER >= 17 235a38a4654SHui template <class _Yp, class _Tp> 236a38a4654SHui struct __bounded_convertible_to_unbounded : false_type {}; 237a38a4654SHui 238a38a4654SHui template <class _Up, std::size_t _Np, class _Tp> 2399783f28cSLouis Dionne struct __bounded_convertible_to_unbounded<_Up[_Np], _Tp> : is_same<__remove_cv_t<_Tp>, _Up[]> {}; 240a38a4654SHui 241a38a4654SHui template <class _Yp, class _Tp> 2429783f28cSLouis Dionne struct __compatible_with : _Or< is_convertible<_Yp*, _Tp*>, __bounded_convertible_to_unbounded<_Yp, _Tp> > {}; 243916fecb4SLouis Dionne #else 244a38a4654SHui template <class _Yp, class _Tp> 2459783f28cSLouis Dionne struct __compatible_with : is_convertible<_Yp*, _Tp*> {}; 246a38a4654SHui #endif // _LIBCPP_STD_VER >= 17 247a38a4654SHui 248a38a4654SHui // Constructors that take raw pointers have a different set of "compatible" constraints 249a38a4654SHui // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.const-9.1 250a38a4654SHui // - If T is an array type, then either T is U[N] and Y(*)[N] is convertible to T*, 251a38a4654SHui // or T is U[] and Y(*)[] is convertible to T*. 252a38a4654SHui // - If T is not an array type, then Y* is convertible to T*. 253a38a4654SHui #if _LIBCPP_STD_VER >= 17 254a38a4654SHui template <class _Yp, class _Tp, class = void> 2559783f28cSLouis Dionne struct __raw_pointer_compatible_with : _And< _Not<is_array<_Tp>>, is_convertible<_Yp*, _Tp*> > {}; 256a38a4654SHui 257a38a4654SHui template <class _Yp, class _Up, std::size_t _Np> 2589783f28cSLouis Dionne struct __raw_pointer_compatible_with<_Yp, _Up[_Np], __enable_if_t< is_convertible<_Yp (*)[_Np], _Up (*)[_Np]>::value> > 259a38a4654SHui : true_type {}; 260a38a4654SHui 261a38a4654SHui template <class _Yp, class _Up> 2629783f28cSLouis Dionne struct __raw_pointer_compatible_with<_Yp, _Up[], __enable_if_t< is_convertible<_Yp (*)[], _Up (*)[]>::value> > 263a38a4654SHui : true_type {}; 264a38a4654SHui 265a38a4654SHui #else 266a38a4654SHui template <class _Yp, class _Tp> 2679783f28cSLouis Dionne struct __raw_pointer_compatible_with : is_convertible<_Yp*, _Tp*> {}; 268a38a4654SHui #endif // _LIBCPP_STD_VER >= 17 269a38a4654SHui 2701f8a6dcfSLouis Dionne template <class _Ptr, class = void> 2711f8a6dcfSLouis Dionne struct __is_deletable : false_type {}; 2721f8a6dcfSLouis Dionne template <class _Ptr> 27373e8e1baSNikolas Klauser struct __is_deletable<_Ptr, decltype(delete std::declval<_Ptr>())> : true_type {}; 2741f8a6dcfSLouis Dionne 2751f8a6dcfSLouis Dionne template <class _Ptr, class = void> 2761f8a6dcfSLouis Dionne struct __is_array_deletable : false_type {}; 2771f8a6dcfSLouis Dionne template <class _Ptr> 27873e8e1baSNikolas Klauser struct __is_array_deletable<_Ptr, decltype(delete[] std::declval<_Ptr>())> : true_type {}; 2791f8a6dcfSLouis Dionne 2809783f28cSLouis Dionne template <class _Dp, class _Pt, class = decltype(std::declval<_Dp>()(std::declval<_Pt>()))> 281e65cd4ceSNikolas Klauser true_type __well_formed_deleter_test(int); 282916fecb4SLouis Dionne 283916fecb4SLouis Dionne template <class, class> 284e65cd4ceSNikolas Klauser false_type __well_formed_deleter_test(...); 285916fecb4SLouis Dionne 286916fecb4SLouis Dionne template <class _Dp, class _Pt> 287841399a2SNikolas Klauser struct __well_formed_deleter : decltype(std::__well_formed_deleter_test<_Dp, _Pt>(0)) {}; 288916fecb4SLouis Dionne 289a38a4654SHui template <class _Dp, class _Yp, class _Tp> 2909783f28cSLouis Dionne struct __shared_ptr_deleter_ctor_reqs { 2919783f28cSLouis Dionne static const bool value = __raw_pointer_compatible_with<_Yp, _Tp>::value && is_move_constructible<_Dp>::value && 292a38a4654SHui __well_formed_deleter<_Dp, _Yp*>::value; 293916fecb4SLouis Dionne }; 294916fecb4SLouis Dionne 295eaae63d8SHui template <class _Dp> 296*f6958523SNikolas Klauser using __shared_ptr_nullptr_deleter_ctor_reqs _LIBCPP_NODEBUG = 297*f6958523SNikolas Klauser _And<is_move_constructible<_Dp>, __well_formed_deleter<_Dp, nullptr_t> >; 298eaae63d8SHui 299916fecb4SLouis Dionne #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI) 300c8eff956SNikolas Klauser # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__)) 301916fecb4SLouis Dionne #else 302916fecb4SLouis Dionne # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI 303916fecb4SLouis Dionne #endif 304916fecb4SLouis Dionne 305916fecb4SLouis Dionne template <class _Tp> 3069783f28cSLouis Dionne class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr { 307eaae63d8SHui struct __nullptr_sfinae_tag {}; 308eaae63d8SHui 309916fecb4SLouis Dionne public: 3104f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 17 311916fecb4SLouis Dionne typedef weak_ptr<_Tp> weak_type; 312916fecb4SLouis Dionne typedef remove_extent_t<_Tp> element_type; 313916fecb4SLouis Dionne #else 314916fecb4SLouis Dionne typedef _Tp element_type; 315916fecb4SLouis Dionne #endif 316916fecb4SLouis Dionne 3171ba8ed0cSNikolas Klauser // A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require 3181ba8ed0cSNikolas Klauser // any bookkeeping, so it's always trivially relocatable. 319*f6958523SNikolas Klauser using __trivially_relocatable _LIBCPP_NODEBUG = shared_ptr; 3201ba8ed0cSNikolas Klauser 321916fecb4SLouis Dionne private: 322916fecb4SLouis Dionne element_type* __ptr_; 323916fecb4SLouis Dionne __shared_weak_count* __cntrl_; 324916fecb4SLouis Dionne 325916fecb4SLouis Dionne public: 3269783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {} 327b2d25ef2SLouis Dionne 3289783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {} 3291f8a6dcfSLouis Dionne 3309783f28cSLouis Dionne template <class _Yp, 33176a24727SNikolas Klauser __enable_if_t< _And< __raw_pointer_compatible_with<_Yp, _Tp> 3321f8a6dcfSLouis Dionne // In C++03 we get errors when trying to do SFINAE with the 3331f8a6dcfSLouis Dionne // delete operator, so we always pretend that it's deletable. 3341f8a6dcfSLouis Dionne // The same happens on GCC. 3351f8a6dcfSLouis Dionne #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC) 3369783f28cSLouis Dionne , 3379783f28cSLouis Dionne _If<is_array<_Tp>::value, __is_array_deletable<_Yp*>, __is_deletable<_Yp*> > 3381f8a6dcfSLouis Dionne #endif 33976a24727SNikolas Klauser >::value, 34076a24727SNikolas Klauser int> = 0> 34183ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI explicit shared_ptr(_Yp* __p) : __ptr_(__p) { 3421f8a6dcfSLouis Dionne unique_ptr<_Yp> __hold(__p); 3431f8a6dcfSLouis Dionne typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 3441f8a6dcfSLouis Dionne typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT> _CntrlBlk; 3451f8a6dcfSLouis Dionne __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT()); 3461f8a6dcfSLouis Dionne __hold.release(); 3471f8a6dcfSLouis Dionne __enable_weak_this(__p, __p); 3481f8a6dcfSLouis Dionne } 3491f8a6dcfSLouis Dionne 35076a24727SNikolas Klauser template <class _Yp, class _Dp, __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0> 3519783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d) : __ptr_(__p) { 352ba87515fSNikolas Klauser #if _LIBCPP_HAS_EXCEPTIONS 3539783f28cSLouis Dionne try { 354ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_EXCEPTIONS 355916fecb4SLouis Dionne typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 356916fecb4SLouis Dionne typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk; 357916fecb4SLouis Dionne #ifndef _LIBCPP_CXX03_LANG 35877a00c0dSLouis Dionne __cntrl_ = new _CntrlBlk(__p, std::move(__d), _AllocT()); 359916fecb4SLouis Dionne #else 360916fecb4SLouis Dionne __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); 361916fecb4SLouis Dionne #endif // not _LIBCPP_CXX03_LANG 362916fecb4SLouis Dionne __enable_weak_this(__p, __p); 363ba87515fSNikolas Klauser #if _LIBCPP_HAS_EXCEPTIONS 3649783f28cSLouis Dionne } catch (...) { 365916fecb4SLouis Dionne __d(__p); 366916fecb4SLouis Dionne throw; 367916fecb4SLouis Dionne } 368ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_EXCEPTIONS 369916fecb4SLouis Dionne } 370916fecb4SLouis Dionne 3719783f28cSLouis Dionne template <class _Yp, 3729783f28cSLouis Dionne class _Dp, 3739783f28cSLouis Dionne class _Alloc, 37476a24727SNikolas Klauser __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0> 3759783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d, _Alloc __a) : __ptr_(__p) { 376ba87515fSNikolas Klauser #if _LIBCPP_HAS_EXCEPTIONS 3779783f28cSLouis Dionne try { 378ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_EXCEPTIONS 379916fecb4SLouis Dionne typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk; 380916fecb4SLouis Dionne typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; 381916fecb4SLouis Dionne typedef __allocator_destructor<_A2> _D2; 382916fecb4SLouis Dionne _A2 __a2(__a); 383916fecb4SLouis Dionne unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); 38477a00c0dSLouis Dionne ::new ((void*)std::addressof(*__hold2.get())) 385916fecb4SLouis Dionne #ifndef _LIBCPP_CXX03_LANG 38677a00c0dSLouis Dionne _CntrlBlk(__p, std::move(__d), __a); 387916fecb4SLouis Dionne #else 388916fecb4SLouis Dionne _CntrlBlk(__p, __d, __a); 389916fecb4SLouis Dionne #endif // not _LIBCPP_CXX03_LANG 39077a00c0dSLouis Dionne __cntrl_ = std::addressof(*__hold2.release()); 391916fecb4SLouis Dionne __enable_weak_this(__p, __p); 392ba87515fSNikolas Klauser #if _LIBCPP_HAS_EXCEPTIONS 3939783f28cSLouis Dionne } catch (...) { 394916fecb4SLouis Dionne __d(__p); 395916fecb4SLouis Dionne throw; 396916fecb4SLouis Dionne } 397ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_EXCEPTIONS 398916fecb4SLouis Dionne } 399916fecb4SLouis Dionne 400e7d56350SLouis Dionne template <class _Dp> 401eaae63d8SHui _LIBCPP_HIDE_FROM_ABI shared_ptr( 402eaae63d8SHui nullptr_t __p, 403eaae63d8SHui _Dp __d, 404eaae63d8SHui __enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs<_Dp>::value, __nullptr_sfinae_tag> = __nullptr_sfinae_tag()) 405eaae63d8SHui : __ptr_(nullptr) { 406ba87515fSNikolas Klauser #if _LIBCPP_HAS_EXCEPTIONS 4079783f28cSLouis Dionne try { 408ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_EXCEPTIONS 409b2d25ef2SLouis Dionne typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT; 410b2d25ef2SLouis Dionne typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk; 411b2d25ef2SLouis Dionne #ifndef _LIBCPP_CXX03_LANG 41277a00c0dSLouis Dionne __cntrl_ = new _CntrlBlk(__p, std::move(__d), _AllocT()); 413b2d25ef2SLouis Dionne #else 414b2d25ef2SLouis Dionne __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); 415b2d25ef2SLouis Dionne #endif // not _LIBCPP_CXX03_LANG 416ba87515fSNikolas Klauser #if _LIBCPP_HAS_EXCEPTIONS 4179783f28cSLouis Dionne } catch (...) { 418b2d25ef2SLouis Dionne __d(__p); 419b2d25ef2SLouis Dionne throw; 420b2d25ef2SLouis Dionne } 421ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_EXCEPTIONS 422b2d25ef2SLouis Dionne } 423b2d25ef2SLouis Dionne 424e7d56350SLouis Dionne template <class _Dp, class _Alloc> 425eaae63d8SHui _LIBCPP_HIDE_FROM_ABI shared_ptr( 426eaae63d8SHui nullptr_t __p, 427eaae63d8SHui _Dp __d, 428eaae63d8SHui _Alloc __a, 429eaae63d8SHui __enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs<_Dp>::value, __nullptr_sfinae_tag> = __nullptr_sfinae_tag()) 430eaae63d8SHui : __ptr_(nullptr) { 431ba87515fSNikolas Klauser #if _LIBCPP_HAS_EXCEPTIONS 4329783f28cSLouis Dionne try { 433ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_EXCEPTIONS 434916fecb4SLouis Dionne typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk; 435916fecb4SLouis Dionne typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; 436916fecb4SLouis Dionne typedef __allocator_destructor<_A2> _D2; 437916fecb4SLouis Dionne _A2 __a2(__a); 438916fecb4SLouis Dionne unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); 43977a00c0dSLouis Dionne ::new ((void*)std::addressof(*__hold2.get())) 440916fecb4SLouis Dionne #ifndef _LIBCPP_CXX03_LANG 44177a00c0dSLouis Dionne _CntrlBlk(__p, std::move(__d), __a); 442916fecb4SLouis Dionne #else 443916fecb4SLouis Dionne _CntrlBlk(__p, __d, __a); 444916fecb4SLouis Dionne #endif // not _LIBCPP_CXX03_LANG 44577a00c0dSLouis Dionne __cntrl_ = std::addressof(*__hold2.release()); 446ba87515fSNikolas Klauser #if _LIBCPP_HAS_EXCEPTIONS 4479783f28cSLouis Dionne } catch (...) { 448916fecb4SLouis Dionne __d(__p); 449916fecb4SLouis Dionne throw; 450916fecb4SLouis Dionne } 451ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_EXCEPTIONS 452916fecb4SLouis Dionne } 453916fecb4SLouis Dionne 454916fecb4SLouis Dionne template <class _Yp> 4559783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT 456916fecb4SLouis Dionne : __ptr_(__p), 4579783f28cSLouis Dionne __cntrl_(__r.__cntrl_) { 458916fecb4SLouis Dionne if (__cntrl_) 459916fecb4SLouis Dionne __cntrl_->__add_shared(); 460916fecb4SLouis Dionne } 461916fecb4SLouis Dionne 462347f45edSpateldeev // LWG-2996 463347f45edSpateldeev // We don't backport because it is an evolutionary change. 464347f45edSpateldeev #if _LIBCPP_STD_VER >= 20 465347f45edSpateldeev template <class _Yp> 466347f45edSpateldeev _LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept 4679783f28cSLouis Dionne : __ptr_(__p), __cntrl_(__r.__cntrl_) { 468347f45edSpateldeev __r.__ptr_ = nullptr; 469347f45edSpateldeev __r.__cntrl_ = nullptr; 470347f45edSpateldeev } 471347f45edSpateldeev #endif 472347f45edSpateldeev 4739783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr(const shared_ptr& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) { 474916fecb4SLouis Dionne if (__cntrl_) 475916fecb4SLouis Dionne __cntrl_->__add_shared(); 476916fecb4SLouis Dionne } 477916fecb4SLouis Dionne 47876a24727SNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0> 4799783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr(const shared_ptr<_Yp>& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) { 480916fecb4SLouis Dionne if (__cntrl_) 481916fecb4SLouis Dionne __cntrl_->__add_shared(); 482916fecb4SLouis Dionne } 483916fecb4SLouis Dionne 4849783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr&& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) { 485916fecb4SLouis Dionne __r.__ptr_ = nullptr; 486916fecb4SLouis Dionne __r.__cntrl_ = nullptr; 487916fecb4SLouis Dionne } 488916fecb4SLouis Dionne 48976a24727SNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0> 4909783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr<_Yp>&& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) { 491916fecb4SLouis Dionne __r.__ptr_ = nullptr; 492916fecb4SLouis Dionne __r.__cntrl_ = nullptr; 493916fecb4SLouis Dionne } 494916fecb4SLouis Dionne 49576a24727SNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0> 4969783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit shared_ptr(const weak_ptr<_Yp>& __r) 4979783f28cSLouis Dionne : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_) { 498b2d25ef2SLouis Dionne if (__cntrl_ == nullptr) 499b2d25ef2SLouis Dionne __throw_bad_weak_ptr(); 500b2d25ef2SLouis Dionne } 501b2d25ef2SLouis Dionne 502916fecb4SLouis Dionne #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 50376a24727SNikolas Klauser template <class _Yp, __enable_if_t<is_convertible<_Yp*, element_type*>::value, int> = 0> 5049783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr(auto_ptr<_Yp>&& __r) : __ptr_(__r.get()) { 505eb12d9b5SLouis Dionne typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<__remove_cv_t<_Yp> > > _CntrlBlk; 506eb12d9b5SLouis Dionne __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<__remove_cv_t<_Yp> >()); 507916fecb4SLouis Dionne __enable_weak_this(__r.get(), __r.get()); 508916fecb4SLouis Dionne __r.release(); 509916fecb4SLouis Dionne } 510916fecb4SLouis Dionne #endif 511916fecb4SLouis Dionne 5129783f28cSLouis Dionne template <class _Yp, 5139783f28cSLouis Dionne class _Dp, 51476a24727SNikolas Klauser __enable_if_t<!is_lvalue_reference<_Dp>::value && __compatible_with<_Yp, _Tp>::value && 51576a24727SNikolas Klauser is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 51676a24727SNikolas Klauser int> = 0> 5179783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) : __ptr_(__r.get()) { 5184f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14 519916fecb4SLouis Dionne if (__ptr_ == nullptr) 520916fecb4SLouis Dionne __cntrl_ = nullptr; 521916fecb4SLouis Dionne else 522916fecb4SLouis Dionne #endif 523916fecb4SLouis Dionne { 524916fecb4SLouis Dionne typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 525916fecb4SLouis Dionne typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT> _CntrlBlk; 52634538dbaSAsher Mancinelli __cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT()); 527916fecb4SLouis Dionne __enable_weak_this(__r.get(), __r.get()); 528916fecb4SLouis Dionne } 529916fecb4SLouis Dionne __r.release(); 530916fecb4SLouis Dionne } 531916fecb4SLouis Dionne 5329783f28cSLouis Dionne template <class _Yp, 5339783f28cSLouis Dionne class _Dp, 5349783f28cSLouis Dionne class = void, 53576a24727SNikolas Klauser __enable_if_t<is_lvalue_reference<_Dp>::value && __compatible_with<_Yp, _Tp>::value && 53676a24727SNikolas Klauser is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, 53776a24727SNikolas Klauser int> = 0> 5389783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) : __ptr_(__r.get()) { 5394f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14 540916fecb4SLouis Dionne if (__ptr_ == nullptr) 541916fecb4SLouis Dionne __cntrl_ = nullptr; 542916fecb4SLouis Dionne else 543916fecb4SLouis Dionne #endif 544916fecb4SLouis Dionne { 545916fecb4SLouis Dionne typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; 546916fecb4SLouis Dionne typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, 5475fab33afSNikolas Klauser reference_wrapper<__libcpp_remove_reference_t<_Dp> >, 5489783f28cSLouis Dionne _AllocT> 5499783f28cSLouis Dionne _CntrlBlk; 55077a00c0dSLouis Dionne __cntrl_ = new _CntrlBlk(__r.get(), std::ref(__r.get_deleter()), _AllocT()); 551916fecb4SLouis Dionne __enable_weak_this(__r.get(), __r.get()); 552916fecb4SLouis Dionne } 553916fecb4SLouis Dionne __r.release(); 554916fecb4SLouis Dionne } 555916fecb4SLouis Dionne 5569783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI ~shared_ptr() { 557916fecb4SLouis Dionne if (__cntrl_) 558916fecb4SLouis Dionne __cntrl_->__release_shared(); 559916fecb4SLouis Dionne } 560916fecb4SLouis Dionne 5619783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(const shared_ptr& __r) _NOEXCEPT { 562916fecb4SLouis Dionne shared_ptr(__r).swap(*this); 563916fecb4SLouis Dionne return *this; 564916fecb4SLouis Dionne } 565916fecb4SLouis Dionne 56676a24727SNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0> 5679783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT { 568916fecb4SLouis Dionne shared_ptr(__r).swap(*this); 569916fecb4SLouis Dionne return *this; 570916fecb4SLouis Dionne } 571916fecb4SLouis Dionne 5729783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(shared_ptr&& __r) _NOEXCEPT { 57377a00c0dSLouis Dionne shared_ptr(std::move(__r)).swap(*this); 574916fecb4SLouis Dionne return *this; 575916fecb4SLouis Dionne } 576916fecb4SLouis Dionne 57776a24727SNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0> 5789783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(shared_ptr<_Yp>&& __r) { 57977a00c0dSLouis Dionne shared_ptr(std::move(__r)).swap(*this); 580916fecb4SLouis Dionne return *this; 581916fecb4SLouis Dionne } 582916fecb4SLouis Dionne 583916fecb4SLouis Dionne #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) 5849783f28cSLouis Dionne template <class _Yp, 58576a24727SNikolas Klauser __enable_if_t<!is_array<_Yp>::value && is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, 58676a24727SNikolas Klauser int> = 0> 5879783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(auto_ptr<_Yp>&& __r) { 58877a00c0dSLouis Dionne shared_ptr(std::move(__r)).swap(*this); 589916fecb4SLouis Dionne return *this; 590916fecb4SLouis Dionne } 591916fecb4SLouis Dionne #endif 592916fecb4SLouis Dionne 59376a24727SNikolas Klauser template <class _Yp, 5949783f28cSLouis Dionne class _Dp, 59576a24727SNikolas Klauser __enable_if_t<_And< __compatible_with<_Yp, _Tp>, 59676a24727SNikolas Klauser is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*> >::value, 59776a24727SNikolas Klauser int> = 0> 5989783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(unique_ptr<_Yp, _Dp>&& __r) { 59977a00c0dSLouis Dionne shared_ptr(std::move(__r)).swap(*this); 600916fecb4SLouis Dionne return *this; 601916fecb4SLouis Dionne } 602916fecb4SLouis Dionne 6039783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void swap(shared_ptr& __r) _NOEXCEPT { 60477a00c0dSLouis Dionne std::swap(__ptr_, __r.__ptr_); 60577a00c0dSLouis Dionne std::swap(__cntrl_, __r.__cntrl_); 606916fecb4SLouis Dionne } 607916fecb4SLouis Dionne 6089783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT { shared_ptr().swap(*this); } 609916fecb4SLouis Dionne 61076a24727SNikolas Klauser template <class _Yp, __enable_if_t<__raw_pointer_compatible_with<_Yp, _Tp>::value, int> = 0> 6119783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p) { 612916fecb4SLouis Dionne shared_ptr(__p).swap(*this); 613916fecb4SLouis Dionne } 614916fecb4SLouis Dionne 61576a24727SNikolas Klauser template <class _Yp, class _Dp, __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0> 6169783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p, _Dp __d) { 617916fecb4SLouis Dionne shared_ptr(__p, __d).swap(*this); 618916fecb4SLouis Dionne } 619916fecb4SLouis Dionne 6209783f28cSLouis Dionne template <class _Yp, 6219783f28cSLouis Dionne class _Dp, 6229783f28cSLouis Dionne class _Alloc, 62376a24727SNikolas Klauser __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0> 6249783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p, _Dp __d, _Alloc __a) { 625916fecb4SLouis Dionne shared_ptr(__p, __d, __a).swap(*this); 626916fecb4SLouis Dionne } 627916fecb4SLouis Dionne 6289783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; } 6299783f28cSLouis Dionne 6309783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT { return *__ptr_; } 6319783f28cSLouis Dionne 6329783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI element_type* operator->() const _NOEXCEPT { 6339783f28cSLouis Dionne static_assert(!is_array<_Tp>::value, "std::shared_ptr<T>::operator-> is only valid when T is not an array type."); 634b2d25ef2SLouis Dionne return __ptr_; 635b2d25ef2SLouis Dionne } 636b2d25ef2SLouis Dionne 6379783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; } 638b2d25ef2SLouis Dionne 63981cedac8SMark de Wever #if _LIBCPP_STD_VER < 20 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE) 64081cedac8SMark de Wever _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT { return use_count() == 1; } 64181cedac8SMark de Wever #endif 642b2d25ef2SLouis Dionne 6439783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return get() != nullptr; } 644b2d25ef2SLouis Dionne 645b2d25ef2SLouis Dionne template <class _Up> 6469783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT { 647b2d25ef2SLouis Dionne return __cntrl_ < __p.__cntrl_; 648b2d25ef2SLouis Dionne } 649b2d25ef2SLouis Dionne 650b2d25ef2SLouis Dionne template <class _Up> 6519783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT { 652b2d25ef2SLouis Dionne return __cntrl_ < __p.__cntrl_; 653b2d25ef2SLouis Dionne } 654b2d25ef2SLouis Dionne 6559783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool __owner_equivalent(const shared_ptr& __p) const { return __cntrl_ == __p.__cntrl_; } 656b2d25ef2SLouis Dionne 6574f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 17 6589783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const { 6599783f28cSLouis Dionne static_assert(is_array<_Tp>::value, "std::shared_ptr<T>::operator[] is only valid when T is an array type."); 660b2d25ef2SLouis Dionne return __ptr_[__i]; 661b2d25ef2SLouis Dionne } 662b2d25ef2SLouis Dionne #endif 663b2d25ef2SLouis Dionne 664ba87515fSNikolas Klauser #if _LIBCPP_HAS_RTTI 665b2d25ef2SLouis Dionne template <class _Dp> 6669783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI _Dp* __get_deleter() const _NOEXCEPT { 6679783f28cSLouis Dionne return static_cast<_Dp*>(__cntrl_ ? const_cast<void*>(__cntrl_->__get_deleter(typeid(_Dp))) : nullptr); 668b2d25ef2SLouis Dionne } 669ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_RTTI 670b2d25ef2SLouis Dionne 671b2d25ef2SLouis Dionne template <class _Yp, class _CntrlBlk> 6729783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static shared_ptr<_Tp> __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT { 673b2d25ef2SLouis Dionne shared_ptr<_Tp> __r; 674b2d25ef2SLouis Dionne __r.__ptr_ = __p; 675b2d25ef2SLouis Dionne __r.__cntrl_ = __cntrl; 676b2d25ef2SLouis Dionne __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); 677b2d25ef2SLouis Dionne return __r; 678b2d25ef2SLouis Dionne } 679b2d25ef2SLouis Dionne 680b2d25ef2SLouis Dionne private: 681b2d25ef2SLouis Dionne template <class _Yp, bool = is_function<_Yp>::value> 6829783f28cSLouis Dionne struct __shared_ptr_default_allocator { 683eb12d9b5SLouis Dionne typedef allocator<__remove_cv_t<_Yp> > type; 684b2d25ef2SLouis Dionne }; 685b2d25ef2SLouis Dionne 686b2d25ef2SLouis Dionne template <class _Yp> 6879783f28cSLouis Dionne struct __shared_ptr_default_allocator<_Yp, true> { 688b2d25ef2SLouis Dionne typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type; 689b2d25ef2SLouis Dionne }; 690b2d25ef2SLouis Dionne 6919783f28cSLouis Dionne template <class _Yp, 6929783f28cSLouis Dionne class _OrigPtr, 69376a24727SNikolas Klauser __enable_if_t<is_convertible<_OrigPtr*, const enable_shared_from_this<_Yp>*>::value, int> = 0> 6949783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void __enable_weak_this(const enable_shared_from_this<_Yp>* __e, _OrigPtr* __ptr) _NOEXCEPT { 6955fab33afSNikolas Klauser typedef __remove_cv_t<_Yp> _RawYp; 6969783f28cSLouis Dionne if (__e && __e->__weak_this_.expired()) { 6979783f28cSLouis Dionne __e->__weak_this_ = shared_ptr<_RawYp>(*this, const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr))); 698b2d25ef2SLouis Dionne } 699b2d25ef2SLouis Dionne } 700b2d25ef2SLouis Dionne 701b2d25ef2SLouis Dionne _LIBCPP_HIDE_FROM_ABI void __enable_weak_this(...) _NOEXCEPT {} 702b2d25ef2SLouis Dionne 703b2d25ef2SLouis Dionne template <class, class _Yp> 7049783f28cSLouis Dionne struct __shared_ptr_default_delete : default_delete<_Yp> {}; 705b2d25ef2SLouis Dionne 706b2d25ef2SLouis Dionne template <class _Yp, class _Un, size_t _Sz> 7079783f28cSLouis Dionne struct __shared_ptr_default_delete<_Yp[_Sz], _Un> : default_delete<_Yp[]> {}; 708b2d25ef2SLouis Dionne 709b2d25ef2SLouis Dionne template <class _Yp, class _Un> 7109783f28cSLouis Dionne struct __shared_ptr_default_delete<_Yp[], _Un> : default_delete<_Yp[]> {}; 711b2d25ef2SLouis Dionne 7129783f28cSLouis Dionne template <class _Up> 7139783f28cSLouis Dionne friend class _LIBCPP_TEMPLATE_VIS shared_ptr; 7149783f28cSLouis Dionne template <class _Up> 7159783f28cSLouis Dionne friend class _LIBCPP_TEMPLATE_VIS weak_ptr; 716b2d25ef2SLouis Dionne }; 717b2d25ef2SLouis Dionne 7184f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 17 719b2d25ef2SLouis Dionne template <class _Tp> 720b2d25ef2SLouis Dionne shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; 721b2d25ef2SLouis Dionne template <class _Tp, class _Dp> 722b2d25ef2SLouis Dionne shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>; 723b2d25ef2SLouis Dionne #endif 724b2d25ef2SLouis Dionne 725916fecb4SLouis Dionne // 726916fecb4SLouis Dionne // std::allocate_shared and std::make_shared 727916fecb4SLouis Dionne // 72876a24727SNikolas Klauser template <class _Tp, class _Alloc, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0> 7299783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) { 730916fecb4SLouis Dionne using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>; 731916fecb4SLouis Dionne using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type; 732916fecb4SLouis Dionne __allocation_guard<_ControlBlockAllocator> __guard(__a, 1); 73377a00c0dSLouis Dionne ::new ((void*)std::addressof(*__guard.__get())) _ControlBlock(__a, std::forward<_Args>(__args)...); 734916fecb4SLouis Dionne auto __control_block = __guard.__release_ptr(); 7359783f28cSLouis Dionne return shared_ptr<_Tp>::__create_with_control_block( 7369783f28cSLouis Dionne (*__control_block).__get_elem(), std::addressof(*__control_block)); 737916fecb4SLouis Dionne } 738916fecb4SLouis Dionne 73976a24727SNikolas Klauser template <class _Tp, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0> 7409783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) { 741eb12d9b5SLouis Dionne return std::allocate_shared<_Tp>(allocator<__remove_cv_t<_Tp> >(), std::forward<_Args>(__args)...); 742916fecb4SLouis Dionne } 743916fecb4SLouis Dionne 7449af9d39aSHui #if _LIBCPP_STD_VER >= 20 7459af9d39aSHui 7469af9d39aSHui template <class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0> 7479783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) { 74858010902SLouis Dionne using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>; 74958010902SLouis Dionne _ForOverwriteAllocator __alloc(__a); 75058010902SLouis Dionne return std::allocate_shared<_Tp>(__alloc); 7519af9d39aSHui } 7529af9d39aSHui 7539af9d39aSHui template <class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0> 7549783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() { 755eb12d9b5SLouis Dionne return std::allocate_shared_for_overwrite<_Tp>(allocator<__remove_cv_t<_Tp>>()); 7569af9d39aSHui } 7579af9d39aSHui 7589af9d39aSHui #endif // _LIBCPP_STD_VER >= 20 7599af9d39aSHui 7604f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 17 761e27a122bSLouis Dionne 762e27a122bSLouis Dionne template <size_t _Alignment> 763e27a122bSLouis Dionne struct __sp_aligned_storage { 764e27a122bSLouis Dionne alignas(_Alignment) char __storage[_Alignment]; 765e27a122bSLouis Dionne }; 766e27a122bSLouis Dionne 767e27a122bSLouis Dionne template <class _Tp, class _Alloc> 768e27a122bSLouis Dionne struct __unbounded_array_control_block; 769e27a122bSLouis Dionne 770e27a122bSLouis Dionne template <class _Tp, class _Alloc> 7719783f28cSLouis Dionne struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count { 7729783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr _Tp* __get_data() noexcept { return __data_; } 773e27a122bSLouis Dionne 7749783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __unbounded_array_control_block( 7759783f28cSLouis Dionne _Alloc const& __alloc, size_t __count, _Tp const& __arg) 7769783f28cSLouis Dionne : __alloc_(__alloc), __count_(__count) { 777ba43f3e8SNikolas Klauser std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::begin(__data_), __count_, __arg); 778e27a122bSLouis Dionne } 779e27a122bSLouis Dionne 7809783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count) 7819783f28cSLouis Dionne : __alloc_(__alloc), __count_(__count) { 7829af9d39aSHui # if _LIBCPP_STD_VER >= 20 78358010902SLouis Dionne if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) { 7849af9d39aSHui // We are purposefully not using an allocator-aware default construction because the spec says so. 7859af9d39aSHui // There's currently no way of expressing default initialization in an allocator-aware manner anyway. 7869af9d39aSHui std::uninitialized_default_construct_n(std::begin(__data_), __count_); 78758010902SLouis Dionne } else { 78858010902SLouis Dionne std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_); 7899af9d39aSHui } 79058010902SLouis Dionne # else 79158010902SLouis Dionne std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_); 7929af9d39aSHui # endif 79358010902SLouis Dionne } 7949af9d39aSHui 795e27a122bSLouis Dionne // Returns the number of bytes required to store a control block followed by the given number 796e27a122bSLouis Dionne // of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment. 7979783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static constexpr size_t __bytes_for(size_t __elements) { 798e27a122bSLouis Dionne // When there's 0 elements, the control block alone is enough since it holds one element. 799e27a122bSLouis Dionne // Otherwise, we allocate one fewer element than requested because the control block already 800e27a122bSLouis Dionne // holds one. Also, we use the bitwise formula below to ensure that we allocate enough bytes 801e27a122bSLouis Dionne // for the whole allocation to be a multiple of _Tp's alignment. That formula is taken from [1]. 802e27a122bSLouis Dionne // 803e27a122bSLouis Dionne // [1]: https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding 804e27a122bSLouis Dionne size_t __bytes = __elements == 0 ? sizeof(__unbounded_array_control_block) 805e27a122bSLouis Dionne : (__elements - 1) * sizeof(_Tp) + sizeof(__unbounded_array_control_block); 806e27a122bSLouis Dionne constexpr size_t __align = alignof(_Tp); 807e27a122bSLouis Dionne return (__bytes + __align - 1) & ~(__align - 1); 808e27a122bSLouis Dionne } 809e27a122bSLouis Dionne 8105efc8116SLouis Dionne _LIBCPP_HIDE_FROM_ABI_VIRTUAL 8119783f28cSLouis Dionne ~__unbounded_array_control_block() override { 8129783f28cSLouis Dionne } // can't be `= default` because of the sometimes-non-trivial union member __data_ 813e27a122bSLouis Dionne 814e27a122bSLouis Dionne private: 81583ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { 81658010902SLouis Dionne # if _LIBCPP_STD_VER >= 20 81758010902SLouis Dionne if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) { 81858010902SLouis Dionne std::__reverse_destroy(__data_, __data_ + __count_); 81958010902SLouis Dionne } else { 820e27a122bSLouis Dionne __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_); 821e27a122bSLouis Dionne std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_); 822e27a122bSLouis Dionne } 82358010902SLouis Dionne # else 82458010902SLouis Dionne __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_); 82558010902SLouis Dionne std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_); 82658010902SLouis Dionne # endif 82758010902SLouis Dionne } 828e27a122bSLouis Dionne 82983ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override { 830e27a122bSLouis Dionne using _AlignedStorage = __sp_aligned_storage<alignof(__unbounded_array_control_block)>; 831e27a122bSLouis Dionne using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>; 832e27a122bSLouis Dionne using _PointerTraits = pointer_traits<typename allocator_traits<_StorageAlloc>::pointer>; 833e27a122bSLouis Dionne 834e27a122bSLouis Dionne _StorageAlloc __tmp(__alloc_); 835e27a122bSLouis Dionne __alloc_.~_Alloc(); 836e27a122bSLouis Dionne size_t __size = __unbounded_array_control_block::__bytes_for(__count_); 837e27a122bSLouis Dionne _AlignedStorage* __storage = reinterpret_cast<_AlignedStorage*>(this); 838f722db02SIlya Biryukov allocator_traits<_StorageAlloc>::deallocate( 839f722db02SIlya Biryukov __tmp, _PointerTraits::pointer_to(*__storage), __size / sizeof(_AlignedStorage)); 840e27a122bSLouis Dionne } 841e27a122bSLouis Dionne 842e27a122bSLouis Dionne _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_; 843e27a122bSLouis Dionne size_t __count_; 844e27a122bSLouis Dionne union { 845e27a122bSLouis Dionne _Tp __data_[1]; 846e27a122bSLouis Dionne }; 847e27a122bSLouis Dionne }; 848e27a122bSLouis Dionne 849e27a122bSLouis Dionne template <class _Array, class _Alloc, class... _Arg> 8509783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Array> 8519783f28cSLouis Dionne __allocate_shared_unbounded_array(const _Alloc& __a, size_t __n, _Arg&&... __arg) { 85230213e99SNikolas Klauser static_assert(__is_unbounded_array_v<_Array>); 853e27a122bSLouis Dionne // We compute the number of bytes necessary to hold the control block and the 854e27a122bSLouis Dionne // array elements. Then, we allocate an array of properly-aligned dummy structs 855e27a122bSLouis Dionne // large enough to hold the control block and array. This allows shifting the 856e27a122bSLouis Dionne // burden of aligning memory properly from us to the allocator. 857e27a122bSLouis Dionne using _ControlBlock = __unbounded_array_control_block<_Array, _Alloc>; 858e27a122bSLouis Dionne using _AlignedStorage = __sp_aligned_storage<alignof(_ControlBlock)>; 859e27a122bSLouis Dionne using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>; 860e27a122bSLouis Dionne __allocation_guard<_StorageAlloc> __guard(__a, _ControlBlock::__bytes_for(__n) / sizeof(_AlignedStorage)); 861e27a122bSLouis Dionne _ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get())); 862971e9c80SNikolas Klauser std::__construct_at(__control_block, __a, __n, std::forward<_Arg>(__arg)...); 863e27a122bSLouis Dionne __guard.__release_ptr(); 864e27a122bSLouis Dionne return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block); 865e27a122bSLouis Dionne } 866e27a122bSLouis Dionne 867e27a122bSLouis Dionne template <class _Tp, class _Alloc> 868e27a122bSLouis Dionne struct __bounded_array_control_block; 869e27a122bSLouis Dionne 870e27a122bSLouis Dionne template <class _Tp, size_t _Count, class _Alloc> 8719783f28cSLouis Dionne struct __bounded_array_control_block<_Tp[_Count], _Alloc> : __shared_weak_count { 8729783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI constexpr _Tp* __get_data() noexcept { return __data_; } 873e27a122bSLouis Dionne 8749783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __bounded_array_control_block(_Alloc const& __alloc, _Tp const& __arg) 8759783f28cSLouis Dionne : __alloc_(__alloc) { 876ba43f3e8SNikolas Klauser std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count, __arg); 877e27a122bSLouis Dionne } 878e27a122bSLouis Dionne 8799783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit __bounded_array_control_block(_Alloc const& __alloc) : __alloc_(__alloc) { 8809af9d39aSHui # if _LIBCPP_STD_VER >= 20 88158010902SLouis Dionne if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) { 8829af9d39aSHui // We are purposefully not using an allocator-aware default construction because the spec says so. 8839af9d39aSHui // There's currently no way of expressing default initialization in an allocator-aware manner anyway. 8849af9d39aSHui std::uninitialized_default_construct_n(std::addressof(__data_[0]), _Count); 88558010902SLouis Dionne } else { 88658010902SLouis Dionne std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count); 8879af9d39aSHui } 88858010902SLouis Dionne # else 88958010902SLouis Dionne std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count); 8909af9d39aSHui # endif 89158010902SLouis Dionne } 8929af9d39aSHui 8935efc8116SLouis Dionne _LIBCPP_HIDE_FROM_ABI_VIRTUAL 8949783f28cSLouis Dionne ~__bounded_array_control_block() override { 8959783f28cSLouis Dionne } // can't be `= default` because of the sometimes-non-trivial union member __data_ 896e27a122bSLouis Dionne 897e27a122bSLouis Dionne private: 89883ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { 89958010902SLouis Dionne # if _LIBCPP_STD_VER >= 20 90058010902SLouis Dionne if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) { 90158010902SLouis Dionne std::__reverse_destroy(__data_, __data_ + _Count); 90258010902SLouis Dionne } else { 903e27a122bSLouis Dionne __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_); 904e27a122bSLouis Dionne std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count); 905e27a122bSLouis Dionne } 90658010902SLouis Dionne # else 90758010902SLouis Dionne __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_); 90858010902SLouis Dionne std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count); 90958010902SLouis Dionne # endif 91058010902SLouis Dionne } 911e27a122bSLouis Dionne 91283ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override { 913e27a122bSLouis Dionne using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, __bounded_array_control_block>; 914e27a122bSLouis Dionne using _PointerTraits = pointer_traits<typename allocator_traits<_ControlBlockAlloc>::pointer>; 915e27a122bSLouis Dionne 916e27a122bSLouis Dionne _ControlBlockAlloc __tmp(__alloc_); 917e27a122bSLouis Dionne __alloc_.~_Alloc(); 918f722db02SIlya Biryukov allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*this), 1); 919e27a122bSLouis Dionne } 920e27a122bSLouis Dionne 921e27a122bSLouis Dionne _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_; 922e27a122bSLouis Dionne union { 923e27a122bSLouis Dionne _Tp __data_[_Count]; 924e27a122bSLouis Dionne }; 925e27a122bSLouis Dionne }; 926e27a122bSLouis Dionne 927e27a122bSLouis Dionne template <class _Array, class _Alloc, class... _Arg> 9289783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&&... __arg) { 92930213e99SNikolas Klauser static_assert(__is_bounded_array_v<_Array>); 930e27a122bSLouis Dionne using _ControlBlock = __bounded_array_control_block<_Array, _Alloc>; 931e27a122bSLouis Dionne using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, _ControlBlock>; 932e27a122bSLouis Dionne 933e27a122bSLouis Dionne __allocation_guard<_ControlBlockAlloc> __guard(__a, 1); 934e27a122bSLouis Dionne _ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get())); 935971e9c80SNikolas Klauser std::__construct_at(__control_block, __a, std::forward<_Arg>(__arg)...); 936e27a122bSLouis Dionne __guard.__release_ptr(); 937e27a122bSLouis Dionne return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block); 938e27a122bSLouis Dionne } 939e27a122bSLouis Dionne 9404f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 17 941971e9c80SNikolas Klauser 9424f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 943971e9c80SNikolas Klauser 9449af9d39aSHui // bounded array variants 94576a24727SNikolas Klauser template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> 9469783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a) { 947e27a122bSLouis Dionne return std::__allocate_shared_bounded_array<_Tp>(__a); 948e27a122bSLouis Dionne } 949e27a122bSLouis Dionne 95076a24727SNikolas Klauser template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> 9519783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u) { 952e27a122bSLouis Dionne return std::__allocate_shared_bounded_array<_Tp>(__a, __u); 953e27a122bSLouis Dionne } 954e27a122bSLouis Dionne 9559af9d39aSHui template <class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> 9569783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a) { 95758010902SLouis Dionne using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>; 95858010902SLouis Dionne _ForOverwriteAllocator __alloc(__a); 95958010902SLouis Dionne return std::__allocate_shared_bounded_array<_Tp>(__alloc); 960e27a122bSLouis Dionne } 961e27a122bSLouis Dionne 96276a24727SNikolas Klauser template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> 9639783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared() { 964e27a122bSLouis Dionne return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>()); 965e27a122bSLouis Dionne } 966e27a122bSLouis Dionne 96776a24727SNikolas Klauser template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> 9689783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u) { 969e27a122bSLouis Dionne return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u); 970e27a122bSLouis Dionne } 971e27a122bSLouis Dionne 9729af9d39aSHui template <class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0> 9739783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite() { 97458010902SLouis Dionne return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>()); 9759af9d39aSHui } 9769af9d39aSHui 9779af9d39aSHui // unbounded array variants 97876a24727SNikolas Klauser template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> 9799783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n) { 9809af9d39aSHui return std::__allocate_shared_unbounded_array<_Tp>(__a, __n); 9819af9d39aSHui } 9829af9d39aSHui 98376a24727SNikolas Klauser template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> 9849783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u) { 9859af9d39aSHui return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u); 9869af9d39aSHui } 9879af9d39aSHui 9889af9d39aSHui template <class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> 9899783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n) { 99058010902SLouis Dionne using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>; 99158010902SLouis Dionne _ForOverwriteAllocator __alloc(__a); 99258010902SLouis Dionne return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n); 9939af9d39aSHui } 9949af9d39aSHui 99576a24727SNikolas Klauser template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> 9969783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n) { 997e27a122bSLouis Dionne return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n); 998e27a122bSLouis Dionne } 999e27a122bSLouis Dionne 100076a24727SNikolas Klauser template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> 10019783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u) { 1002e27a122bSLouis Dionne return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u); 1003e27a122bSLouis Dionne } 1004e27a122bSLouis Dionne 10059af9d39aSHui template <class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0> 10069783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) { 100758010902SLouis Dionne return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n); 10089af9d39aSHui } 10099af9d39aSHui 10104f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 1011e27a122bSLouis Dionne 1012916fecb4SLouis Dionne template <class _Tp, class _Up> 10139783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT { 1014916fecb4SLouis Dionne return __x.get() == __y.get(); 1015916fecb4SLouis Dionne } 1016916fecb4SLouis Dionne 10173b217f2fSAdrian Vogelsgesang #if _LIBCPP_STD_VER <= 17 10183b217f2fSAdrian Vogelsgesang 1019916fecb4SLouis Dionne template <class _Tp, class _Up> 10209783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT { 1021916fecb4SLouis Dionne return !(__x == __y); 1022916fecb4SLouis Dionne } 1023916fecb4SLouis Dionne 1024916fecb4SLouis Dionne template <class _Tp, class _Up> 10259783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT { 1026916fecb4SLouis Dionne # if _LIBCPP_STD_VER <= 11 1027916fecb4SLouis Dionne typedef typename common_type<_Tp*, _Up*>::type _Vp; 1028916fecb4SLouis Dionne return less<_Vp>()(__x.get(), __y.get()); 1029916fecb4SLouis Dionne # else 1030916fecb4SLouis Dionne return less<>()(__x.get(), __y.get()); 1031916fecb4SLouis Dionne # endif 1032916fecb4SLouis Dionne } 1033916fecb4SLouis Dionne 1034916fecb4SLouis Dionne template <class _Tp, class _Up> 10359783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT { 1036916fecb4SLouis Dionne return __y < __x; 1037916fecb4SLouis Dionne } 1038916fecb4SLouis Dionne 1039916fecb4SLouis Dionne template <class _Tp, class _Up> 10409783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT { 1041916fecb4SLouis Dionne return !(__y < __x); 1042916fecb4SLouis Dionne } 1043916fecb4SLouis Dionne 1044916fecb4SLouis Dionne template <class _Tp, class _Up> 10459783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT { 1046916fecb4SLouis Dionne return !(__x < __y); 1047916fecb4SLouis Dionne } 1048916fecb4SLouis Dionne 10493b217f2fSAdrian Vogelsgesang #endif // _LIBCPP_STD_VER <= 17 10503b217f2fSAdrian Vogelsgesang 10514f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 10523b217f2fSAdrian Vogelsgesang template <class _Tp, class _Up> 10539783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) noexcept { 10543b217f2fSAdrian Vogelsgesang return compare_three_way()(__x.get(), __y.get()); 10553b217f2fSAdrian Vogelsgesang } 10563b217f2fSAdrian Vogelsgesang #endif 10573b217f2fSAdrian Vogelsgesang 1058916fecb4SLouis Dionne template <class _Tp> 10599783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT { 1060916fecb4SLouis Dionne return !__x; 1061916fecb4SLouis Dionne } 1062916fecb4SLouis Dionne 10633b217f2fSAdrian Vogelsgesang #if _LIBCPP_STD_VER <= 17 10643b217f2fSAdrian Vogelsgesang 1065916fecb4SLouis Dionne template <class _Tp> 10669783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT { 1067916fecb4SLouis Dionne return !__x; 1068916fecb4SLouis Dionne } 1069916fecb4SLouis Dionne 1070916fecb4SLouis Dionne template <class _Tp> 10719783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT { 1072916fecb4SLouis Dionne return static_cast<bool>(__x); 1073916fecb4SLouis Dionne } 1074916fecb4SLouis Dionne 1075916fecb4SLouis Dionne template <class _Tp> 10769783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT { 1077916fecb4SLouis Dionne return static_cast<bool>(__x); 1078916fecb4SLouis Dionne } 1079916fecb4SLouis Dionne 1080916fecb4SLouis Dionne template <class _Tp> 10819783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT { 108265a1efc6SJames Touton return less<typename shared_ptr<_Tp>::element_type*>()(__x.get(), nullptr); 1083916fecb4SLouis Dionne } 1084916fecb4SLouis Dionne 1085916fecb4SLouis Dionne template <class _Tp> 10869783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT { 108765a1efc6SJames Touton return less<typename shared_ptr<_Tp>::element_type*>()(nullptr, __x.get()); 1088916fecb4SLouis Dionne } 1089916fecb4SLouis Dionne 1090916fecb4SLouis Dionne template <class _Tp> 10919783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT { 1092916fecb4SLouis Dionne return nullptr < __x; 1093916fecb4SLouis Dionne } 1094916fecb4SLouis Dionne 1095916fecb4SLouis Dionne template <class _Tp> 10969783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT { 1097916fecb4SLouis Dionne return __x < nullptr; 1098916fecb4SLouis Dionne } 1099916fecb4SLouis Dionne 1100916fecb4SLouis Dionne template <class _Tp> 11019783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT { 1102916fecb4SLouis Dionne return !(nullptr < __x); 1103916fecb4SLouis Dionne } 1104916fecb4SLouis Dionne 1105916fecb4SLouis Dionne template <class _Tp> 11069783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT { 1107916fecb4SLouis Dionne return !(__x < nullptr); 1108916fecb4SLouis Dionne } 1109916fecb4SLouis Dionne 1110916fecb4SLouis Dionne template <class _Tp> 11119783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT { 1112916fecb4SLouis Dionne return !(__x < nullptr); 1113916fecb4SLouis Dionne } 1114916fecb4SLouis Dionne 1115916fecb4SLouis Dionne template <class _Tp> 11169783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT { 1117916fecb4SLouis Dionne return !(nullptr < __x); 1118916fecb4SLouis Dionne } 1119916fecb4SLouis Dionne 11203b217f2fSAdrian Vogelsgesang #endif // _LIBCPP_STD_VER <= 17 11213b217f2fSAdrian Vogelsgesang 11224f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 11233b217f2fSAdrian Vogelsgesang template <class _Tp> 11249783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(shared_ptr<_Tp> const& __x, nullptr_t) noexcept { 11253b217f2fSAdrian Vogelsgesang return compare_three_way()(__x.get(), static_cast<typename shared_ptr<_Tp>::element_type*>(nullptr)); 11263b217f2fSAdrian Vogelsgesang } 11273b217f2fSAdrian Vogelsgesang #endif 11283b217f2fSAdrian Vogelsgesang 1129916fecb4SLouis Dionne template <class _Tp> 11309783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI void swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT { 1131916fecb4SLouis Dionne __x.swap(__y); 1132916fecb4SLouis Dionne } 1133916fecb4SLouis Dionne 1134916fecb4SLouis Dionne template <class _Tp, class _Up> 11359783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { 11369783f28cSLouis Dionne return shared_ptr<_Tp>(__r, static_cast< typename shared_ptr<_Tp>::element_type*>(__r.get())); 1137916fecb4SLouis Dionne } 1138916fecb4SLouis Dionne 1139347f45edSpateldeev // LWG-2996 1140347f45edSpateldeev // We don't backport because it is an evolutionary change. 1141347f45edSpateldeev #if _LIBCPP_STD_VER >= 20 1142347f45edSpateldeev template <class _Tp, class _Up> 1143347f45edSpateldeev _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept { 1144347f45edSpateldeev return shared_ptr<_Tp>(std::move(__r), static_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); 1145347f45edSpateldeev } 1146347f45edSpateldeev #endif 1147347f45edSpateldeev 1148916fecb4SLouis Dionne template <class _Tp, class _Up> 11499783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { 1150916fecb4SLouis Dionne typedef typename shared_ptr<_Tp>::element_type _ET; 1151916fecb4SLouis Dionne _ET* __p = dynamic_cast<_ET*>(__r.get()); 1152916fecb4SLouis Dionne return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>(); 1153916fecb4SLouis Dionne } 1154916fecb4SLouis Dionne 1155347f45edSpateldeev // LWG-2996 1156347f45edSpateldeev // We don't backport because it is an evolutionary change. 1157347f45edSpateldeev #if _LIBCPP_STD_VER >= 20 1158347f45edSpateldeev template <class _Tp, class _Up> 1159347f45edSpateldeev _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept { 1160347f45edSpateldeev auto* __p = dynamic_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()); 1161347f45edSpateldeev return __p ? shared_ptr<_Tp>(std::move(__r), __p) : shared_ptr<_Tp>(); 1162347f45edSpateldeev } 1163347f45edSpateldeev #endif 1164347f45edSpateldeev 1165916fecb4SLouis Dionne template <class _Tp, class _Up> 11669783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { 1167916fecb4SLouis Dionne typedef typename shared_ptr<_Tp>::element_type _RTp; 1168916fecb4SLouis Dionne return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get())); 1169916fecb4SLouis Dionne } 1170916fecb4SLouis Dionne 1171347f45edSpateldeev // LWG-2996 1172347f45edSpateldeev // We don't backport because it is an evolutionary change. 1173347f45edSpateldeev #if _LIBCPP_STD_VER >= 20 1174347f45edSpateldeev template <class _Tp, class _Up> 1175347f45edSpateldeev _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept { 1176347f45edSpateldeev return shared_ptr<_Tp>(std::move(__r), const_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); 1177347f45edSpateldeev } 1178347f45edSpateldeev #endif 1179347f45edSpateldeev 1180916fecb4SLouis Dionne template <class _Tp, class _Up> 11819783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT { 11829783f28cSLouis Dionne return shared_ptr<_Tp>(__r, reinterpret_cast< typename shared_ptr<_Tp>::element_type*>(__r.get())); 1183916fecb4SLouis Dionne } 1184916fecb4SLouis Dionne 1185347f45edSpateldeev // LWG-2996 1186347f45edSpateldeev // We don't backport because it is an evolutionary change. 1187347f45edSpateldeev #if _LIBCPP_STD_VER >= 20 1188347f45edSpateldeev template <class _Tp, class _Up> 1189347f45edSpateldeev _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept { 1190347f45edSpateldeev return shared_ptr<_Tp>(std::move(__r), reinterpret_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); 1191347f45edSpateldeev } 1192347f45edSpateldeev #endif 1193347f45edSpateldeev 1194ba87515fSNikolas Klauser #if _LIBCPP_HAS_RTTI 1195916fecb4SLouis Dionne 1196916fecb4SLouis Dionne template <class _Dp, class _Tp> 11979783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT { 1198916fecb4SLouis Dionne return __p.template __get_deleter<_Dp>(); 1199916fecb4SLouis Dionne } 1200916fecb4SLouis Dionne 1201ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_RTTI 1202916fecb4SLouis Dionne 1203916fecb4SLouis Dionne template <class _Tp> 12049783f28cSLouis Dionne class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr { 1205916fecb4SLouis Dionne public: 12064f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 17 1207065ac300SKonstantin Varlamov typedef remove_extent_t<_Tp> element_type; 1208065ac300SKonstantin Varlamov #else 1209916fecb4SLouis Dionne typedef _Tp element_type; 1210065ac300SKonstantin Varlamov #endif 1211065ac300SKonstantin Varlamov 12121ba8ed0cSNikolas Klauser // A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require 12131ba8ed0cSNikolas Klauser // any bookkeeping, so it's always trivially relocatable. 1214*f6958523SNikolas Klauser using __trivially_relocatable _LIBCPP_NODEBUG = weak_ptr; 12151ba8ed0cSNikolas Klauser 1216916fecb4SLouis Dionne private: 1217916fecb4SLouis Dionne element_type* __ptr_; 1218916fecb4SLouis Dionne __shared_weak_count* __cntrl_; 1219916fecb4SLouis Dionne 1220916fecb4SLouis Dionne public: 12219783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT; 12224da76ea7SNikolas Klauser 12234da76ea7SNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0> 12244c198542SLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr(shared_ptr<_Yp> const& __r) _NOEXCEPT; 12254da76ea7SNikolas Klauser 12269783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr const& __r) _NOEXCEPT; 12274da76ea7SNikolas Klauser 12284da76ea7SNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0> 12294c198542SLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr<_Yp> const& __r) _NOEXCEPT; 1230916fecb4SLouis Dionne 12319783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr&& __r) _NOEXCEPT; 12324da76ea7SNikolas Klauser 12334da76ea7SNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0> 12344c198542SLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr<_Yp>&& __r) _NOEXCEPT; 12354da76ea7SNikolas Klauser 123683ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI ~weak_ptr(); 1237916fecb4SLouis Dionne 12389783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT; 1239475bd19eSNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0> 12409783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT; 1241916fecb4SLouis Dionne 12429783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT; 1243475bd19eSNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0> 12449783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT; 1245916fecb4SLouis Dionne 1246475bd19eSNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0> 12479783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT; 1248916fecb4SLouis Dionne 12499783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void swap(weak_ptr& __r) _NOEXCEPT; 12509783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT; 1251916fecb4SLouis Dionne 12529783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; } 12539783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT { return __cntrl_ == nullptr || __cntrl_->use_count() == 0; } 125483ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT; 1255916fecb4SLouis Dionne template <class _Up> 12569783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT { 12579783f28cSLouis Dionne return __cntrl_ < __r.__cntrl_; 12589783f28cSLouis Dionne } 1259916fecb4SLouis Dionne template <class _Up> 12609783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT { 12619783f28cSLouis Dionne return __cntrl_ < __r.__cntrl_; 12629783f28cSLouis Dionne } 1263916fecb4SLouis Dionne 12649783f28cSLouis Dionne template <class _Up> 12659783f28cSLouis Dionne friend class _LIBCPP_TEMPLATE_VIS weak_ptr; 12669783f28cSLouis Dionne template <class _Up> 12679783f28cSLouis Dionne friend class _LIBCPP_TEMPLATE_VIS shared_ptr; 1268916fecb4SLouis Dionne }; 1269916fecb4SLouis Dionne 12704f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 17 1271916fecb4SLouis Dionne template <class _Tp> 1272916fecb4SLouis Dionne weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; 1273916fecb4SLouis Dionne #endif 1274916fecb4SLouis Dionne 1275916fecb4SLouis Dionne template <class _Tp> 12769783f28cSLouis Dionne inline _LIBCPP_CONSTEXPR weak_ptr<_Tp>::weak_ptr() _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {} 1277916fecb4SLouis Dionne 1278916fecb4SLouis Dionne template <class _Tp> 12799783f28cSLouis Dionne inline weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) { 1280916fecb4SLouis Dionne if (__cntrl_) 1281916fecb4SLouis Dionne __cntrl_->__add_weak(); 1282916fecb4SLouis Dionne } 1283916fecb4SLouis Dionne 1284916fecb4SLouis Dionne template <class _Tp> 12854da76ea7SNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> > 12869783f28cSLouis Dionne inline weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) { 1287916fecb4SLouis Dionne if (__cntrl_) 1288916fecb4SLouis Dionne __cntrl_->__add_weak(); 1289916fecb4SLouis Dionne } 1290916fecb4SLouis Dionne 1291916fecb4SLouis Dionne template <class _Tp> 12924da76ea7SNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> > 12939783f28cSLouis Dionne inline weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r) _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) { 1294b861457cSAmirreza Ashouri shared_ptr<_Yp> __s = __r.lock(); 1295b861457cSAmirreza Ashouri *this = weak_ptr<_Tp>(__s); 1296916fecb4SLouis Dionne } 1297916fecb4SLouis Dionne 1298916fecb4SLouis Dionne template <class _Tp> 12999783f28cSLouis Dionne inline weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) { 1300916fecb4SLouis Dionne __r.__ptr_ = nullptr; 1301916fecb4SLouis Dionne __r.__cntrl_ = nullptr; 1302916fecb4SLouis Dionne } 1303916fecb4SLouis Dionne 1304916fecb4SLouis Dionne template <class _Tp> 13054da76ea7SNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> > 13069783f28cSLouis Dionne inline weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r) _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) { 1307b861457cSAmirreza Ashouri shared_ptr<_Yp> __s = __r.lock(); 1308b861457cSAmirreza Ashouri *this = weak_ptr<_Tp>(__s); 1309b861457cSAmirreza Ashouri __r.reset(); 1310916fecb4SLouis Dionne } 1311916fecb4SLouis Dionne 1312916fecb4SLouis Dionne template <class _Tp> 13139783f28cSLouis Dionne weak_ptr<_Tp>::~weak_ptr() { 1314916fecb4SLouis Dionne if (__cntrl_) 1315916fecb4SLouis Dionne __cntrl_->__release_weak(); 1316916fecb4SLouis Dionne } 1317916fecb4SLouis Dionne 1318916fecb4SLouis Dionne template <class _Tp> 13199783f28cSLouis Dionne inline weak_ptr<_Tp>& weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT { 1320916fecb4SLouis Dionne weak_ptr(__r).swap(*this); 1321916fecb4SLouis Dionne return *this; 1322916fecb4SLouis Dionne } 1323916fecb4SLouis Dionne 1324916fecb4SLouis Dionne template <class _Tp> 1325475bd19eSNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> > 13269783f28cSLouis Dionne inline weak_ptr<_Tp>& weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT { 1327916fecb4SLouis Dionne weak_ptr(__r).swap(*this); 1328916fecb4SLouis Dionne return *this; 1329916fecb4SLouis Dionne } 1330916fecb4SLouis Dionne 1331916fecb4SLouis Dionne template <class _Tp> 13329783f28cSLouis Dionne inline weak_ptr<_Tp>& weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT { 133377a00c0dSLouis Dionne weak_ptr(std::move(__r)).swap(*this); 1334916fecb4SLouis Dionne return *this; 1335916fecb4SLouis Dionne } 1336916fecb4SLouis Dionne 1337916fecb4SLouis Dionne template <class _Tp> 1338475bd19eSNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> > 13399783f28cSLouis Dionne inline weak_ptr<_Tp>& weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT { 134077a00c0dSLouis Dionne weak_ptr(std::move(__r)).swap(*this); 1341916fecb4SLouis Dionne return *this; 1342916fecb4SLouis Dionne } 1343916fecb4SLouis Dionne 1344916fecb4SLouis Dionne template <class _Tp> 1345475bd19eSNikolas Klauser template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> > 13469783f28cSLouis Dionne inline weak_ptr<_Tp>& weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT { 1347916fecb4SLouis Dionne weak_ptr(__r).swap(*this); 1348916fecb4SLouis Dionne return *this; 1349916fecb4SLouis Dionne } 1350916fecb4SLouis Dionne 1351916fecb4SLouis Dionne template <class _Tp> 13529783f28cSLouis Dionne inline void weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT { 135377a00c0dSLouis Dionne std::swap(__ptr_, __r.__ptr_); 135477a00c0dSLouis Dionne std::swap(__cntrl_, __r.__cntrl_); 1355916fecb4SLouis Dionne } 1356916fecb4SLouis Dionne 1357916fecb4SLouis Dionne template <class _Tp> 13589783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI void swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT { 1359916fecb4SLouis Dionne __x.swap(__y); 1360916fecb4SLouis Dionne } 1361916fecb4SLouis Dionne 1362916fecb4SLouis Dionne template <class _Tp> 13639783f28cSLouis Dionne inline void weak_ptr<_Tp>::reset() _NOEXCEPT { 1364916fecb4SLouis Dionne weak_ptr().swap(*this); 1365916fecb4SLouis Dionne } 1366916fecb4SLouis Dionne 1367916fecb4SLouis Dionne template <class _Tp> 13689783f28cSLouis Dionne shared_ptr<_Tp> weak_ptr<_Tp>::lock() const _NOEXCEPT { 1369916fecb4SLouis Dionne shared_ptr<_Tp> __r; 1370916fecb4SLouis Dionne __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_; 1371916fecb4SLouis Dionne if (__r.__cntrl_) 1372916fecb4SLouis Dionne __r.__ptr_ = __ptr_; 1373916fecb4SLouis Dionne return __r; 1374916fecb4SLouis Dionne } 1375916fecb4SLouis Dionne 13764f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 17 13779783f28cSLouis Dionne template <class _Tp = void> 13789783f28cSLouis Dionne struct owner_less; 1379916fecb4SLouis Dionne #else 13809783f28cSLouis Dionne template <class _Tp> 13819783f28cSLouis Dionne struct owner_less; 1382916fecb4SLouis Dionne #endif 1383916fecb4SLouis Dionne 1384916fecb4SLouis Dionne template <class _Tp> 13859783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> > : __binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool> { 13869783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT { 13879783f28cSLouis Dionne return __x.owner_before(__y); 13889783f28cSLouis Dionne } 13899783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT { 13909783f28cSLouis Dionne return __x.owner_before(__y); 13919783f28cSLouis Dionne } 13929783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT { 13939783f28cSLouis Dionne return __x.owner_before(__y); 13949783f28cSLouis Dionne } 1395916fecb4SLouis Dionne }; 1396916fecb4SLouis Dionne 1397916fecb4SLouis Dionne template <class _Tp> 13989783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> > : __binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool> { 13999783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT { 14009783f28cSLouis Dionne return __x.owner_before(__y); 14019783f28cSLouis Dionne } 14029783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT { 14039783f28cSLouis Dionne return __x.owner_before(__y); 14049783f28cSLouis Dionne } 14059783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT { 14069783f28cSLouis Dionne return __x.owner_before(__y); 14079783f28cSLouis Dionne } 1408916fecb4SLouis Dionne }; 1409916fecb4SLouis Dionne 14104f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 17 1411916fecb4SLouis Dionne template <> 14129783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS owner_less<void> { 1413916fecb4SLouis Dionne template <class _Tp, class _Up> 14149783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT { 14159783f28cSLouis Dionne return __x.owner_before(__y); 14169783f28cSLouis Dionne } 1417916fecb4SLouis Dionne template <class _Tp, class _Up> 14189783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT { 14199783f28cSLouis Dionne return __x.owner_before(__y); 14209783f28cSLouis Dionne } 1421916fecb4SLouis Dionne template <class _Tp, class _Up> 14229783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT { 14239783f28cSLouis Dionne return __x.owner_before(__y); 14249783f28cSLouis Dionne } 1425916fecb4SLouis Dionne template <class _Tp, class _Up> 14269783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPT { 14279783f28cSLouis Dionne return __x.owner_before(__y); 14289783f28cSLouis Dionne } 1429916fecb4SLouis Dionne typedef void is_transparent; 1430916fecb4SLouis Dionne }; 1431916fecb4SLouis Dionne #endif 1432916fecb4SLouis Dionne 1433916fecb4SLouis Dionne template <class _Tp> 14349783f28cSLouis Dionne class _LIBCPP_TEMPLATE_VIS enable_shared_from_this { 1435916fecb4SLouis Dionne mutable weak_ptr<_Tp> __weak_this_; 14369783f28cSLouis Dionne 1437916fecb4SLouis Dionne protected: 14389783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR enable_shared_from_this() _NOEXCEPT {} 14399783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {} 14409783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT { return *this; } 14419783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI ~enable_shared_from_this() {} 14429783f28cSLouis Dionne 1443916fecb4SLouis Dionne public: 14449783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); } 14459783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const { return shared_ptr<const _Tp>(__weak_this_); } 1446916fecb4SLouis Dionne 14474f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 17 14489783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr<_Tp> weak_from_this() _NOEXCEPT { return __weak_this_; } 1449916fecb4SLouis Dionne 14509783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT { return __weak_this_; } 14514f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 17 1452916fecb4SLouis Dionne 14539783f28cSLouis Dionne template <class _Up> 14549783f28cSLouis Dionne friend class shared_ptr; 1455916fecb4SLouis Dionne }; 1456916fecb4SLouis Dionne 14579783f28cSLouis Dionne template <class _Tp> 14589783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS hash; 1459916fecb4SLouis Dionne 1460916fecb4SLouis Dionne template <class _Tp> 14619783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> > { 1462dc066888SArthur O'Dwyer #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 1463dc066888SArthur O'Dwyer _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> argument_type; 1464dc066888SArthur O'Dwyer _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 1465dc066888SArthur O'Dwyer #endif 1466916fecb4SLouis Dionne 14679783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT { 1468916fecb4SLouis Dionne return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get()); 1469916fecb4SLouis Dionne } 1470916fecb4SLouis Dionne }; 1471916fecb4SLouis Dionne 1472916fecb4SLouis Dionne template <class _CharT, class _Traits, class _Yp> 14739783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 1474916fecb4SLouis Dionne operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p); 1475916fecb4SLouis Dionne 1476c6f3b7bcSNikolas Klauser #if _LIBCPP_HAS_THREADS 1477916fecb4SLouis Dionne 14789783f28cSLouis Dionne class _LIBCPP_EXPORTED_FROM_ABI __sp_mut { 147984fc2c3cSNikolas Klauser void* __lx_; 14809783f28cSLouis Dionne 1481916fecb4SLouis Dionne public: 1482916fecb4SLouis Dionne void lock() _NOEXCEPT; 1483916fecb4SLouis Dionne void unlock() _NOEXCEPT; 1484916fecb4SLouis Dionne 1485916fecb4SLouis Dionne private: 1486916fecb4SLouis Dionne _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT; 1487916fecb4SLouis Dionne __sp_mut(const __sp_mut&); 1488916fecb4SLouis Dionne __sp_mut& operator=(const __sp_mut&); 1489916fecb4SLouis Dionne 1490f1ea0b11SNikolas Klauser friend _LIBCPP_EXPORTED_FROM_ABI __sp_mut& __get_sp_mut(const void*); 1491916fecb4SLouis Dionne }; 1492916fecb4SLouis Dionne 1493ec350ad4Sphilnik777 _LIBCPP_EXPORTED_FROM_ABI __sp_mut& __get_sp_mut(const void*); 1494916fecb4SLouis Dionne 1495916fecb4SLouis Dionne template <class _Tp> 1496716ed5fcSNico Weber inline _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const shared_ptr<_Tp>*) { 1497916fecb4SLouis Dionne return false; 1498916fecb4SLouis Dionne } 1499916fecb4SLouis Dionne 1500916fecb4SLouis Dionne template <class _Tp> 1501716ed5fcSNico Weber _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p) { 1502841399a2SNikolas Klauser __sp_mut& __m = std::__get_sp_mut(__p); 1503916fecb4SLouis Dionne __m.lock(); 1504916fecb4SLouis Dionne shared_ptr<_Tp> __q = *__p; 1505916fecb4SLouis Dionne __m.unlock(); 1506916fecb4SLouis Dionne return __q; 1507916fecb4SLouis Dionne } 1508916fecb4SLouis Dionne 1509916fecb4SLouis Dionne template <class _Tp> 1510716ed5fcSNico Weber inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order) { 1511841399a2SNikolas Klauser return std::atomic_load(__p); 1512916fecb4SLouis Dionne } 1513916fecb4SLouis Dionne 1514916fecb4SLouis Dionne template <class _Tp> 1515716ed5fcSNico Weber _LIBCPP_HIDE_FROM_ABI void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) { 1516841399a2SNikolas Klauser __sp_mut& __m = std::__get_sp_mut(__p); 1517916fecb4SLouis Dionne __m.lock(); 1518916fecb4SLouis Dionne __p->swap(__r); 1519916fecb4SLouis Dionne __m.unlock(); 1520916fecb4SLouis Dionne } 1521916fecb4SLouis Dionne 1522916fecb4SLouis Dionne template <class _Tp> 1523716ed5fcSNico Weber inline _LIBCPP_HIDE_FROM_ABI void atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) { 1524841399a2SNikolas Klauser std::atomic_store(__p, __r); 1525916fecb4SLouis Dionne } 1526916fecb4SLouis Dionne 1527916fecb4SLouis Dionne template <class _Tp> 1528716ed5fcSNico Weber _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) { 1529841399a2SNikolas Klauser __sp_mut& __m = std::__get_sp_mut(__p); 1530916fecb4SLouis Dionne __m.lock(); 1531916fecb4SLouis Dionne __p->swap(__r); 1532916fecb4SLouis Dionne __m.unlock(); 1533916fecb4SLouis Dionne return __r; 1534916fecb4SLouis Dionne } 1535916fecb4SLouis Dionne 1536916fecb4SLouis Dionne template <class _Tp> 1537716ed5fcSNico Weber inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> 15389783f28cSLouis Dionne atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) { 1539841399a2SNikolas Klauser return std::atomic_exchange(__p, __r); 1540916fecb4SLouis Dionne } 1541916fecb4SLouis Dionne 1542916fecb4SLouis Dionne template <class _Tp> 1543716ed5fcSNico Weber _LIBCPP_HIDE_FROM_ABI bool 15449783f28cSLouis Dionne atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) { 1545916fecb4SLouis Dionne shared_ptr<_Tp> __temp; 1546841399a2SNikolas Klauser __sp_mut& __m = std::__get_sp_mut(__p); 1547916fecb4SLouis Dionne __m.lock(); 15489783f28cSLouis Dionne if (__p->__owner_equivalent(*__v)) { 154977a00c0dSLouis Dionne std::swap(__temp, *__p); 1550916fecb4SLouis Dionne *__p = __w; 1551916fecb4SLouis Dionne __m.unlock(); 1552916fecb4SLouis Dionne return true; 1553916fecb4SLouis Dionne } 155477a00c0dSLouis Dionne std::swap(__temp, *__v); 1555916fecb4SLouis Dionne *__v = *__p; 1556916fecb4SLouis Dionne __m.unlock(); 1557916fecb4SLouis Dionne return false; 1558916fecb4SLouis Dionne } 1559916fecb4SLouis Dionne 1560916fecb4SLouis Dionne template <class _Tp> 1561716ed5fcSNico Weber inline _LIBCPP_HIDE_FROM_ABI bool 15629783f28cSLouis Dionne atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) { 1563841399a2SNikolas Klauser return std::atomic_compare_exchange_strong(__p, __v, __w); 1564916fecb4SLouis Dionne } 1565916fecb4SLouis Dionne 1566916fecb4SLouis Dionne template <class _Tp> 1567716ed5fcSNico Weber inline _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit( 15689783f28cSLouis Dionne shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w, memory_order, memory_order) { 1569841399a2SNikolas Klauser return std::atomic_compare_exchange_strong(__p, __v, __w); 1570916fecb4SLouis Dionne } 1571916fecb4SLouis Dionne 1572916fecb4SLouis Dionne template <class _Tp> 1573716ed5fcSNico Weber inline _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit( 15749783f28cSLouis Dionne shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w, memory_order, memory_order) { 1575841399a2SNikolas Klauser return std::atomic_compare_exchange_weak(__p, __v, __w); 1576916fecb4SLouis Dionne } 1577916fecb4SLouis Dionne 1578c6f3b7bcSNikolas Klauser #endif // _LIBCPP_HAS_THREADS 1579916fecb4SLouis Dionne 1580916fecb4SLouis Dionne _LIBCPP_END_NAMESPACE_STD 1581916fecb4SLouis Dionne 15827b462251SLouis Dionne _LIBCPP_POP_MACROS 15837b462251SLouis Dionne 1584916fecb4SLouis Dionne #endif // _LIBCPP___MEMORY_SHARED_PTR_H 1585