xref: /openbsd-src/gnu/llvm/libcxx/include/__memory/shared_ptr.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
176d0caaeSpatrick // -*- C++ -*-
276d0caaeSpatrick //===----------------------------------------------------------------------===//
376d0caaeSpatrick //
476d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
576d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
676d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
776d0caaeSpatrick //
876d0caaeSpatrick //===----------------------------------------------------------------------===//
976d0caaeSpatrick 
1076d0caaeSpatrick #ifndef _LIBCPP___MEMORY_SHARED_PTR_H
1176d0caaeSpatrick #define _LIBCPP___MEMORY_SHARED_PTR_H
1276d0caaeSpatrick 
1376d0caaeSpatrick #include <__availability>
14*4bdff4beSrobert #include <__compare/compare_three_way.h>
15*4bdff4beSrobert #include <__compare/ordering.h>
1676d0caaeSpatrick #include <__config>
1776d0caaeSpatrick #include <__functional/binary_function.h>
1876d0caaeSpatrick #include <__functional/operations.h>
1976d0caaeSpatrick #include <__functional/reference_wrapper.h>
20*4bdff4beSrobert #include <__iterator/access.h>
2176d0caaeSpatrick #include <__memory/addressof.h>
2276d0caaeSpatrick #include <__memory/allocation_guard.h>
2376d0caaeSpatrick #include <__memory/allocator.h>
24*4bdff4beSrobert #include <__memory/allocator_destructor.h>
25*4bdff4beSrobert #include <__memory/allocator_traits.h>
26*4bdff4beSrobert #include <__memory/auto_ptr.h>
2776d0caaeSpatrick #include <__memory/compressed_pair.h>
28*4bdff4beSrobert #include <__memory/construct_at.h>
2976d0caaeSpatrick #include <__memory/pointer_traits.h>
30*4bdff4beSrobert #include <__memory/uninitialized_algorithms.h>
3176d0caaeSpatrick #include <__memory/unique_ptr.h>
3276d0caaeSpatrick #include <__utility/forward.h>
33*4bdff4beSrobert #include <__utility/move.h>
34*4bdff4beSrobert #include <__utility/swap.h>
3576d0caaeSpatrick #include <cstddef>
3676d0caaeSpatrick #include <cstdlib> // abort
3776d0caaeSpatrick #include <iosfwd>
38*4bdff4beSrobert #include <new>
3976d0caaeSpatrick #include <stdexcept>
4076d0caaeSpatrick #include <typeinfo>
4176d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
4276d0caaeSpatrick #  include <atomic>
4376d0caaeSpatrick #endif
4476d0caaeSpatrick 
4576d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
4676d0caaeSpatrick #  pragma GCC system_header
4776d0caaeSpatrick #endif
4876d0caaeSpatrick 
4976d0caaeSpatrick _LIBCPP_BEGIN_NAMESPACE_STD
5076d0caaeSpatrick 
5176d0caaeSpatrick // NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
5276d0caaeSpatrick // should be sufficient for thread safety.
5376d0caaeSpatrick // See https://llvm.org/PR22803
5476d0caaeSpatrick #if defined(__clang__) && __has_builtin(__atomic_add_fetch)          \
5576d0caaeSpatrick                        && defined(__ATOMIC_RELAXED)                  \
5676d0caaeSpatrick                        && defined(__ATOMIC_ACQ_REL)
5776d0caaeSpatrick #   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
5876d0caaeSpatrick #elif defined(_LIBCPP_COMPILER_GCC)
5976d0caaeSpatrick #   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
6076d0caaeSpatrick #endif
6176d0caaeSpatrick 
6276d0caaeSpatrick template <class _ValueType>
6376d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
__libcpp_relaxed_load(_ValueType const * __value)6476d0caaeSpatrick _ValueType __libcpp_relaxed_load(_ValueType const* __value) {
6576d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_THREADS) && \
6676d0caaeSpatrick     defined(__ATOMIC_RELAXED) &&        \
6776d0caaeSpatrick     (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
6876d0caaeSpatrick     return __atomic_load_n(__value, __ATOMIC_RELAXED);
6976d0caaeSpatrick #else
7076d0caaeSpatrick     return *__value;
7176d0caaeSpatrick #endif
7276d0caaeSpatrick }
7376d0caaeSpatrick 
7476d0caaeSpatrick template <class _ValueType>
7576d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
__libcpp_acquire_load(_ValueType const * __value)7676d0caaeSpatrick _ValueType __libcpp_acquire_load(_ValueType const* __value) {
7776d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_THREADS) && \
7876d0caaeSpatrick     defined(__ATOMIC_ACQUIRE) &&        \
7976d0caaeSpatrick     (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
8076d0caaeSpatrick     return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
8176d0caaeSpatrick #else
8276d0caaeSpatrick     return *__value;
8376d0caaeSpatrick #endif
8476d0caaeSpatrick }
8576d0caaeSpatrick 
8676d0caaeSpatrick template <class _Tp>
8776d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY _Tp
__libcpp_atomic_refcount_increment(_Tp & __t)8876d0caaeSpatrick __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT
8976d0caaeSpatrick {
9076d0caaeSpatrick #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
9176d0caaeSpatrick     return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
9276d0caaeSpatrick #else
9376d0caaeSpatrick     return __t += 1;
9476d0caaeSpatrick #endif
9576d0caaeSpatrick }
9676d0caaeSpatrick 
9776d0caaeSpatrick template <class _Tp>
9876d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY _Tp
__libcpp_atomic_refcount_decrement(_Tp & __t)9976d0caaeSpatrick __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
10076d0caaeSpatrick {
10176d0caaeSpatrick #if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
10276d0caaeSpatrick     return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
10376d0caaeSpatrick #else
10476d0caaeSpatrick     return __t -= 1;
10576d0caaeSpatrick #endif
10676d0caaeSpatrick }
10776d0caaeSpatrick 
10876d0caaeSpatrick class _LIBCPP_EXCEPTION_ABI bad_weak_ptr
10976d0caaeSpatrick     : public std::exception
11076d0caaeSpatrick {
11176d0caaeSpatrick public:
11276d0caaeSpatrick     bad_weak_ptr() _NOEXCEPT = default;
11376d0caaeSpatrick     bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
114*4bdff4beSrobert     ~bad_weak_ptr() _NOEXCEPT override;
115*4bdff4beSrobert     const char* what() const  _NOEXCEPT override;
11676d0caaeSpatrick };
11776d0caaeSpatrick 
11876d0caaeSpatrick _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
__throw_bad_weak_ptr()11976d0caaeSpatrick void __throw_bad_weak_ptr()
12076d0caaeSpatrick {
12176d0caaeSpatrick #ifndef _LIBCPP_NO_EXCEPTIONS
12276d0caaeSpatrick     throw bad_weak_ptr();
12376d0caaeSpatrick #else
12476d0caaeSpatrick     _VSTD::abort();
12576d0caaeSpatrick #endif
12676d0caaeSpatrick }
12776d0caaeSpatrick 
12876d0caaeSpatrick template<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
12976d0caaeSpatrick 
13076d0caaeSpatrick class _LIBCPP_TYPE_VIS __shared_count
13176d0caaeSpatrick {
13276d0caaeSpatrick     __shared_count(const __shared_count&);
13376d0caaeSpatrick     __shared_count& operator=(const __shared_count&);
13476d0caaeSpatrick 
13576d0caaeSpatrick protected:
13676d0caaeSpatrick     long __shared_owners_;
13776d0caaeSpatrick     virtual ~__shared_count();
13876d0caaeSpatrick private:
13976d0caaeSpatrick     virtual void __on_zero_shared() _NOEXCEPT = 0;
14076d0caaeSpatrick 
14176d0caaeSpatrick public:
14276d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
14376d0caaeSpatrick     explicit __shared_count(long __refs = 0) _NOEXCEPT
__shared_owners_(__refs)14476d0caaeSpatrick         : __shared_owners_(__refs) {}
14576d0caaeSpatrick 
146*4bdff4beSrobert #if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
147*4bdff4beSrobert     void __add_shared() noexcept;
148*4bdff4beSrobert     bool __release_shared() noexcept;
14976d0caaeSpatrick #else
15076d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
__add_shared()15176d0caaeSpatrick     void __add_shared() _NOEXCEPT {
15276d0caaeSpatrick       __libcpp_atomic_refcount_increment(__shared_owners_);
15376d0caaeSpatrick     }
15476d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
__release_shared()15576d0caaeSpatrick     bool __release_shared() _NOEXCEPT {
15676d0caaeSpatrick       if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
15776d0caaeSpatrick         __on_zero_shared();
15876d0caaeSpatrick         return true;
15976d0caaeSpatrick       }
16076d0caaeSpatrick       return false;
16176d0caaeSpatrick     }
16276d0caaeSpatrick #endif
16376d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
use_count()16476d0caaeSpatrick     long use_count() const _NOEXCEPT {
16576d0caaeSpatrick         return __libcpp_relaxed_load(&__shared_owners_) + 1;
16676d0caaeSpatrick     }
16776d0caaeSpatrick };
16876d0caaeSpatrick 
16976d0caaeSpatrick class _LIBCPP_TYPE_VIS __shared_weak_count
17076d0caaeSpatrick     : private __shared_count
17176d0caaeSpatrick {
17276d0caaeSpatrick     long __shared_weak_owners_;
17376d0caaeSpatrick 
17476d0caaeSpatrick public:
17576d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
17676d0caaeSpatrick     explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
__shared_count(__refs)17776d0caaeSpatrick         : __shared_count(__refs),
17876d0caaeSpatrick           __shared_weak_owners_(__refs) {}
17976d0caaeSpatrick protected:
180*4bdff4beSrobert     ~__shared_weak_count() override;
18176d0caaeSpatrick 
18276d0caaeSpatrick public:
183*4bdff4beSrobert #if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
184*4bdff4beSrobert     void __add_shared() noexcept;
185*4bdff4beSrobert     void __add_weak() noexcept;
186*4bdff4beSrobert     void __release_shared() noexcept;
18776d0caaeSpatrick #else
18876d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
18976d0caaeSpatrick     void __add_shared() _NOEXCEPT {
19076d0caaeSpatrick       __shared_count::__add_shared();
19176d0caaeSpatrick     }
19276d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
19376d0caaeSpatrick     void __add_weak() _NOEXCEPT {
19476d0caaeSpatrick       __libcpp_atomic_refcount_increment(__shared_weak_owners_);
19576d0caaeSpatrick     }
19676d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
19776d0caaeSpatrick     void __release_shared() _NOEXCEPT {
19876d0caaeSpatrick       if (__shared_count::__release_shared())
19976d0caaeSpatrick         __release_weak();
20076d0caaeSpatrick     }
20176d0caaeSpatrick #endif
20276d0caaeSpatrick     void __release_weak() _NOEXCEPT;
20376d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
use_count()20476d0caaeSpatrick     long use_count() const _NOEXCEPT {return __shared_count::use_count();}
20576d0caaeSpatrick     __shared_weak_count* lock() _NOEXCEPT;
20676d0caaeSpatrick 
20776d0caaeSpatrick     virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
20876d0caaeSpatrick private:
20976d0caaeSpatrick     virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
21076d0caaeSpatrick };
21176d0caaeSpatrick 
21276d0caaeSpatrick template <class _Tp, class _Dp, class _Alloc>
21376d0caaeSpatrick class __shared_ptr_pointer
21476d0caaeSpatrick     : public __shared_weak_count
21576d0caaeSpatrick {
21676d0caaeSpatrick     __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
21776d0caaeSpatrick public:
21876d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
__shared_ptr_pointer(_Tp __p,_Dp __d,_Alloc __a)21976d0caaeSpatrick     __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
22076d0caaeSpatrick         :  __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
22176d0caaeSpatrick 
222*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
223*4bdff4beSrobert     const void* __get_deleter(const type_info&) const _NOEXCEPT override;
22476d0caaeSpatrick #endif
22576d0caaeSpatrick 
22676d0caaeSpatrick private:
227*4bdff4beSrobert     void __on_zero_shared() _NOEXCEPT override;
228*4bdff4beSrobert     void __on_zero_shared_weak() _NOEXCEPT override;
22976d0caaeSpatrick };
23076d0caaeSpatrick 
231*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
23276d0caaeSpatrick 
23376d0caaeSpatrick template <class _Tp, class _Dp, class _Alloc>
23476d0caaeSpatrick const void*
__get_deleter(const type_info & __t)23576d0caaeSpatrick __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
23676d0caaeSpatrick {
23776d0caaeSpatrick     return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
23876d0caaeSpatrick }
23976d0caaeSpatrick 
240*4bdff4beSrobert #endif // _LIBCPP_HAS_NO_RTTI
24176d0caaeSpatrick 
24276d0caaeSpatrick template <class _Tp, class _Dp, class _Alloc>
24376d0caaeSpatrick void
__on_zero_shared()24476d0caaeSpatrick __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT
24576d0caaeSpatrick {
24676d0caaeSpatrick     __data_.first().second()(__data_.first().first());
24776d0caaeSpatrick     __data_.first().second().~_Dp();
24876d0caaeSpatrick }
24976d0caaeSpatrick 
25076d0caaeSpatrick template <class _Tp, class _Dp, class _Alloc>
25176d0caaeSpatrick void
__on_zero_shared_weak()25276d0caaeSpatrick __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
25376d0caaeSpatrick {
25476d0caaeSpatrick     typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;
25576d0caaeSpatrick     typedef allocator_traits<_Al> _ATraits;
25676d0caaeSpatrick     typedef pointer_traits<typename _ATraits::pointer> _PTraits;
25776d0caaeSpatrick 
25876d0caaeSpatrick     _Al __a(__data_.second());
25976d0caaeSpatrick     __data_.second().~_Alloc();
26076d0caaeSpatrick     __a.deallocate(_PTraits::pointer_to(*this), 1);
26176d0caaeSpatrick }
26276d0caaeSpatrick 
263*4bdff4beSrobert // This tag is used to instantiate an allocator type. The various shared_ptr control blocks
264*4bdff4beSrobert // detect that the allocator has been instantiated for this type and perform alternative
265*4bdff4beSrobert // initialization/destruction based on that.
266*4bdff4beSrobert struct __for_overwrite_tag {};
267*4bdff4beSrobert 
26876d0caaeSpatrick template <class _Tp, class _Alloc>
26976d0caaeSpatrick struct __shared_ptr_emplace
27076d0caaeSpatrick     : __shared_weak_count
27176d0caaeSpatrick {
27276d0caaeSpatrick     template<class ..._Args>
27376d0caaeSpatrick     _LIBCPP_HIDE_FROM_ABI
__shared_ptr_emplace__shared_ptr_emplace27476d0caaeSpatrick     explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
27576d0caaeSpatrick         : __storage_(_VSTD::move(__a))
27676d0caaeSpatrick     {
277*4bdff4beSrobert #if _LIBCPP_STD_VER >= 20
278*4bdff4beSrobert         if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
279*4bdff4beSrobert             static_assert(sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");
280*4bdff4beSrobert             ::new ((void*)__get_elem()) _Tp;
281*4bdff4beSrobert         } else {
28276d0caaeSpatrick             using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
28376d0caaeSpatrick             _TpAlloc __tmp(*__get_alloc());
28476d0caaeSpatrick             allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
285*4bdff4beSrobert         }
28676d0caaeSpatrick #else
28776d0caaeSpatrick         ::new ((void*)__get_elem()) _Tp(_VSTD::forward<_Args>(__args)...);
28876d0caaeSpatrick #endif
28976d0caaeSpatrick     }
29076d0caaeSpatrick 
29176d0caaeSpatrick     _LIBCPP_HIDE_FROM_ABI
__get_alloc__shared_ptr_emplace29276d0caaeSpatrick     _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
29376d0caaeSpatrick 
29476d0caaeSpatrick     _LIBCPP_HIDE_FROM_ABI
__get_elem__shared_ptr_emplace29576d0caaeSpatrick     _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
29676d0caaeSpatrick 
29776d0caaeSpatrick private:
__on_zero_shared__shared_ptr_emplace298*4bdff4beSrobert     void __on_zero_shared() _NOEXCEPT override {
29976d0caaeSpatrick #if _LIBCPP_STD_VER > 17
300*4bdff4beSrobert         if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
301*4bdff4beSrobert             __get_elem()->~_Tp();
302*4bdff4beSrobert         } else {
30376d0caaeSpatrick             using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
30476d0caaeSpatrick             _TpAlloc __tmp(*__get_alloc());
30576d0caaeSpatrick             allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
306*4bdff4beSrobert         }
30776d0caaeSpatrick #else
30876d0caaeSpatrick         __get_elem()->~_Tp();
30976d0caaeSpatrick #endif
31076d0caaeSpatrick     }
31176d0caaeSpatrick 
__on_zero_shared_weak__shared_ptr_emplace312*4bdff4beSrobert     void __on_zero_shared_weak() _NOEXCEPT override {
31376d0caaeSpatrick         using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
31476d0caaeSpatrick         using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;
31576d0caaeSpatrick         _ControlBlockAlloc __tmp(*__get_alloc());
31676d0caaeSpatrick         __storage_.~_Storage();
31776d0caaeSpatrick         allocator_traits<_ControlBlockAlloc>::deallocate(__tmp,
31876d0caaeSpatrick             pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1);
31976d0caaeSpatrick     }
32076d0caaeSpatrick 
32176d0caaeSpatrick     // This class implements the control block for non-array shared pointers created
32276d0caaeSpatrick     // through `std::allocate_shared` and `std::make_shared`.
32376d0caaeSpatrick     //
32476d0caaeSpatrick     // In previous versions of the library, we used a compressed pair to store
32576d0caaeSpatrick     // both the _Alloc and the _Tp. This implies using EBO, which is incompatible
32676d0caaeSpatrick     // with Allocator construction for _Tp. To allow implementing P0674 in C++20,
32776d0caaeSpatrick     // we now use a properly aligned char buffer while making sure that we maintain
32876d0caaeSpatrick     // the same layout that we had when we used a compressed pair.
32976d0caaeSpatrick     using _CompressedPair = __compressed_pair<_Alloc, _Tp>;
_ALIGNAS_TYPE__shared_ptr_emplace33076d0caaeSpatrick     struct _ALIGNAS_TYPE(_CompressedPair) _Storage {
33176d0caaeSpatrick         char __blob_[sizeof(_CompressedPair)];
33276d0caaeSpatrick 
33376d0caaeSpatrick         _LIBCPP_HIDE_FROM_ABI explicit _Storage(_Alloc&& __a) {
33476d0caaeSpatrick             ::new ((void*)__get_alloc()) _Alloc(_VSTD::move(__a));
33576d0caaeSpatrick         }
33676d0caaeSpatrick         _LIBCPP_HIDE_FROM_ABI ~_Storage() {
33776d0caaeSpatrick             __get_alloc()->~_Alloc();
33876d0caaeSpatrick         }
33976d0caaeSpatrick         _Alloc* __get_alloc() _NOEXCEPT {
34076d0caaeSpatrick             _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
34176d0caaeSpatrick             typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair);
34276d0caaeSpatrick             _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first);
34376d0caaeSpatrick             return __alloc;
34476d0caaeSpatrick         }
34576d0caaeSpatrick         _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {
34676d0caaeSpatrick             _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
34776d0caaeSpatrick             typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair);
34876d0caaeSpatrick             _Tp *__elem = reinterpret_cast<_Tp*>(__second);
34976d0caaeSpatrick             return __elem;
35076d0caaeSpatrick         }
35176d0caaeSpatrick     };
35276d0caaeSpatrick 
35376d0caaeSpatrick     static_assert(_LIBCPP_ALIGNOF(_Storage) == _LIBCPP_ALIGNOF(_CompressedPair), "");
35476d0caaeSpatrick     static_assert(sizeof(_Storage) == sizeof(_CompressedPair), "");
35576d0caaeSpatrick     _Storage __storage_;
35676d0caaeSpatrick };
35776d0caaeSpatrick 
35876d0caaeSpatrick struct __shared_ptr_dummy_rebind_allocator_type;
35976d0caaeSpatrick template <>
36076d0caaeSpatrick class _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type>
36176d0caaeSpatrick {
36276d0caaeSpatrick public:
36376d0caaeSpatrick     template <class _Other>
36476d0caaeSpatrick     struct rebind
36576d0caaeSpatrick     {
36676d0caaeSpatrick         typedef allocator<_Other> other;
36776d0caaeSpatrick     };
36876d0caaeSpatrick };
36976d0caaeSpatrick 
37076d0caaeSpatrick template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
37176d0caaeSpatrick 
372*4bdff4beSrobert // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.general-6
373*4bdff4beSrobert // A pointer type Y* is said to be compatible with a pointer type T*
374*4bdff4beSrobert // when either Y* is convertible to T* or Y is U[N] and T is cv U[].
375*4bdff4beSrobert #if _LIBCPP_STD_VER >= 17
376*4bdff4beSrobert template <class _Yp, class _Tp>
377*4bdff4beSrobert struct __bounded_convertible_to_unbounded : false_type {};
378*4bdff4beSrobert 
379*4bdff4beSrobert template <class _Up, std::size_t _Np, class _Tp>
380*4bdff4beSrobert struct __bounded_convertible_to_unbounded<_Up[_Np], _Tp>
381*4bdff4beSrobert         : is_same<__remove_cv_t<_Tp>, _Up[]> {};
382*4bdff4beSrobert 
383*4bdff4beSrobert template <class _Yp, class _Tp>
38476d0caaeSpatrick struct __compatible_with
385*4bdff4beSrobert     : _Or<
386*4bdff4beSrobert         is_convertible<_Yp*, _Tp*>,
387*4bdff4beSrobert         __bounded_convertible_to_unbounded<_Yp, _Tp>
388*4bdff4beSrobert     > {};
38976d0caaeSpatrick #else
390*4bdff4beSrobert template <class _Yp, class _Tp>
391*4bdff4beSrobert struct __compatible_with
392*4bdff4beSrobert     : is_convertible<_Yp*, _Tp*> {};
393*4bdff4beSrobert #endif // _LIBCPP_STD_VER >= 17
394*4bdff4beSrobert 
395*4bdff4beSrobert // Constructors that take raw pointers have a different set of "compatible" constraints
396*4bdff4beSrobert // http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.const-9.1
397*4bdff4beSrobert // - If T is an array type, then either T is U[N] and Y(*)[N] is convertible to T*,
398*4bdff4beSrobert //   or T is U[] and Y(*)[] is convertible to T*.
399*4bdff4beSrobert // - If T is not an array type, then Y* is convertible to T*.
400*4bdff4beSrobert #if _LIBCPP_STD_VER >= 17
401*4bdff4beSrobert template <class _Yp, class _Tp, class = void>
402*4bdff4beSrobert struct __raw_pointer_compatible_with : _And<
403*4bdff4beSrobert         _Not<is_array<_Tp>>,
404*4bdff4beSrobert         is_convertible<_Yp*, _Tp*>
405*4bdff4beSrobert         > {};
406*4bdff4beSrobert 
407*4bdff4beSrobert template <class _Yp, class _Up, std::size_t _Np>
408*4bdff4beSrobert struct __raw_pointer_compatible_with<_Yp, _Up[_Np], __enable_if_t<
409*4bdff4beSrobert             is_convertible<_Yp(*)[_Np], _Up(*)[_Np]>::value> >
410*4bdff4beSrobert         : true_type {};
411*4bdff4beSrobert 
412*4bdff4beSrobert template <class _Yp, class _Up>
413*4bdff4beSrobert struct __raw_pointer_compatible_with<_Yp, _Up[], __enable_if_t<
414*4bdff4beSrobert             is_convertible<_Yp(*)[], _Up(*)[]>::value> >
415*4bdff4beSrobert         : true_type {};
416*4bdff4beSrobert 
417*4bdff4beSrobert #else
418*4bdff4beSrobert template <class _Yp, class _Tp>
419*4bdff4beSrobert struct __raw_pointer_compatible_with
420*4bdff4beSrobert     : is_convertible<_Yp*, _Tp*> {};
421*4bdff4beSrobert #endif // _LIBCPP_STD_VER >= 17
422*4bdff4beSrobert 
42376d0caaeSpatrick 
42476d0caaeSpatrick template <class _Ptr, class = void>
42576d0caaeSpatrick struct __is_deletable : false_type { };
42676d0caaeSpatrick template <class _Ptr>
427*4bdff4beSrobert struct __is_deletable<_Ptr, decltype(delete std::declval<_Ptr>())> : true_type { };
42876d0caaeSpatrick 
42976d0caaeSpatrick template <class _Ptr, class = void>
43076d0caaeSpatrick struct __is_array_deletable : false_type { };
43176d0caaeSpatrick template <class _Ptr>
432*4bdff4beSrobert struct __is_array_deletable<_Ptr, decltype(delete[] std::declval<_Ptr>())> : true_type { };
43376d0caaeSpatrick 
43476d0caaeSpatrick template <class _Dp, class _Pt,
435*4bdff4beSrobert     class = decltype(std::declval<_Dp>()(std::declval<_Pt>()))>
43676d0caaeSpatrick static true_type __well_formed_deleter_test(int);
43776d0caaeSpatrick 
43876d0caaeSpatrick template <class, class>
43976d0caaeSpatrick static false_type __well_formed_deleter_test(...);
44076d0caaeSpatrick 
44176d0caaeSpatrick template <class _Dp, class _Pt>
442*4bdff4beSrobert struct __well_formed_deleter : decltype(std::__well_formed_deleter_test<_Dp, _Pt>(0)) {};
44376d0caaeSpatrick 
444*4bdff4beSrobert template<class _Dp, class _Yp, class _Tp>
44576d0caaeSpatrick struct __shared_ptr_deleter_ctor_reqs
44676d0caaeSpatrick {
447*4bdff4beSrobert     static const bool value = __raw_pointer_compatible_with<_Yp, _Tp>::value &&
44876d0caaeSpatrick                               is_move_constructible<_Dp>::value &&
449*4bdff4beSrobert                               __well_formed_deleter<_Dp, _Yp*>::value;
45076d0caaeSpatrick };
45176d0caaeSpatrick 
45276d0caaeSpatrick #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
45376d0caaeSpatrick #  define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
45476d0caaeSpatrick #else
45576d0caaeSpatrick #  define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
45676d0caaeSpatrick #endif
45776d0caaeSpatrick 
45876d0caaeSpatrick template<class _Tp>
45976d0caaeSpatrick class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
46076d0caaeSpatrick {
46176d0caaeSpatrick public:
46276d0caaeSpatrick #if _LIBCPP_STD_VER > 14
46376d0caaeSpatrick     typedef weak_ptr<_Tp> weak_type;
46476d0caaeSpatrick     typedef remove_extent_t<_Tp> element_type;
46576d0caaeSpatrick #else
46676d0caaeSpatrick     typedef _Tp element_type;
46776d0caaeSpatrick #endif
46876d0caaeSpatrick 
46976d0caaeSpatrick private:
47076d0caaeSpatrick     element_type*      __ptr_;
47176d0caaeSpatrick     __shared_weak_count* __cntrl_;
47276d0caaeSpatrick 
47376d0caaeSpatrick public:
474*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
475*4bdff4beSrobert     _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT
476*4bdff4beSrobert         : __ptr_(nullptr),
477*4bdff4beSrobert           __cntrl_(nullptr)
478*4bdff4beSrobert     { }
47976d0caaeSpatrick 
480*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
481*4bdff4beSrobert     _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT
482*4bdff4beSrobert         : __ptr_(nullptr),
483*4bdff4beSrobert           __cntrl_(nullptr)
484*4bdff4beSrobert     { }
485*4bdff4beSrobert 
486*4bdff4beSrobert     template<class _Yp, class = __enable_if_t<
48776d0caaeSpatrick         _And<
488*4bdff4beSrobert             __raw_pointer_compatible_with<_Yp, _Tp>
48976d0caaeSpatrick             // In C++03 we get errors when trying to do SFINAE with the
49076d0caaeSpatrick             // delete operator, so we always pretend that it's deletable.
49176d0caaeSpatrick             // The same happens on GCC.
49276d0caaeSpatrick #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC)
49376d0caaeSpatrick             , _If<is_array<_Tp>::value, __is_array_deletable<_Yp*>, __is_deletable<_Yp*> >
49476d0caaeSpatrick #endif
49576d0caaeSpatrick         >::value
49676d0caaeSpatrick     > >
49776d0caaeSpatrick     explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
49876d0caaeSpatrick         unique_ptr<_Yp> __hold(__p);
49976d0caaeSpatrick         typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
50076d0caaeSpatrick         typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT> _CntrlBlk;
50176d0caaeSpatrick         __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
50276d0caaeSpatrick         __hold.release();
50376d0caaeSpatrick         __enable_weak_this(__p, __p);
50476d0caaeSpatrick     }
50576d0caaeSpatrick 
506*4bdff4beSrobert     template<class _Yp, class _Dp, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
507*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
508*4bdff4beSrobert     shared_ptr(_Yp* __p, _Dp __d)
50976d0caaeSpatrick         : __ptr_(__p)
51076d0caaeSpatrick     {
51176d0caaeSpatrick #ifndef _LIBCPP_NO_EXCEPTIONS
51276d0caaeSpatrick         try
51376d0caaeSpatrick         {
51476d0caaeSpatrick #endif // _LIBCPP_NO_EXCEPTIONS
51576d0caaeSpatrick             typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
51676d0caaeSpatrick             typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk;
51776d0caaeSpatrick #ifndef _LIBCPP_CXX03_LANG
51876d0caaeSpatrick             __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
51976d0caaeSpatrick #else
52076d0caaeSpatrick             __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
52176d0caaeSpatrick #endif // not _LIBCPP_CXX03_LANG
52276d0caaeSpatrick             __enable_weak_this(__p, __p);
52376d0caaeSpatrick #ifndef _LIBCPP_NO_EXCEPTIONS
52476d0caaeSpatrick         }
52576d0caaeSpatrick         catch (...)
52676d0caaeSpatrick         {
52776d0caaeSpatrick             __d(__p);
52876d0caaeSpatrick             throw;
52976d0caaeSpatrick         }
53076d0caaeSpatrick #endif // _LIBCPP_NO_EXCEPTIONS
53176d0caaeSpatrick     }
53276d0caaeSpatrick 
533*4bdff4beSrobert     template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
534*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
535*4bdff4beSrobert     shared_ptr(_Yp* __p, _Dp __d, _Alloc __a)
53676d0caaeSpatrick         : __ptr_(__p)
53776d0caaeSpatrick     {
53876d0caaeSpatrick #ifndef _LIBCPP_NO_EXCEPTIONS
53976d0caaeSpatrick         try
54076d0caaeSpatrick         {
54176d0caaeSpatrick #endif // _LIBCPP_NO_EXCEPTIONS
54276d0caaeSpatrick             typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
54376d0caaeSpatrick             typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
54476d0caaeSpatrick             typedef __allocator_destructor<_A2> _D2;
54576d0caaeSpatrick             _A2 __a2(__a);
54676d0caaeSpatrick             unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
54776d0caaeSpatrick             ::new ((void*)_VSTD::addressof(*__hold2.get()))
54876d0caaeSpatrick #ifndef _LIBCPP_CXX03_LANG
54976d0caaeSpatrick                 _CntrlBlk(__p, _VSTD::move(__d), __a);
55076d0caaeSpatrick #else
55176d0caaeSpatrick                 _CntrlBlk(__p, __d, __a);
55276d0caaeSpatrick #endif // not _LIBCPP_CXX03_LANG
55376d0caaeSpatrick             __cntrl_ = _VSTD::addressof(*__hold2.release());
55476d0caaeSpatrick             __enable_weak_this(__p, __p);
55576d0caaeSpatrick #ifndef _LIBCPP_NO_EXCEPTIONS
55676d0caaeSpatrick         }
55776d0caaeSpatrick         catch (...)
55876d0caaeSpatrick         {
55976d0caaeSpatrick             __d(__p);
56076d0caaeSpatrick             throw;
56176d0caaeSpatrick         }
56276d0caaeSpatrick #endif // _LIBCPP_NO_EXCEPTIONS
56376d0caaeSpatrick     }
56476d0caaeSpatrick 
565*4bdff4beSrobert     template<class _Dp>
566*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
567*4bdff4beSrobert     shared_ptr(nullptr_t __p, _Dp __d)
568*4bdff4beSrobert         : __ptr_(nullptr)
569*4bdff4beSrobert     {
570*4bdff4beSrobert #ifndef _LIBCPP_NO_EXCEPTIONS
571*4bdff4beSrobert         try
572*4bdff4beSrobert         {
573*4bdff4beSrobert #endif // _LIBCPP_NO_EXCEPTIONS
574*4bdff4beSrobert             typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
575*4bdff4beSrobert             typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk;
576*4bdff4beSrobert #ifndef _LIBCPP_CXX03_LANG
577*4bdff4beSrobert             __cntrl_ = new _CntrlBlk(__p, _VSTD::move(__d), _AllocT());
578*4bdff4beSrobert #else
579*4bdff4beSrobert             __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
580*4bdff4beSrobert #endif // not _LIBCPP_CXX03_LANG
581*4bdff4beSrobert #ifndef _LIBCPP_NO_EXCEPTIONS
582*4bdff4beSrobert         }
583*4bdff4beSrobert         catch (...)
584*4bdff4beSrobert         {
585*4bdff4beSrobert             __d(__p);
586*4bdff4beSrobert             throw;
587*4bdff4beSrobert         }
588*4bdff4beSrobert #endif // _LIBCPP_NO_EXCEPTIONS
589*4bdff4beSrobert     }
590*4bdff4beSrobert 
59176d0caaeSpatrick     template<class _Dp, class _Alloc>
592*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
593*4bdff4beSrobert     shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
59476d0caaeSpatrick         : __ptr_(nullptr)
59576d0caaeSpatrick     {
59676d0caaeSpatrick #ifndef _LIBCPP_NO_EXCEPTIONS
59776d0caaeSpatrick         try
59876d0caaeSpatrick         {
59976d0caaeSpatrick #endif // _LIBCPP_NO_EXCEPTIONS
60076d0caaeSpatrick             typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
60176d0caaeSpatrick             typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
60276d0caaeSpatrick             typedef __allocator_destructor<_A2> _D2;
60376d0caaeSpatrick             _A2 __a2(__a);
60476d0caaeSpatrick             unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
60576d0caaeSpatrick             ::new ((void*)_VSTD::addressof(*__hold2.get()))
60676d0caaeSpatrick #ifndef _LIBCPP_CXX03_LANG
60776d0caaeSpatrick                 _CntrlBlk(__p, _VSTD::move(__d), __a);
60876d0caaeSpatrick #else
60976d0caaeSpatrick                 _CntrlBlk(__p, __d, __a);
61076d0caaeSpatrick #endif // not _LIBCPP_CXX03_LANG
61176d0caaeSpatrick             __cntrl_ = _VSTD::addressof(*__hold2.release());
61276d0caaeSpatrick #ifndef _LIBCPP_NO_EXCEPTIONS
61376d0caaeSpatrick         }
61476d0caaeSpatrick         catch (...)
61576d0caaeSpatrick         {
61676d0caaeSpatrick             __d(__p);
61776d0caaeSpatrick             throw;
61876d0caaeSpatrick         }
61976d0caaeSpatrick #endif // _LIBCPP_NO_EXCEPTIONS
62076d0caaeSpatrick     }
62176d0caaeSpatrick 
62276d0caaeSpatrick     template<class _Yp>
623*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
624*4bdff4beSrobert     shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
62576d0caaeSpatrick         : __ptr_(__p),
62676d0caaeSpatrick           __cntrl_(__r.__cntrl_)
62776d0caaeSpatrick     {
62876d0caaeSpatrick         if (__cntrl_)
62976d0caaeSpatrick             __cntrl_->__add_shared();
63076d0caaeSpatrick     }
63176d0caaeSpatrick 
632*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
633*4bdff4beSrobert     shared_ptr(const shared_ptr& __r) _NOEXCEPT
63476d0caaeSpatrick         : __ptr_(__r.__ptr_),
63576d0caaeSpatrick           __cntrl_(__r.__cntrl_)
63676d0caaeSpatrick     {
63776d0caaeSpatrick         if (__cntrl_)
63876d0caaeSpatrick             __cntrl_->__add_shared();
63976d0caaeSpatrick     }
64076d0caaeSpatrick 
641*4bdff4beSrobert     template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
642*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
643*4bdff4beSrobert     shared_ptr(const shared_ptr<_Yp>& __r) _NOEXCEPT
64476d0caaeSpatrick         : __ptr_(__r.__ptr_),
64576d0caaeSpatrick           __cntrl_(__r.__cntrl_)
64676d0caaeSpatrick     {
64776d0caaeSpatrick         if (__cntrl_)
64876d0caaeSpatrick             __cntrl_->__add_shared();
64976d0caaeSpatrick     }
65076d0caaeSpatrick 
651*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
652*4bdff4beSrobert     shared_ptr(shared_ptr&& __r) _NOEXCEPT
65376d0caaeSpatrick         : __ptr_(__r.__ptr_),
65476d0caaeSpatrick           __cntrl_(__r.__cntrl_)
65576d0caaeSpatrick     {
65676d0caaeSpatrick         __r.__ptr_ = nullptr;
65776d0caaeSpatrick         __r.__cntrl_ = nullptr;
65876d0caaeSpatrick     }
65976d0caaeSpatrick 
660*4bdff4beSrobert     template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
661*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
662*4bdff4beSrobert     shared_ptr(shared_ptr<_Yp>&& __r) _NOEXCEPT
66376d0caaeSpatrick         : __ptr_(__r.__ptr_),
66476d0caaeSpatrick           __cntrl_(__r.__cntrl_)
66576d0caaeSpatrick     {
66676d0caaeSpatrick         __r.__ptr_ = nullptr;
66776d0caaeSpatrick         __r.__cntrl_ = nullptr;
66876d0caaeSpatrick     }
66976d0caaeSpatrick 
670*4bdff4beSrobert     template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
671*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
672*4bdff4beSrobert     explicit shared_ptr(const weak_ptr<_Yp>& __r)
673*4bdff4beSrobert         : __ptr_(__r.__ptr_),
674*4bdff4beSrobert           __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
675*4bdff4beSrobert     {
676*4bdff4beSrobert         if (__cntrl_ == nullptr)
677*4bdff4beSrobert             __throw_bad_weak_ptr();
678*4bdff4beSrobert     }
679*4bdff4beSrobert 
68076d0caaeSpatrick #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
681*4bdff4beSrobert     template<class _Yp, class = __enable_if_t<is_convertible<_Yp*, element_type*>::value> >
682*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
683*4bdff4beSrobert     shared_ptr(auto_ptr<_Yp>&& __r)
68476d0caaeSpatrick         : __ptr_(__r.get())
68576d0caaeSpatrick     {
68676d0caaeSpatrick         typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
68776d0caaeSpatrick         __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
68876d0caaeSpatrick         __enable_weak_this(__r.get(), __r.get());
68976d0caaeSpatrick         __r.release();
69076d0caaeSpatrick     }
69176d0caaeSpatrick #endif
69276d0caaeSpatrick 
693*4bdff4beSrobert     template <class _Yp, class _Dp, class = __enable_if_t<
69476d0caaeSpatrick         !is_lvalue_reference<_Dp>::value &&
695*4bdff4beSrobert          __compatible_with<_Yp, _Tp>::value &&
696*4bdff4beSrobert          is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
697*4bdff4beSrobert     > >
698*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
699*4bdff4beSrobert     shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
70076d0caaeSpatrick         : __ptr_(__r.get())
70176d0caaeSpatrick     {
70276d0caaeSpatrick #if _LIBCPP_STD_VER > 11
70376d0caaeSpatrick         if (__ptr_ == nullptr)
70476d0caaeSpatrick             __cntrl_ = nullptr;
70576d0caaeSpatrick         else
70676d0caaeSpatrick #endif
70776d0caaeSpatrick         {
70876d0caaeSpatrick             typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
70976d0caaeSpatrick             typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT> _CntrlBlk;
710*4bdff4beSrobert             __cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT());
71176d0caaeSpatrick             __enable_weak_this(__r.get(), __r.get());
71276d0caaeSpatrick         }
71376d0caaeSpatrick         __r.release();
71476d0caaeSpatrick     }
71576d0caaeSpatrick 
716*4bdff4beSrobert     template <class _Yp, class _Dp, class = void, class = __enable_if_t<
71776d0caaeSpatrick         is_lvalue_reference<_Dp>::value &&
718*4bdff4beSrobert          __compatible_with<_Yp, _Tp>::value &&
719*4bdff4beSrobert         is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value
720*4bdff4beSrobert     > >
721*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
722*4bdff4beSrobert     shared_ptr(unique_ptr<_Yp, _Dp>&& __r)
72376d0caaeSpatrick         : __ptr_(__r.get())
72476d0caaeSpatrick     {
72576d0caaeSpatrick #if _LIBCPP_STD_VER > 11
72676d0caaeSpatrick         if (__ptr_ == nullptr)
72776d0caaeSpatrick             __cntrl_ = nullptr;
72876d0caaeSpatrick         else
72976d0caaeSpatrick #endif
73076d0caaeSpatrick         {
73176d0caaeSpatrick             typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
73276d0caaeSpatrick             typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer,
733*4bdff4beSrobert                                         reference_wrapper<__libcpp_remove_reference_t<_Dp> >,
73476d0caaeSpatrick                                         _AllocT> _CntrlBlk;
73576d0caaeSpatrick             __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
73676d0caaeSpatrick             __enable_weak_this(__r.get(), __r.get());
73776d0caaeSpatrick         }
73876d0caaeSpatrick         __r.release();
73976d0caaeSpatrick     }
74076d0caaeSpatrick 
741*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
742*4bdff4beSrobert     ~shared_ptr()
74376d0caaeSpatrick     {
74476d0caaeSpatrick         if (__cntrl_)
74576d0caaeSpatrick             __cntrl_->__release_shared();
74676d0caaeSpatrick     }
74776d0caaeSpatrick 
748*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
749*4bdff4beSrobert     shared_ptr<_Tp>& operator=(const shared_ptr& __r) _NOEXCEPT
75076d0caaeSpatrick     {
75176d0caaeSpatrick         shared_ptr(__r).swap(*this);
75276d0caaeSpatrick         return *this;
75376d0caaeSpatrick     }
75476d0caaeSpatrick 
755*4bdff4beSrobert     template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
756*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
757*4bdff4beSrobert     shared_ptr<_Tp>& operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
75876d0caaeSpatrick     {
75976d0caaeSpatrick         shared_ptr(__r).swap(*this);
76076d0caaeSpatrick         return *this;
76176d0caaeSpatrick     }
76276d0caaeSpatrick 
763*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
764*4bdff4beSrobert     shared_ptr<_Tp>& operator=(shared_ptr&& __r) _NOEXCEPT
76576d0caaeSpatrick     {
76676d0caaeSpatrick         shared_ptr(_VSTD::move(__r)).swap(*this);
76776d0caaeSpatrick         return *this;
76876d0caaeSpatrick     }
76976d0caaeSpatrick 
770*4bdff4beSrobert     template<class _Yp, class = __enable_if_t<__compatible_with<_Yp, _Tp>::value> >
771*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
772*4bdff4beSrobert     shared_ptr<_Tp>& operator=(shared_ptr<_Yp>&& __r)
77376d0caaeSpatrick     {
77476d0caaeSpatrick         shared_ptr(_VSTD::move(__r)).swap(*this);
77576d0caaeSpatrick         return *this;
77676d0caaeSpatrick     }
77776d0caaeSpatrick 
77876d0caaeSpatrick #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
779*4bdff4beSrobert     template<class _Yp, class = __enable_if_t<
78076d0caaeSpatrick         !is_array<_Yp>::value &&
781*4bdff4beSrobert         is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value
782*4bdff4beSrobert     > >
783*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
784*4bdff4beSrobert     shared_ptr<_Tp>& operator=(auto_ptr<_Yp>&& __r)
78576d0caaeSpatrick     {
78676d0caaeSpatrick         shared_ptr(_VSTD::move(__r)).swap(*this);
78776d0caaeSpatrick         return *this;
78876d0caaeSpatrick     }
78976d0caaeSpatrick #endif
79076d0caaeSpatrick 
791*4bdff4beSrobert     template <class _Yp, class _Dp, class = __enable_if_t<_And<
792*4bdff4beSrobert         __compatible_with<_Yp, _Tp>,
793*4bdff4beSrobert         is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>
794*4bdff4beSrobert     >::value> >
795*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
796*4bdff4beSrobert     shared_ptr<_Tp>& operator=(unique_ptr<_Yp, _Dp>&& __r)
79776d0caaeSpatrick     {
79876d0caaeSpatrick         shared_ptr(_VSTD::move(__r)).swap(*this);
79976d0caaeSpatrick         return *this;
80076d0caaeSpatrick     }
80176d0caaeSpatrick 
802*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
803*4bdff4beSrobert     void swap(shared_ptr& __r) _NOEXCEPT
80476d0caaeSpatrick     {
80576d0caaeSpatrick         _VSTD::swap(__ptr_, __r.__ptr_);
80676d0caaeSpatrick         _VSTD::swap(__cntrl_, __r.__cntrl_);
80776d0caaeSpatrick     }
80876d0caaeSpatrick 
809*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
810*4bdff4beSrobert     void reset() _NOEXCEPT
81176d0caaeSpatrick     {
81276d0caaeSpatrick         shared_ptr().swap(*this);
81376d0caaeSpatrick     }
81476d0caaeSpatrick 
815*4bdff4beSrobert     template<class _Yp, class = __enable_if_t<
816*4bdff4beSrobert         __raw_pointer_compatible_with<_Yp, _Tp>::value
817*4bdff4beSrobert     > >
818*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
819*4bdff4beSrobert     void reset(_Yp* __p)
82076d0caaeSpatrick     {
82176d0caaeSpatrick         shared_ptr(__p).swap(*this);
82276d0caaeSpatrick     }
82376d0caaeSpatrick 
824*4bdff4beSrobert     template<class _Yp, class _Dp, class = __enable_if_t<
825*4bdff4beSrobert         __shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
826*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
827*4bdff4beSrobert     void reset(_Yp* __p, _Dp __d)
82876d0caaeSpatrick     {
82976d0caaeSpatrick         shared_ptr(__p, __d).swap(*this);
83076d0caaeSpatrick     }
83176d0caaeSpatrick 
832*4bdff4beSrobert     template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<
833*4bdff4beSrobert         __shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> >
834*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
835*4bdff4beSrobert     void reset(_Yp* __p, _Dp __d, _Alloc __a)
83676d0caaeSpatrick     {
83776d0caaeSpatrick         shared_ptr(__p, __d, __a).swap(*this);
83876d0caaeSpatrick     }
83976d0caaeSpatrick 
840*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
841*4bdff4beSrobert     element_type* get() const _NOEXCEPT
842*4bdff4beSrobert     {
843*4bdff4beSrobert         return __ptr_;
844*4bdff4beSrobert     }
845*4bdff4beSrobert 
846*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
847*4bdff4beSrobert     __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT
848*4bdff4beSrobert     {
849*4bdff4beSrobert         return *__ptr_;
850*4bdff4beSrobert     }
851*4bdff4beSrobert 
852*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
853*4bdff4beSrobert     element_type* operator->() const _NOEXCEPT
854*4bdff4beSrobert     {
855*4bdff4beSrobert         static_assert(!is_array<_Tp>::value,
856*4bdff4beSrobert                       "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
857*4bdff4beSrobert         return __ptr_;
858*4bdff4beSrobert     }
859*4bdff4beSrobert 
860*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
861*4bdff4beSrobert     long use_count() const _NOEXCEPT
862*4bdff4beSrobert     {
863*4bdff4beSrobert         return __cntrl_ ? __cntrl_->use_count() : 0;
864*4bdff4beSrobert     }
865*4bdff4beSrobert 
866*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
867*4bdff4beSrobert     bool unique() const _NOEXCEPT
868*4bdff4beSrobert     {
869*4bdff4beSrobert         return use_count() == 1;
870*4bdff4beSrobert     }
871*4bdff4beSrobert 
872*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
873*4bdff4beSrobert     explicit operator bool() const _NOEXCEPT
874*4bdff4beSrobert     {
875*4bdff4beSrobert         return get() != nullptr;
876*4bdff4beSrobert     }
877*4bdff4beSrobert 
878*4bdff4beSrobert     template <class _Up>
879*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
880*4bdff4beSrobert     bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT
881*4bdff4beSrobert     {
882*4bdff4beSrobert         return __cntrl_ < __p.__cntrl_;
883*4bdff4beSrobert     }
884*4bdff4beSrobert 
885*4bdff4beSrobert     template <class _Up>
886*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
887*4bdff4beSrobert     bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT
888*4bdff4beSrobert     {
889*4bdff4beSrobert         return __cntrl_ < __p.__cntrl_;
890*4bdff4beSrobert     }
891*4bdff4beSrobert 
892*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
893*4bdff4beSrobert     bool __owner_equivalent(const shared_ptr& __p) const
894*4bdff4beSrobert     {
895*4bdff4beSrobert         return __cntrl_ == __p.__cntrl_;
896*4bdff4beSrobert     }
897*4bdff4beSrobert 
898*4bdff4beSrobert #if _LIBCPP_STD_VER > 14
899*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
900*4bdff4beSrobert     __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const
901*4bdff4beSrobert     {
902*4bdff4beSrobert             static_assert(is_array<_Tp>::value,
903*4bdff4beSrobert                           "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
904*4bdff4beSrobert             return __ptr_[__i];
905*4bdff4beSrobert     }
906*4bdff4beSrobert #endif
907*4bdff4beSrobert 
908*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
909*4bdff4beSrobert     template <class _Dp>
910*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
911*4bdff4beSrobert     _Dp* __get_deleter() const _NOEXCEPT
912*4bdff4beSrobert     {
913*4bdff4beSrobert         return static_cast<_Dp*>(__cntrl_
914*4bdff4beSrobert                     ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
915*4bdff4beSrobert                       : nullptr);
916*4bdff4beSrobert     }
917*4bdff4beSrobert #endif // _LIBCPP_HAS_NO_RTTI
918*4bdff4beSrobert 
919*4bdff4beSrobert     template<class _Yp, class _CntrlBlk>
920*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
921*4bdff4beSrobert     static shared_ptr<_Tp> __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT
922*4bdff4beSrobert     {
923*4bdff4beSrobert         shared_ptr<_Tp> __r;
924*4bdff4beSrobert         __r.__ptr_ = __p;
925*4bdff4beSrobert         __r.__cntrl_ = __cntrl;
926*4bdff4beSrobert         __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
927*4bdff4beSrobert         return __r;
928*4bdff4beSrobert     }
929*4bdff4beSrobert 
930*4bdff4beSrobert private:
931*4bdff4beSrobert     template <class _Yp, bool = is_function<_Yp>::value>
932*4bdff4beSrobert     struct __shared_ptr_default_allocator
933*4bdff4beSrobert     {
934*4bdff4beSrobert         typedef allocator<_Yp> type;
935*4bdff4beSrobert     };
936*4bdff4beSrobert 
937*4bdff4beSrobert     template <class _Yp>
938*4bdff4beSrobert     struct __shared_ptr_default_allocator<_Yp, true>
939*4bdff4beSrobert     {
940*4bdff4beSrobert         typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
941*4bdff4beSrobert     };
942*4bdff4beSrobert 
943*4bdff4beSrobert     template <class _Yp, class _OrigPtr, class = __enable_if_t<
944*4bdff4beSrobert         is_convertible<_OrigPtr*, const enable_shared_from_this<_Yp>*>::value
945*4bdff4beSrobert     > >
946*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
947*4bdff4beSrobert     void __enable_weak_this(const enable_shared_from_this<_Yp>* __e, _OrigPtr* __ptr) _NOEXCEPT
948*4bdff4beSrobert     {
949*4bdff4beSrobert         typedef __remove_cv_t<_Yp> _RawYp;
950*4bdff4beSrobert         if (__e && __e->__weak_this_.expired())
951*4bdff4beSrobert         {
952*4bdff4beSrobert             __e->__weak_this_ = shared_ptr<_RawYp>(*this,
953*4bdff4beSrobert                 const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
954*4bdff4beSrobert         }
955*4bdff4beSrobert     }
956*4bdff4beSrobert 
957*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI void __enable_weak_this(...) _NOEXCEPT { }
958*4bdff4beSrobert 
959*4bdff4beSrobert     template <class, class _Yp>
960*4bdff4beSrobert     struct __shared_ptr_default_delete
961*4bdff4beSrobert         : default_delete<_Yp>
962*4bdff4beSrobert     { };
963*4bdff4beSrobert 
964*4bdff4beSrobert     template <class _Yp, class _Un, size_t _Sz>
965*4bdff4beSrobert     struct __shared_ptr_default_delete<_Yp[_Sz], _Un>
966*4bdff4beSrobert         : default_delete<_Yp[]>
967*4bdff4beSrobert     { };
968*4bdff4beSrobert 
969*4bdff4beSrobert     template <class _Yp, class _Un>
970*4bdff4beSrobert     struct __shared_ptr_default_delete<_Yp[], _Un>
971*4bdff4beSrobert         : default_delete<_Yp[]>
972*4bdff4beSrobert     { };
973*4bdff4beSrobert 
974*4bdff4beSrobert     template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
975*4bdff4beSrobert     template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
976*4bdff4beSrobert };
977*4bdff4beSrobert 
978*4bdff4beSrobert #if _LIBCPP_STD_VER > 14
979*4bdff4beSrobert template<class _Tp>
980*4bdff4beSrobert shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
981*4bdff4beSrobert template<class _Tp, class _Dp>
982*4bdff4beSrobert shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
983*4bdff4beSrobert #endif
984*4bdff4beSrobert 
98576d0caaeSpatrick //
98676d0caaeSpatrick // std::allocate_shared and std::make_shared
98776d0caaeSpatrick //
988*4bdff4beSrobert template<class _Tp, class _Alloc, class ..._Args, class = __enable_if_t<!is_array<_Tp>::value> >
98976d0caaeSpatrick _LIBCPP_HIDE_FROM_ABI
99076d0caaeSpatrick shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args)
99176d0caaeSpatrick {
99276d0caaeSpatrick     using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
99376d0caaeSpatrick     using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
99476d0caaeSpatrick     __allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
99576d0caaeSpatrick     ::new ((void*)_VSTD::addressof(*__guard.__get())) _ControlBlock(__a, _VSTD::forward<_Args>(__args)...);
99676d0caaeSpatrick     auto __control_block = __guard.__release_ptr();
99776d0caaeSpatrick     return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block));
99876d0caaeSpatrick }
99976d0caaeSpatrick 
1000*4bdff4beSrobert template<class _Tp, class ..._Args, class = __enable_if_t<!is_array<_Tp>::value> >
100176d0caaeSpatrick _LIBCPP_HIDE_FROM_ABI
100276d0caaeSpatrick shared_ptr<_Tp> make_shared(_Args&& ...__args)
100376d0caaeSpatrick {
100476d0caaeSpatrick     return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
100576d0caaeSpatrick }
100676d0caaeSpatrick 
1007*4bdff4beSrobert #if _LIBCPP_STD_VER >= 20
1008*4bdff4beSrobert 
1009*4bdff4beSrobert template<class _Tp, class _Alloc, __enable_if_t<!is_array<_Tp>::value, int> = 0>
1010*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1011*4bdff4beSrobert shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a)
1012*4bdff4beSrobert {
1013*4bdff4beSrobert     using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
1014*4bdff4beSrobert     _ForOverwriteAllocator __alloc(__a);
1015*4bdff4beSrobert     return std::allocate_shared<_Tp>(__alloc);
1016*4bdff4beSrobert }
1017*4bdff4beSrobert 
1018*4bdff4beSrobert template<class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
1019*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1020*4bdff4beSrobert shared_ptr<_Tp> make_shared_for_overwrite()
1021*4bdff4beSrobert {
1022*4bdff4beSrobert     return std::allocate_shared_for_overwrite<_Tp>(allocator<_Tp>());
1023*4bdff4beSrobert }
1024*4bdff4beSrobert 
1025*4bdff4beSrobert #endif // _LIBCPP_STD_VER >= 20
1026*4bdff4beSrobert 
1027*4bdff4beSrobert #if _LIBCPP_STD_VER > 14
1028*4bdff4beSrobert 
1029*4bdff4beSrobert template <size_t _Alignment>
1030*4bdff4beSrobert struct __sp_aligned_storage {
1031*4bdff4beSrobert     alignas(_Alignment) char __storage[_Alignment];
1032*4bdff4beSrobert };
1033*4bdff4beSrobert 
1034*4bdff4beSrobert template <class _Tp, class _Alloc>
1035*4bdff4beSrobert struct __unbounded_array_control_block;
1036*4bdff4beSrobert 
1037*4bdff4beSrobert template <class _Tp, class _Alloc>
1038*4bdff4beSrobert struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count
1039*4bdff4beSrobert {
1040*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI constexpr
1041*4bdff4beSrobert     _Tp* __get_data() noexcept { return __data_; }
1042*4bdff4beSrobert 
1043*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
1044*4bdff4beSrobert     explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count, _Tp const& __arg)
1045*4bdff4beSrobert         : __alloc_(__alloc), __count_(__count)
1046*4bdff4beSrobert     {
1047*4bdff4beSrobert         std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::begin(__data_), __count_, __arg);
1048*4bdff4beSrobert     }
1049*4bdff4beSrobert 
1050*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
1051*4bdff4beSrobert     explicit __unbounded_array_control_block(_Alloc const& __alloc, size_t __count)
1052*4bdff4beSrobert         : __alloc_(__alloc), __count_(__count)
1053*4bdff4beSrobert     {
1054*4bdff4beSrobert #if _LIBCPP_STD_VER >= 20
1055*4bdff4beSrobert         if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
1056*4bdff4beSrobert             // We are purposefully not using an allocator-aware default construction because the spec says so.
1057*4bdff4beSrobert             // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
1058*4bdff4beSrobert             std::uninitialized_default_construct_n(std::begin(__data_), __count_);
1059*4bdff4beSrobert         } else {
1060*4bdff4beSrobert             std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_);
1061*4bdff4beSrobert         }
1062*4bdff4beSrobert #else
1063*4bdff4beSrobert         std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::begin(__data_), __count_);
1064*4bdff4beSrobert #endif
1065*4bdff4beSrobert     }
1066*4bdff4beSrobert 
1067*4bdff4beSrobert     // Returns the number of bytes required to store a control block followed by the given number
1068*4bdff4beSrobert     // of elements of _Tp, with the whole storage being aligned to a multiple of _Tp's alignment.
1069*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
1070*4bdff4beSrobert     static constexpr size_t __bytes_for(size_t __elements) {
1071*4bdff4beSrobert         // When there's 0 elements, the control block alone is enough since it holds one element.
1072*4bdff4beSrobert         // Otherwise, we allocate one fewer element than requested because the control block already
1073*4bdff4beSrobert         // holds one. Also, we use the bitwise formula below to ensure that we allocate enough bytes
1074*4bdff4beSrobert         // for the whole allocation to be a multiple of _Tp's alignment. That formula is taken from [1].
1075*4bdff4beSrobert         //
1076*4bdff4beSrobert         // [1]: https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding
1077*4bdff4beSrobert         size_t __bytes = __elements == 0 ? sizeof(__unbounded_array_control_block)
1078*4bdff4beSrobert                                          : (__elements - 1) * sizeof(_Tp) + sizeof(__unbounded_array_control_block);
1079*4bdff4beSrobert         constexpr size_t __align = alignof(_Tp);
1080*4bdff4beSrobert         return (__bytes + __align - 1) & ~(__align - 1);
1081*4bdff4beSrobert     }
1082*4bdff4beSrobert 
1083*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI_VIRTUAL
1084*4bdff4beSrobert     ~__unbounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
1085*4bdff4beSrobert 
1086*4bdff4beSrobert private:
1087*4bdff4beSrobert     void __on_zero_shared() _NOEXCEPT override {
1088*4bdff4beSrobert #if _LIBCPP_STD_VER >= 20
1089*4bdff4beSrobert         if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
1090*4bdff4beSrobert             std::__reverse_destroy(__data_, __data_ + __count_);
1091*4bdff4beSrobert         } else {
1092*4bdff4beSrobert             __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
1093*4bdff4beSrobert             std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_);
1094*4bdff4beSrobert         }
1095*4bdff4beSrobert #else
1096*4bdff4beSrobert         __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
1097*4bdff4beSrobert         std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + __count_);
1098*4bdff4beSrobert #endif
1099*4bdff4beSrobert     }
1100*4bdff4beSrobert 
1101*4bdff4beSrobert     void __on_zero_shared_weak() _NOEXCEPT override {
1102*4bdff4beSrobert         using _AlignedStorage = __sp_aligned_storage<alignof(__unbounded_array_control_block)>;
1103*4bdff4beSrobert         using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>;
1104*4bdff4beSrobert         using _PointerTraits = pointer_traits<typename allocator_traits<_StorageAlloc>::pointer>;
1105*4bdff4beSrobert 
1106*4bdff4beSrobert         _StorageAlloc __tmp(__alloc_);
1107*4bdff4beSrobert         __alloc_.~_Alloc();
1108*4bdff4beSrobert         size_t __size = __unbounded_array_control_block::__bytes_for(__count_);
1109*4bdff4beSrobert         _AlignedStorage* __storage = reinterpret_cast<_AlignedStorage*>(this);
1110*4bdff4beSrobert         allocator_traits<_StorageAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*__storage), __size);
1111*4bdff4beSrobert     }
1112*4bdff4beSrobert 
1113*4bdff4beSrobert     _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
1114*4bdff4beSrobert     size_t __count_;
1115*4bdff4beSrobert     union {
1116*4bdff4beSrobert         _Tp __data_[1];
1117*4bdff4beSrobert     };
1118*4bdff4beSrobert };
1119*4bdff4beSrobert 
1120*4bdff4beSrobert template<class _Array, class _Alloc, class... _Arg>
1121*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1122*4bdff4beSrobert shared_ptr<_Array> __allocate_shared_unbounded_array(const _Alloc& __a, size_t __n, _Arg&& ...__arg)
1123*4bdff4beSrobert {
1124*4bdff4beSrobert     static_assert(__libcpp_is_unbounded_array<_Array>::value);
1125*4bdff4beSrobert     // We compute the number of bytes necessary to hold the control block and the
1126*4bdff4beSrobert     // array elements. Then, we allocate an array of properly-aligned dummy structs
1127*4bdff4beSrobert     // large enough to hold the control block and array. This allows shifting the
1128*4bdff4beSrobert     // burden of aligning memory properly from us to the allocator.
1129*4bdff4beSrobert     using _ControlBlock = __unbounded_array_control_block<_Array, _Alloc>;
1130*4bdff4beSrobert     using _AlignedStorage = __sp_aligned_storage<alignof(_ControlBlock)>;
1131*4bdff4beSrobert     using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>;
1132*4bdff4beSrobert     __allocation_guard<_StorageAlloc> __guard(__a, _ControlBlock::__bytes_for(__n) / sizeof(_AlignedStorage));
1133*4bdff4beSrobert     _ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get()));
1134*4bdff4beSrobert     std::__construct_at(__control_block, __a, __n, std::forward<_Arg>(__arg)...);
1135*4bdff4beSrobert     __guard.__release_ptr();
1136*4bdff4beSrobert     return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
1137*4bdff4beSrobert }
1138*4bdff4beSrobert 
1139*4bdff4beSrobert template <class _Tp, class _Alloc>
1140*4bdff4beSrobert struct __bounded_array_control_block;
1141*4bdff4beSrobert 
1142*4bdff4beSrobert template <class _Tp, size_t _Count, class _Alloc>
1143*4bdff4beSrobert struct __bounded_array_control_block<_Tp[_Count], _Alloc>
1144*4bdff4beSrobert     : __shared_weak_count
1145*4bdff4beSrobert {
1146*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI constexpr
1147*4bdff4beSrobert     _Tp* __get_data() noexcept { return __data_; }
1148*4bdff4beSrobert 
1149*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
1150*4bdff4beSrobert     explicit __bounded_array_control_block(_Alloc const& __alloc, _Tp const& __arg) : __alloc_(__alloc) {
1151*4bdff4beSrobert         std::__uninitialized_allocator_fill_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count, __arg);
1152*4bdff4beSrobert     }
1153*4bdff4beSrobert 
1154*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI
1155*4bdff4beSrobert     explicit __bounded_array_control_block(_Alloc const& __alloc) : __alloc_(__alloc) {
1156*4bdff4beSrobert #if _LIBCPP_STD_VER >= 20
1157*4bdff4beSrobert         if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
1158*4bdff4beSrobert             // We are purposefully not using an allocator-aware default construction because the spec says so.
1159*4bdff4beSrobert             // There's currently no way of expressing default initialization in an allocator-aware manner anyway.
1160*4bdff4beSrobert             std::uninitialized_default_construct_n(std::addressof(__data_[0]), _Count);
1161*4bdff4beSrobert         } else {
1162*4bdff4beSrobert             std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count);
1163*4bdff4beSrobert         }
1164*4bdff4beSrobert #else
1165*4bdff4beSrobert         std::__uninitialized_allocator_value_construct_n_multidimensional(__alloc_, std::addressof(__data_[0]), _Count);
1166*4bdff4beSrobert #endif
1167*4bdff4beSrobert     }
1168*4bdff4beSrobert 
1169*4bdff4beSrobert     _LIBCPP_HIDE_FROM_ABI_VIRTUAL
1170*4bdff4beSrobert     ~__bounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_
1171*4bdff4beSrobert 
1172*4bdff4beSrobert private:
1173*4bdff4beSrobert     void __on_zero_shared() _NOEXCEPT override {
1174*4bdff4beSrobert #if _LIBCPP_STD_VER >= 20
1175*4bdff4beSrobert         if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) {
1176*4bdff4beSrobert             std::__reverse_destroy(__data_, __data_ + _Count);
1177*4bdff4beSrobert         } else {
1178*4bdff4beSrobert             __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
1179*4bdff4beSrobert             std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count);
1180*4bdff4beSrobert         }
1181*4bdff4beSrobert #else
1182*4bdff4beSrobert         __allocator_traits_rebind_t<_Alloc, _Tp> __value_alloc(__alloc_);
1183*4bdff4beSrobert         std::__allocator_destroy_multidimensional(__value_alloc, __data_, __data_ + _Count);
1184*4bdff4beSrobert #endif
1185*4bdff4beSrobert     }
1186*4bdff4beSrobert 
1187*4bdff4beSrobert     void __on_zero_shared_weak() _NOEXCEPT override {
1188*4bdff4beSrobert         using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, __bounded_array_control_block>;
1189*4bdff4beSrobert         using _PointerTraits = pointer_traits<typename allocator_traits<_ControlBlockAlloc>::pointer>;
1190*4bdff4beSrobert 
1191*4bdff4beSrobert         _ControlBlockAlloc __tmp(__alloc_);
1192*4bdff4beSrobert         __alloc_.~_Alloc();
1193*4bdff4beSrobert         allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*this), sizeof(*this));
1194*4bdff4beSrobert     }
1195*4bdff4beSrobert 
1196*4bdff4beSrobert     _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_;
1197*4bdff4beSrobert     union {
1198*4bdff4beSrobert         _Tp __data_[_Count];
1199*4bdff4beSrobert     };
1200*4bdff4beSrobert };
1201*4bdff4beSrobert 
1202*4bdff4beSrobert template<class _Array, class _Alloc, class... _Arg>
1203*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1204*4bdff4beSrobert shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&& ...__arg)
1205*4bdff4beSrobert {
1206*4bdff4beSrobert     static_assert(__libcpp_is_bounded_array<_Array>::value);
1207*4bdff4beSrobert     using _ControlBlock = __bounded_array_control_block<_Array, _Alloc>;
1208*4bdff4beSrobert     using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, _ControlBlock>;
1209*4bdff4beSrobert 
1210*4bdff4beSrobert     __allocation_guard<_ControlBlockAlloc> __guard(__a, 1);
1211*4bdff4beSrobert     _ControlBlock* __control_block = reinterpret_cast<_ControlBlock*>(std::addressof(*__guard.__get()));
1212*4bdff4beSrobert     std::__construct_at(__control_block, __a, std::forward<_Arg>(__arg)...);
1213*4bdff4beSrobert     __guard.__release_ptr();
1214*4bdff4beSrobert     return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block);
1215*4bdff4beSrobert }
1216*4bdff4beSrobert 
1217*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 14
1218*4bdff4beSrobert 
1219*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
1220*4bdff4beSrobert 
1221*4bdff4beSrobert // bounded array variants
1222*4bdff4beSrobert template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1223*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1224*4bdff4beSrobert shared_ptr<_Tp> allocate_shared(const _Alloc& __a)
1225*4bdff4beSrobert {
1226*4bdff4beSrobert     return std::__allocate_shared_bounded_array<_Tp>(__a);
1227*4bdff4beSrobert }
1228*4bdff4beSrobert 
1229*4bdff4beSrobert template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1230*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1231*4bdff4beSrobert shared_ptr<_Tp> allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u)
1232*4bdff4beSrobert {
1233*4bdff4beSrobert     return std::__allocate_shared_bounded_array<_Tp>(__a, __u);
1234*4bdff4beSrobert }
1235*4bdff4beSrobert 
1236*4bdff4beSrobert template<class _Tp, class _Alloc, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
1237*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1238*4bdff4beSrobert shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a)
1239*4bdff4beSrobert {
1240*4bdff4beSrobert     using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
1241*4bdff4beSrobert     _ForOverwriteAllocator __alloc(__a);
1242*4bdff4beSrobert     return std::__allocate_shared_bounded_array<_Tp>(__alloc);
1243*4bdff4beSrobert }
1244*4bdff4beSrobert 
1245*4bdff4beSrobert template<class _Tp, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1246*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1247*4bdff4beSrobert shared_ptr<_Tp> make_shared()
1248*4bdff4beSrobert {
1249*4bdff4beSrobert     return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>());
1250*4bdff4beSrobert }
1251*4bdff4beSrobert 
1252*4bdff4beSrobert template<class _Tp, class = __enable_if_t<is_bounded_array<_Tp>::value>>
1253*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1254*4bdff4beSrobert shared_ptr<_Tp> make_shared(const remove_extent_t<_Tp>& __u)
1255*4bdff4beSrobert {
1256*4bdff4beSrobert     return std::__allocate_shared_bounded_array<_Tp>(allocator<_Tp>(), __u);
1257*4bdff4beSrobert }
1258*4bdff4beSrobert 
1259*4bdff4beSrobert template<class _Tp, __enable_if_t<is_bounded_array<_Tp>::value, int> = 0>
1260*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1261*4bdff4beSrobert shared_ptr<_Tp> make_shared_for_overwrite()
1262*4bdff4beSrobert {
1263*4bdff4beSrobert     return std::__allocate_shared_bounded_array<_Tp>(allocator<__for_overwrite_tag>());
1264*4bdff4beSrobert }
1265*4bdff4beSrobert 
1266*4bdff4beSrobert // unbounded array variants
1267*4bdff4beSrobert template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1268*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1269*4bdff4beSrobert shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n)
1270*4bdff4beSrobert {
1271*4bdff4beSrobert     return std::__allocate_shared_unbounded_array<_Tp>(__a, __n);
1272*4bdff4beSrobert }
1273*4bdff4beSrobert 
1274*4bdff4beSrobert template<class _Tp, class _Alloc, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1275*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1276*4bdff4beSrobert shared_ptr<_Tp> allocate_shared(const _Alloc& __a, size_t __n, const remove_extent_t<_Tp>& __u)
1277*4bdff4beSrobert {
1278*4bdff4beSrobert     return std::__allocate_shared_unbounded_array<_Tp>(__a, __n, __u);
1279*4bdff4beSrobert }
1280*4bdff4beSrobert 
1281*4bdff4beSrobert template<class _Tp, class _Alloc, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
1282*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1283*4bdff4beSrobert shared_ptr<_Tp> allocate_shared_for_overwrite(const _Alloc& __a, size_t __n)
1284*4bdff4beSrobert {
1285*4bdff4beSrobert     using _ForOverwriteAllocator = __allocator_traits_rebind_t<_Alloc, __for_overwrite_tag>;
1286*4bdff4beSrobert     _ForOverwriteAllocator __alloc(__a);
1287*4bdff4beSrobert     return std::__allocate_shared_unbounded_array<_Tp>(__alloc, __n);
1288*4bdff4beSrobert }
1289*4bdff4beSrobert 
1290*4bdff4beSrobert template<class _Tp, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1291*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1292*4bdff4beSrobert shared_ptr<_Tp> make_shared(size_t __n)
1293*4bdff4beSrobert {
1294*4bdff4beSrobert     return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n);
1295*4bdff4beSrobert }
1296*4bdff4beSrobert 
1297*4bdff4beSrobert template<class _Tp, class = __enable_if_t<is_unbounded_array<_Tp>::value>>
1298*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1299*4bdff4beSrobert shared_ptr<_Tp> make_shared(size_t __n, const remove_extent_t<_Tp>& __u)
1300*4bdff4beSrobert {
1301*4bdff4beSrobert     return std::__allocate_shared_unbounded_array<_Tp>(allocator<_Tp>(), __n, __u);
1302*4bdff4beSrobert }
1303*4bdff4beSrobert 
1304*4bdff4beSrobert template<class _Tp, __enable_if_t<is_unbounded_array<_Tp>::value, int> = 0>
1305*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI
1306*4bdff4beSrobert shared_ptr<_Tp> make_shared_for_overwrite(size_t __n)
1307*4bdff4beSrobert {
1308*4bdff4beSrobert     return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n);
1309*4bdff4beSrobert }
1310*4bdff4beSrobert 
1311*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
1312*4bdff4beSrobert 
131376d0caaeSpatrick template<class _Tp, class _Up>
131476d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
131576d0caaeSpatrick bool
131676d0caaeSpatrick operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
131776d0caaeSpatrick {
131876d0caaeSpatrick     return __x.get() == __y.get();
131976d0caaeSpatrick }
132076d0caaeSpatrick 
1321*4bdff4beSrobert #if _LIBCPP_STD_VER <= 17
1322*4bdff4beSrobert 
132376d0caaeSpatrick template<class _Tp, class _Up>
132476d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
132576d0caaeSpatrick bool
132676d0caaeSpatrick operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
132776d0caaeSpatrick {
132876d0caaeSpatrick     return !(__x == __y);
132976d0caaeSpatrick }
133076d0caaeSpatrick 
133176d0caaeSpatrick template<class _Tp, class _Up>
133276d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
133376d0caaeSpatrick bool
133476d0caaeSpatrick operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
133576d0caaeSpatrick {
133676d0caaeSpatrick #if _LIBCPP_STD_VER <= 11
133776d0caaeSpatrick     typedef typename common_type<_Tp*, _Up*>::type _Vp;
133876d0caaeSpatrick     return less<_Vp>()(__x.get(), __y.get());
133976d0caaeSpatrick #else
134076d0caaeSpatrick     return less<>()(__x.get(), __y.get());
134176d0caaeSpatrick #endif
134276d0caaeSpatrick 
134376d0caaeSpatrick }
134476d0caaeSpatrick 
134576d0caaeSpatrick template<class _Tp, class _Up>
134676d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
134776d0caaeSpatrick bool
134876d0caaeSpatrick operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
134976d0caaeSpatrick {
135076d0caaeSpatrick     return __y < __x;
135176d0caaeSpatrick }
135276d0caaeSpatrick 
135376d0caaeSpatrick template<class _Tp, class _Up>
135476d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
135576d0caaeSpatrick bool
135676d0caaeSpatrick operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
135776d0caaeSpatrick {
135876d0caaeSpatrick     return !(__y < __x);
135976d0caaeSpatrick }
136076d0caaeSpatrick 
136176d0caaeSpatrick template<class _Tp, class _Up>
136276d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
136376d0caaeSpatrick bool
136476d0caaeSpatrick operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
136576d0caaeSpatrick {
136676d0caaeSpatrick     return !(__x < __y);
136776d0caaeSpatrick }
136876d0caaeSpatrick 
1369*4bdff4beSrobert #endif // _LIBCPP_STD_VER <= 17
1370*4bdff4beSrobert 
1371*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
1372*4bdff4beSrobert template<class _Tp, class _Up>
1373*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI strong_ordering
1374*4bdff4beSrobert operator<=>(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) noexcept
1375*4bdff4beSrobert {
1376*4bdff4beSrobert     return compare_three_way()(__x.get(), __y.get());
1377*4bdff4beSrobert }
1378*4bdff4beSrobert #endif
1379*4bdff4beSrobert 
138076d0caaeSpatrick template<class _Tp>
138176d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
138276d0caaeSpatrick bool
138376d0caaeSpatrick operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
138476d0caaeSpatrick {
138576d0caaeSpatrick     return !__x;
138676d0caaeSpatrick }
138776d0caaeSpatrick 
1388*4bdff4beSrobert #if _LIBCPP_STD_VER <= 17
1389*4bdff4beSrobert 
139076d0caaeSpatrick template<class _Tp>
139176d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
139276d0caaeSpatrick bool
139376d0caaeSpatrick operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
139476d0caaeSpatrick {
139576d0caaeSpatrick     return !__x;
139676d0caaeSpatrick }
139776d0caaeSpatrick 
139876d0caaeSpatrick template<class _Tp>
139976d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
140076d0caaeSpatrick bool
140176d0caaeSpatrick operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
140276d0caaeSpatrick {
140376d0caaeSpatrick     return static_cast<bool>(__x);
140476d0caaeSpatrick }
140576d0caaeSpatrick 
140676d0caaeSpatrick template<class _Tp>
140776d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
140876d0caaeSpatrick bool
140976d0caaeSpatrick operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
141076d0caaeSpatrick {
141176d0caaeSpatrick     return static_cast<bool>(__x);
141276d0caaeSpatrick }
141376d0caaeSpatrick 
141476d0caaeSpatrick template<class _Tp>
141576d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
141676d0caaeSpatrick bool
141776d0caaeSpatrick operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
141876d0caaeSpatrick {
141976d0caaeSpatrick     return less<_Tp*>()(__x.get(), nullptr);
142076d0caaeSpatrick }
142176d0caaeSpatrick 
142276d0caaeSpatrick template<class _Tp>
142376d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
142476d0caaeSpatrick bool
142576d0caaeSpatrick operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
142676d0caaeSpatrick {
142776d0caaeSpatrick     return less<_Tp*>()(nullptr, __x.get());
142876d0caaeSpatrick }
142976d0caaeSpatrick 
143076d0caaeSpatrick template<class _Tp>
143176d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
143276d0caaeSpatrick bool
143376d0caaeSpatrick operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
143476d0caaeSpatrick {
143576d0caaeSpatrick     return nullptr < __x;
143676d0caaeSpatrick }
143776d0caaeSpatrick 
143876d0caaeSpatrick template<class _Tp>
143976d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
144076d0caaeSpatrick bool
144176d0caaeSpatrick operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
144276d0caaeSpatrick {
144376d0caaeSpatrick     return __x < nullptr;
144476d0caaeSpatrick }
144576d0caaeSpatrick 
144676d0caaeSpatrick template<class _Tp>
144776d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
144876d0caaeSpatrick bool
144976d0caaeSpatrick operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
145076d0caaeSpatrick {
145176d0caaeSpatrick     return !(nullptr < __x);
145276d0caaeSpatrick }
145376d0caaeSpatrick 
145476d0caaeSpatrick template<class _Tp>
145576d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
145676d0caaeSpatrick bool
145776d0caaeSpatrick operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
145876d0caaeSpatrick {
145976d0caaeSpatrick     return !(__x < nullptr);
146076d0caaeSpatrick }
146176d0caaeSpatrick 
146276d0caaeSpatrick template<class _Tp>
146376d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
146476d0caaeSpatrick bool
146576d0caaeSpatrick operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
146676d0caaeSpatrick {
146776d0caaeSpatrick     return !(__x < nullptr);
146876d0caaeSpatrick }
146976d0caaeSpatrick 
147076d0caaeSpatrick template<class _Tp>
147176d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
147276d0caaeSpatrick bool
147376d0caaeSpatrick operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
147476d0caaeSpatrick {
147576d0caaeSpatrick     return !(nullptr < __x);
147676d0caaeSpatrick }
147776d0caaeSpatrick 
1478*4bdff4beSrobert #endif // _LIBCPP_STD_VER <= 17
1479*4bdff4beSrobert 
1480*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
1481*4bdff4beSrobert template<class _Tp>
1482*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI strong_ordering
1483*4bdff4beSrobert operator<=>(shared_ptr<_Tp> const& __x, nullptr_t) noexcept
1484*4bdff4beSrobert {
1485*4bdff4beSrobert     return compare_three_way()(__x.get(), static_cast<typename shared_ptr<_Tp>::element_type*>(nullptr));
1486*4bdff4beSrobert }
1487*4bdff4beSrobert #endif
1488*4bdff4beSrobert 
148976d0caaeSpatrick template<class _Tp>
149076d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
149176d0caaeSpatrick void
149276d0caaeSpatrick swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
149376d0caaeSpatrick {
149476d0caaeSpatrick     __x.swap(__y);
149576d0caaeSpatrick }
149676d0caaeSpatrick 
149776d0caaeSpatrick template<class _Tp, class _Up>
149876d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
149976d0caaeSpatrick shared_ptr<_Tp>
150076d0caaeSpatrick static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
150176d0caaeSpatrick {
150276d0caaeSpatrick     return shared_ptr<_Tp>(__r,
150376d0caaeSpatrick                            static_cast<
150476d0caaeSpatrick                                typename shared_ptr<_Tp>::element_type*>(__r.get()));
150576d0caaeSpatrick }
150676d0caaeSpatrick 
150776d0caaeSpatrick template<class _Tp, class _Up>
150876d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
150976d0caaeSpatrick shared_ptr<_Tp>
151076d0caaeSpatrick dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
151176d0caaeSpatrick {
151276d0caaeSpatrick     typedef typename shared_ptr<_Tp>::element_type _ET;
151376d0caaeSpatrick     _ET* __p = dynamic_cast<_ET*>(__r.get());
151476d0caaeSpatrick     return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
151576d0caaeSpatrick }
151676d0caaeSpatrick 
151776d0caaeSpatrick template<class _Tp, class _Up>
1518*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
151976d0caaeSpatrick const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
152076d0caaeSpatrick {
152176d0caaeSpatrick     typedef typename shared_ptr<_Tp>::element_type _RTp;
152276d0caaeSpatrick     return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
152376d0caaeSpatrick }
152476d0caaeSpatrick 
152576d0caaeSpatrick template<class _Tp, class _Up>
1526*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
152776d0caaeSpatrick reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
152876d0caaeSpatrick {
152976d0caaeSpatrick     return shared_ptr<_Tp>(__r,
153076d0caaeSpatrick                            reinterpret_cast<
153176d0caaeSpatrick                                typename shared_ptr<_Tp>::element_type*>(__r.get()));
153276d0caaeSpatrick }
153376d0caaeSpatrick 
1534*4bdff4beSrobert #ifndef _LIBCPP_HAS_NO_RTTI
153576d0caaeSpatrick 
153676d0caaeSpatrick template<class _Dp, class _Tp>
153776d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
153876d0caaeSpatrick _Dp*
153976d0caaeSpatrick get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
154076d0caaeSpatrick {
154176d0caaeSpatrick     return __p.template __get_deleter<_Dp>();
154276d0caaeSpatrick }
154376d0caaeSpatrick 
1544*4bdff4beSrobert #endif // _LIBCPP_HAS_NO_RTTI
154576d0caaeSpatrick 
154676d0caaeSpatrick template<class _Tp>
154776d0caaeSpatrick class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
154876d0caaeSpatrick {
154976d0caaeSpatrick public:
1550*4bdff4beSrobert #if _LIBCPP_STD_VER > 14
1551*4bdff4beSrobert     typedef remove_extent_t<_Tp> element_type;
1552*4bdff4beSrobert #else
155376d0caaeSpatrick     typedef _Tp element_type;
1554*4bdff4beSrobert #endif
1555*4bdff4beSrobert 
155676d0caaeSpatrick private:
155776d0caaeSpatrick     element_type*        __ptr_;
155876d0caaeSpatrick     __shared_weak_count* __cntrl_;
155976d0caaeSpatrick 
156076d0caaeSpatrick public:
156176d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
156276d0caaeSpatrick     _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
156376d0caaeSpatrick     template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r,
1564*4bdff4beSrobert                    typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0)
156576d0caaeSpatrick                         _NOEXCEPT;
156676d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
156776d0caaeSpatrick     weak_ptr(weak_ptr const& __r) _NOEXCEPT;
156876d0caaeSpatrick     template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r,
1569*4bdff4beSrobert                    typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0)
157076d0caaeSpatrick                          _NOEXCEPT;
157176d0caaeSpatrick 
157276d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
157376d0caaeSpatrick     weak_ptr(weak_ptr&& __r) _NOEXCEPT;
157476d0caaeSpatrick     template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
1575*4bdff4beSrobert                    typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0)
157676d0caaeSpatrick                          _NOEXCEPT;
157776d0caaeSpatrick     ~weak_ptr();
157876d0caaeSpatrick 
157976d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
158076d0caaeSpatrick     weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
158176d0caaeSpatrick     template<class _Yp>
158276d0caaeSpatrick         typename enable_if
158376d0caaeSpatrick         <
1584*4bdff4beSrobert             __compatible_with<_Yp, _Tp>::value,
158576d0caaeSpatrick             weak_ptr&
158676d0caaeSpatrick         >::type
158776d0caaeSpatrick         _LIBCPP_INLINE_VISIBILITY
158876d0caaeSpatrick         operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
158976d0caaeSpatrick 
159076d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
159176d0caaeSpatrick     weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
159276d0caaeSpatrick     template<class _Yp>
159376d0caaeSpatrick         typename enable_if
159476d0caaeSpatrick         <
1595*4bdff4beSrobert             __compatible_with<_Yp, _Tp>::value,
159676d0caaeSpatrick             weak_ptr&
159776d0caaeSpatrick         >::type
159876d0caaeSpatrick         _LIBCPP_INLINE_VISIBILITY
159976d0caaeSpatrick         operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
160076d0caaeSpatrick 
160176d0caaeSpatrick     template<class _Yp>
160276d0caaeSpatrick         typename enable_if
160376d0caaeSpatrick         <
1604*4bdff4beSrobert             __compatible_with<_Yp, _Tp>::value,
160576d0caaeSpatrick             weak_ptr&
160676d0caaeSpatrick         >::type
160776d0caaeSpatrick         _LIBCPP_INLINE_VISIBILITY
160876d0caaeSpatrick         operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
160976d0caaeSpatrick 
161076d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
161176d0caaeSpatrick     void swap(weak_ptr& __r) _NOEXCEPT;
161276d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
161376d0caaeSpatrick     void reset() _NOEXCEPT;
161476d0caaeSpatrick 
161576d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
161676d0caaeSpatrick     long use_count() const _NOEXCEPT
161776d0caaeSpatrick         {return __cntrl_ ? __cntrl_->use_count() : 0;}
161876d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
161976d0caaeSpatrick     bool expired() const _NOEXCEPT
162076d0caaeSpatrick         {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;}
162176d0caaeSpatrick     shared_ptr<_Tp> lock() const _NOEXCEPT;
162276d0caaeSpatrick     template<class _Up>
162376d0caaeSpatrick         _LIBCPP_INLINE_VISIBILITY
162476d0caaeSpatrick         bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT
162576d0caaeSpatrick         {return __cntrl_ < __r.__cntrl_;}
162676d0caaeSpatrick     template<class _Up>
162776d0caaeSpatrick         _LIBCPP_INLINE_VISIBILITY
162876d0caaeSpatrick         bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT
162976d0caaeSpatrick         {return __cntrl_ < __r.__cntrl_;}
163076d0caaeSpatrick 
163176d0caaeSpatrick     template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
163276d0caaeSpatrick     template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
163376d0caaeSpatrick };
163476d0caaeSpatrick 
1635*4bdff4beSrobert #if _LIBCPP_STD_VER > 14
163676d0caaeSpatrick template<class _Tp>
163776d0caaeSpatrick weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
163876d0caaeSpatrick #endif
163976d0caaeSpatrick 
164076d0caaeSpatrick template<class _Tp>
164176d0caaeSpatrick inline
164276d0caaeSpatrick _LIBCPP_CONSTEXPR
164376d0caaeSpatrick weak_ptr<_Tp>::weak_ptr() _NOEXCEPT
164476d0caaeSpatrick     : __ptr_(nullptr),
164576d0caaeSpatrick       __cntrl_(nullptr)
164676d0caaeSpatrick {
164776d0caaeSpatrick }
164876d0caaeSpatrick 
164976d0caaeSpatrick template<class _Tp>
165076d0caaeSpatrick inline
165176d0caaeSpatrick weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT
165276d0caaeSpatrick     : __ptr_(__r.__ptr_),
165376d0caaeSpatrick       __cntrl_(__r.__cntrl_)
165476d0caaeSpatrick {
165576d0caaeSpatrick     if (__cntrl_)
165676d0caaeSpatrick         __cntrl_->__add_weak();
165776d0caaeSpatrick }
165876d0caaeSpatrick 
165976d0caaeSpatrick template<class _Tp>
166076d0caaeSpatrick template<class _Yp>
166176d0caaeSpatrick inline
166276d0caaeSpatrick weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
1663*4bdff4beSrobert                         typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type)
166476d0caaeSpatrick                          _NOEXCEPT
166576d0caaeSpatrick     : __ptr_(__r.__ptr_),
166676d0caaeSpatrick       __cntrl_(__r.__cntrl_)
166776d0caaeSpatrick {
166876d0caaeSpatrick     if (__cntrl_)
166976d0caaeSpatrick         __cntrl_->__add_weak();
167076d0caaeSpatrick }
167176d0caaeSpatrick 
167276d0caaeSpatrick template<class _Tp>
167376d0caaeSpatrick template<class _Yp>
167476d0caaeSpatrick inline
167576d0caaeSpatrick weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
1676*4bdff4beSrobert                         typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type)
167776d0caaeSpatrick          _NOEXCEPT
167876d0caaeSpatrick     : __ptr_(__r.__ptr_),
167976d0caaeSpatrick       __cntrl_(__r.__cntrl_)
168076d0caaeSpatrick {
168176d0caaeSpatrick     if (__cntrl_)
168276d0caaeSpatrick         __cntrl_->__add_weak();
168376d0caaeSpatrick }
168476d0caaeSpatrick 
168576d0caaeSpatrick template<class _Tp>
168676d0caaeSpatrick inline
168776d0caaeSpatrick weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
168876d0caaeSpatrick     : __ptr_(__r.__ptr_),
168976d0caaeSpatrick       __cntrl_(__r.__cntrl_)
169076d0caaeSpatrick {
169176d0caaeSpatrick     __r.__ptr_ = nullptr;
169276d0caaeSpatrick     __r.__cntrl_ = nullptr;
169376d0caaeSpatrick }
169476d0caaeSpatrick 
169576d0caaeSpatrick template<class _Tp>
169676d0caaeSpatrick template<class _Yp>
169776d0caaeSpatrick inline
169876d0caaeSpatrick weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
1699*4bdff4beSrobert                         typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type)
170076d0caaeSpatrick          _NOEXCEPT
170176d0caaeSpatrick     : __ptr_(__r.__ptr_),
170276d0caaeSpatrick       __cntrl_(__r.__cntrl_)
170376d0caaeSpatrick {
170476d0caaeSpatrick     __r.__ptr_ = nullptr;
170576d0caaeSpatrick     __r.__cntrl_ = nullptr;
170676d0caaeSpatrick }
170776d0caaeSpatrick 
170876d0caaeSpatrick template<class _Tp>
170976d0caaeSpatrick weak_ptr<_Tp>::~weak_ptr()
171076d0caaeSpatrick {
171176d0caaeSpatrick     if (__cntrl_)
171276d0caaeSpatrick         __cntrl_->__release_weak();
171376d0caaeSpatrick }
171476d0caaeSpatrick 
171576d0caaeSpatrick template<class _Tp>
171676d0caaeSpatrick inline
171776d0caaeSpatrick weak_ptr<_Tp>&
171876d0caaeSpatrick weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
171976d0caaeSpatrick {
172076d0caaeSpatrick     weak_ptr(__r).swap(*this);
172176d0caaeSpatrick     return *this;
172276d0caaeSpatrick }
172376d0caaeSpatrick 
172476d0caaeSpatrick template<class _Tp>
172576d0caaeSpatrick template<class _Yp>
172676d0caaeSpatrick inline
172776d0caaeSpatrick typename enable_if
172876d0caaeSpatrick <
1729*4bdff4beSrobert     __compatible_with<_Yp, _Tp>::value,
173076d0caaeSpatrick     weak_ptr<_Tp>&
173176d0caaeSpatrick >::type
173276d0caaeSpatrick weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
173376d0caaeSpatrick {
173476d0caaeSpatrick     weak_ptr(__r).swap(*this);
173576d0caaeSpatrick     return *this;
173676d0caaeSpatrick }
173776d0caaeSpatrick 
173876d0caaeSpatrick template<class _Tp>
173976d0caaeSpatrick inline
174076d0caaeSpatrick weak_ptr<_Tp>&
174176d0caaeSpatrick weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
174276d0caaeSpatrick {
174376d0caaeSpatrick     weak_ptr(_VSTD::move(__r)).swap(*this);
174476d0caaeSpatrick     return *this;
174576d0caaeSpatrick }
174676d0caaeSpatrick 
174776d0caaeSpatrick template<class _Tp>
174876d0caaeSpatrick template<class _Yp>
174976d0caaeSpatrick inline
175076d0caaeSpatrick typename enable_if
175176d0caaeSpatrick <
1752*4bdff4beSrobert     __compatible_with<_Yp, _Tp>::value,
175376d0caaeSpatrick     weak_ptr<_Tp>&
175476d0caaeSpatrick >::type
175576d0caaeSpatrick weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
175676d0caaeSpatrick {
175776d0caaeSpatrick     weak_ptr(_VSTD::move(__r)).swap(*this);
175876d0caaeSpatrick     return *this;
175976d0caaeSpatrick }
176076d0caaeSpatrick 
176176d0caaeSpatrick template<class _Tp>
176276d0caaeSpatrick template<class _Yp>
176376d0caaeSpatrick inline
176476d0caaeSpatrick typename enable_if
176576d0caaeSpatrick <
1766*4bdff4beSrobert     __compatible_with<_Yp, _Tp>::value,
176776d0caaeSpatrick     weak_ptr<_Tp>&
176876d0caaeSpatrick >::type
176976d0caaeSpatrick weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
177076d0caaeSpatrick {
177176d0caaeSpatrick     weak_ptr(__r).swap(*this);
177276d0caaeSpatrick     return *this;
177376d0caaeSpatrick }
177476d0caaeSpatrick 
177576d0caaeSpatrick template<class _Tp>
177676d0caaeSpatrick inline
177776d0caaeSpatrick void
177876d0caaeSpatrick weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
177976d0caaeSpatrick {
178076d0caaeSpatrick     _VSTD::swap(__ptr_, __r.__ptr_);
178176d0caaeSpatrick     _VSTD::swap(__cntrl_, __r.__cntrl_);
178276d0caaeSpatrick }
178376d0caaeSpatrick 
178476d0caaeSpatrick template<class _Tp>
178576d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
178676d0caaeSpatrick void
178776d0caaeSpatrick swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
178876d0caaeSpatrick {
178976d0caaeSpatrick     __x.swap(__y);
179076d0caaeSpatrick }
179176d0caaeSpatrick 
179276d0caaeSpatrick template<class _Tp>
179376d0caaeSpatrick inline
179476d0caaeSpatrick void
179576d0caaeSpatrick weak_ptr<_Tp>::reset() _NOEXCEPT
179676d0caaeSpatrick {
179776d0caaeSpatrick     weak_ptr().swap(*this);
179876d0caaeSpatrick }
179976d0caaeSpatrick 
180076d0caaeSpatrick template<class _Tp>
180176d0caaeSpatrick shared_ptr<_Tp>
180276d0caaeSpatrick weak_ptr<_Tp>::lock() const _NOEXCEPT
180376d0caaeSpatrick {
180476d0caaeSpatrick     shared_ptr<_Tp> __r;
180576d0caaeSpatrick     __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
180676d0caaeSpatrick     if (__r.__cntrl_)
180776d0caaeSpatrick         __r.__ptr_ = __ptr_;
180876d0caaeSpatrick     return __r;
180976d0caaeSpatrick }
181076d0caaeSpatrick 
181176d0caaeSpatrick #if _LIBCPP_STD_VER > 14
181276d0caaeSpatrick template <class _Tp = void> struct owner_less;
181376d0caaeSpatrick #else
181476d0caaeSpatrick template <class _Tp> struct owner_less;
181576d0caaeSpatrick #endif
181676d0caaeSpatrick 
181776d0caaeSpatrick 
181876d0caaeSpatrick template <class _Tp>
181976d0caaeSpatrick struct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> >
1820*4bdff4beSrobert     : __binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
182176d0caaeSpatrick {
182276d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
182376d0caaeSpatrick     bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
182476d0caaeSpatrick         {return __x.owner_before(__y);}
182576d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
182676d0caaeSpatrick     bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
182776d0caaeSpatrick         {return __x.owner_before(__y);}
182876d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
182976d0caaeSpatrick     bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
183076d0caaeSpatrick         {return __x.owner_before(__y);}
183176d0caaeSpatrick };
183276d0caaeSpatrick 
183376d0caaeSpatrick template <class _Tp>
183476d0caaeSpatrick struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
1835*4bdff4beSrobert     : __binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
183676d0caaeSpatrick {
183776d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
183876d0caaeSpatrick     bool operator()(  weak_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
183976d0caaeSpatrick         {return __x.owner_before(__y);}
184076d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
184176d0caaeSpatrick     bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
184276d0caaeSpatrick         {return __x.owner_before(__y);}
184376d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
184476d0caaeSpatrick     bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
184576d0caaeSpatrick         {return __x.owner_before(__y);}
184676d0caaeSpatrick };
184776d0caaeSpatrick 
184876d0caaeSpatrick #if _LIBCPP_STD_VER > 14
184976d0caaeSpatrick template <>
185076d0caaeSpatrick struct _LIBCPP_TEMPLATE_VIS owner_less<void>
185176d0caaeSpatrick {
185276d0caaeSpatrick     template <class _Tp, class _Up>
185376d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
185476d0caaeSpatrick     bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
185576d0caaeSpatrick         {return __x.owner_before(__y);}
185676d0caaeSpatrick     template <class _Tp, class _Up>
185776d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
185876d0caaeSpatrick     bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const _NOEXCEPT
185976d0caaeSpatrick         {return __x.owner_before(__y);}
186076d0caaeSpatrick     template <class _Tp, class _Up>
186176d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
186276d0caaeSpatrick     bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
186376d0caaeSpatrick         {return __x.owner_before(__y);}
186476d0caaeSpatrick     template <class _Tp, class _Up>
186576d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
186676d0caaeSpatrick     bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const _NOEXCEPT
186776d0caaeSpatrick         {return __x.owner_before(__y);}
186876d0caaeSpatrick     typedef void is_transparent;
186976d0caaeSpatrick };
187076d0caaeSpatrick #endif
187176d0caaeSpatrick 
187276d0caaeSpatrick template<class _Tp>
187376d0caaeSpatrick class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
187476d0caaeSpatrick {
187576d0caaeSpatrick     mutable weak_ptr<_Tp> __weak_this_;
187676d0caaeSpatrick protected:
187776d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
187876d0caaeSpatrick     enable_shared_from_this() _NOEXCEPT {}
187976d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
188076d0caaeSpatrick     enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
188176d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
188276d0caaeSpatrick     enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
188376d0caaeSpatrick         {return *this;}
188476d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
188576d0caaeSpatrick     ~enable_shared_from_this() {}
188676d0caaeSpatrick public:
188776d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
188876d0caaeSpatrick     shared_ptr<_Tp> shared_from_this()
188976d0caaeSpatrick         {return shared_ptr<_Tp>(__weak_this_);}
189076d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
189176d0caaeSpatrick     shared_ptr<_Tp const> shared_from_this() const
189276d0caaeSpatrick         {return shared_ptr<const _Tp>(__weak_this_);}
189376d0caaeSpatrick 
189476d0caaeSpatrick #if _LIBCPP_STD_VER > 14
189576d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
189676d0caaeSpatrick     weak_ptr<_Tp> weak_from_this() _NOEXCEPT
189776d0caaeSpatrick        { return __weak_this_; }
189876d0caaeSpatrick 
189976d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
190076d0caaeSpatrick     weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
190176d0caaeSpatrick         { return __weak_this_; }
190276d0caaeSpatrick #endif // _LIBCPP_STD_VER > 14
190376d0caaeSpatrick 
190476d0caaeSpatrick     template <class _Up> friend class shared_ptr;
190576d0caaeSpatrick };
190676d0caaeSpatrick 
190776d0caaeSpatrick template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
190876d0caaeSpatrick 
190976d0caaeSpatrick template <class _Tp>
191076d0caaeSpatrick struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >
191176d0caaeSpatrick {
191276d0caaeSpatrick #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
191376d0caaeSpatrick     _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> argument_type;
191476d0caaeSpatrick     _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t          result_type;
191576d0caaeSpatrick #endif
191676d0caaeSpatrick 
191776d0caaeSpatrick     _LIBCPP_INLINE_VISIBILITY
191876d0caaeSpatrick     size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT
191976d0caaeSpatrick     {
192076d0caaeSpatrick         return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
192176d0caaeSpatrick     }
192276d0caaeSpatrick };
192376d0caaeSpatrick 
192476d0caaeSpatrick template<class _CharT, class _Traits, class _Yp>
192576d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
192676d0caaeSpatrick basic_ostream<_CharT, _Traits>&
192776d0caaeSpatrick operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
192876d0caaeSpatrick 
192976d0caaeSpatrick 
1930*4bdff4beSrobert #if !defined(_LIBCPP_HAS_NO_THREADS)
193176d0caaeSpatrick 
193276d0caaeSpatrick class _LIBCPP_TYPE_VIS __sp_mut
193376d0caaeSpatrick {
1934*4bdff4beSrobert     void* __lx_;
193576d0caaeSpatrick public:
193676d0caaeSpatrick     void lock() _NOEXCEPT;
193776d0caaeSpatrick     void unlock() _NOEXCEPT;
193876d0caaeSpatrick 
193976d0caaeSpatrick private:
194076d0caaeSpatrick     _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;
194176d0caaeSpatrick     __sp_mut(const __sp_mut&);
194276d0caaeSpatrick     __sp_mut& operator=(const __sp_mut&);
194376d0caaeSpatrick 
194476d0caaeSpatrick     friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
194576d0caaeSpatrick };
194676d0caaeSpatrick 
194776d0caaeSpatrick _LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
194876d0caaeSpatrick __sp_mut& __get_sp_mut(const void*);
194976d0caaeSpatrick 
195076d0caaeSpatrick template <class _Tp>
195176d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
195276d0caaeSpatrick bool
195376d0caaeSpatrick atomic_is_lock_free(const shared_ptr<_Tp>*)
195476d0caaeSpatrick {
195576d0caaeSpatrick     return false;
195676d0caaeSpatrick }
195776d0caaeSpatrick 
195876d0caaeSpatrick template <class _Tp>
195976d0caaeSpatrick _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1960*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
196176d0caaeSpatrick atomic_load(const shared_ptr<_Tp>* __p)
196276d0caaeSpatrick {
1963*4bdff4beSrobert     __sp_mut& __m = std::__get_sp_mut(__p);
196476d0caaeSpatrick     __m.lock();
196576d0caaeSpatrick     shared_ptr<_Tp> __q = *__p;
196676d0caaeSpatrick     __m.unlock();
196776d0caaeSpatrick     return __q;
196876d0caaeSpatrick }
196976d0caaeSpatrick 
197076d0caaeSpatrick template <class _Tp>
197176d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
197276d0caaeSpatrick _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
197376d0caaeSpatrick shared_ptr<_Tp>
197476d0caaeSpatrick atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
197576d0caaeSpatrick {
1976*4bdff4beSrobert     return std::atomic_load(__p);
197776d0caaeSpatrick }
197876d0caaeSpatrick 
197976d0caaeSpatrick template <class _Tp>
198076d0caaeSpatrick _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1981*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI void
198276d0caaeSpatrick atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
198376d0caaeSpatrick {
1984*4bdff4beSrobert     __sp_mut& __m = std::__get_sp_mut(__p);
198576d0caaeSpatrick     __m.lock();
198676d0caaeSpatrick     __p->swap(__r);
198776d0caaeSpatrick     __m.unlock();
198876d0caaeSpatrick }
198976d0caaeSpatrick 
199076d0caaeSpatrick template <class _Tp>
199176d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
199276d0caaeSpatrick _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
199376d0caaeSpatrick void
199476d0caaeSpatrick atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
199576d0caaeSpatrick {
1996*4bdff4beSrobert     std::atomic_store(__p, __r);
199776d0caaeSpatrick }
199876d0caaeSpatrick 
199976d0caaeSpatrick template <class _Tp>
200076d0caaeSpatrick _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2001*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>
200276d0caaeSpatrick atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
200376d0caaeSpatrick {
2004*4bdff4beSrobert     __sp_mut& __m = std::__get_sp_mut(__p);
200576d0caaeSpatrick     __m.lock();
200676d0caaeSpatrick     __p->swap(__r);
200776d0caaeSpatrick     __m.unlock();
200876d0caaeSpatrick     return __r;
200976d0caaeSpatrick }
201076d0caaeSpatrick 
201176d0caaeSpatrick template <class _Tp>
201276d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
201376d0caaeSpatrick _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
201476d0caaeSpatrick shared_ptr<_Tp>
201576d0caaeSpatrick atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
201676d0caaeSpatrick {
2017*4bdff4beSrobert     return std::atomic_exchange(__p, __r);
201876d0caaeSpatrick }
201976d0caaeSpatrick 
202076d0caaeSpatrick template <class _Tp>
202176d0caaeSpatrick _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
2022*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI bool
202376d0caaeSpatrick atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
202476d0caaeSpatrick {
202576d0caaeSpatrick     shared_ptr<_Tp> __temp;
2026*4bdff4beSrobert     __sp_mut& __m = std::__get_sp_mut(__p);
202776d0caaeSpatrick     __m.lock();
202876d0caaeSpatrick     if (__p->__owner_equivalent(*__v))
202976d0caaeSpatrick     {
203076d0caaeSpatrick         _VSTD::swap(__temp, *__p);
203176d0caaeSpatrick         *__p = __w;
203276d0caaeSpatrick         __m.unlock();
203376d0caaeSpatrick         return true;
203476d0caaeSpatrick     }
203576d0caaeSpatrick     _VSTD::swap(__temp, *__v);
203676d0caaeSpatrick     *__v = *__p;
203776d0caaeSpatrick     __m.unlock();
203876d0caaeSpatrick     return false;
203976d0caaeSpatrick }
204076d0caaeSpatrick 
204176d0caaeSpatrick template <class _Tp>
204276d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
204376d0caaeSpatrick _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
204476d0caaeSpatrick bool
204576d0caaeSpatrick atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
204676d0caaeSpatrick {
2047*4bdff4beSrobert     return std::atomic_compare_exchange_strong(__p, __v, __w);
204876d0caaeSpatrick }
204976d0caaeSpatrick 
205076d0caaeSpatrick template <class _Tp>
205176d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
205276d0caaeSpatrick _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
205376d0caaeSpatrick bool
205476d0caaeSpatrick atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
205576d0caaeSpatrick                                         shared_ptr<_Tp> __w, memory_order, memory_order)
205676d0caaeSpatrick {
2057*4bdff4beSrobert     return std::atomic_compare_exchange_strong(__p, __v, __w);
205876d0caaeSpatrick }
205976d0caaeSpatrick 
206076d0caaeSpatrick template <class _Tp>
206176d0caaeSpatrick inline _LIBCPP_INLINE_VISIBILITY
206276d0caaeSpatrick _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
206376d0caaeSpatrick bool
206476d0caaeSpatrick atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
206576d0caaeSpatrick                                       shared_ptr<_Tp> __w, memory_order, memory_order)
206676d0caaeSpatrick {
2067*4bdff4beSrobert     return std::atomic_compare_exchange_weak(__p, __v, __w);
206876d0caaeSpatrick }
206976d0caaeSpatrick 
2070*4bdff4beSrobert #endif // !defined(_LIBCPP_HAS_NO_THREADS)
207176d0caaeSpatrick 
207276d0caaeSpatrick _LIBCPP_END_NAMESPACE_STD
207376d0caaeSpatrick 
207476d0caaeSpatrick #endif // _LIBCPP___MEMORY_SHARED_PTR_H
2075