1218 lines · c
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___CXX03___MEMORY_SHARED_PTR_H11#define _LIBCPP___CXX03___MEMORY_SHARED_PTR_H12 13#include <__cxx03/__config>14#include <__cxx03/__exception/exception.h>15#include <__cxx03/__functional/binary_function.h>16#include <__cxx03/__functional/operations.h>17#include <__cxx03/__functional/reference_wrapper.h>18#include <__cxx03/__fwd/ostream.h>19#include <__cxx03/__iterator/access.h>20#include <__cxx03/__memory/addressof.h>21#include <__cxx03/__memory/allocation_guard.h>22#include <__cxx03/__memory/allocator.h>23#include <__cxx03/__memory/allocator_destructor.h>24#include <__cxx03/__memory/allocator_traits.h>25#include <__cxx03/__memory/auto_ptr.h>26#include <__cxx03/__memory/compressed_pair.h>27#include <__cxx03/__memory/construct_at.h>28#include <__cxx03/__memory/pointer_traits.h>29#include <__cxx03/__memory/uninitialized_algorithms.h>30#include <__cxx03/__memory/unique_ptr.h>31#include <__cxx03/__type_traits/add_lvalue_reference.h>32#include <__cxx03/__type_traits/conditional.h>33#include <__cxx03/__type_traits/conjunction.h>34#include <__cxx03/__type_traits/disjunction.h>35#include <__cxx03/__type_traits/is_array.h>36#include <__cxx03/__type_traits/is_bounded_array.h>37#include <__cxx03/__type_traits/is_constructible.h>38#include <__cxx03/__type_traits/is_convertible.h>39#include <__cxx03/__type_traits/is_reference.h>40#include <__cxx03/__type_traits/is_unbounded_array.h>41#include <__cxx03/__type_traits/nat.h>42#include <__cxx03/__type_traits/negation.h>43#include <__cxx03/__type_traits/remove_extent.h>44#include <__cxx03/__type_traits/remove_reference.h>45#include <__cxx03/__utility/declval.h>46#include <__cxx03/__utility/forward.h>47#include <__cxx03/__utility/move.h>48#include <__cxx03/__utility/swap.h>49#include <__cxx03/__verbose_abort>50#include <__cxx03/cstddef>51#include <__cxx03/new>52#include <__cxx03/typeinfo>53#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)54# include <__cxx03/__atomic/memory_order.h>55#endif56 57#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)58# pragma GCC system_header59#endif60 61_LIBCPP_PUSH_MACROS62#include <__cxx03/__undef_macros>63 64_LIBCPP_BEGIN_NAMESPACE_STD65 66// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)67// should be sufficient for thread safety.68// See https://llvm.org/PR2280369#if defined(__clang__) && __has_builtin(__atomic_add_fetch) && defined(__ATOMIC_RELAXED) && defined(__ATOMIC_ACQ_REL)70# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT71#elif defined(_LIBCPP_COMPILER_GCC)72# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT73#endif74 75template <class _ValueType>76inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_relaxed_load(_ValueType const* __value) {77#if !defined(_LIBCPP_HAS_NO_THREADS) && defined(__ATOMIC_RELAXED) && \78 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))79 return __atomic_load_n(__value, __ATOMIC_RELAXED);80#else81 return *__value;82#endif83}84 85template <class _ValueType>86inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_acquire_load(_ValueType const* __value) {87#if !defined(_LIBCPP_HAS_NO_THREADS) && defined(__ATOMIC_ACQUIRE) && \88 (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))89 return __atomic_load_n(__value, __ATOMIC_ACQUIRE);90#else91 return *__value;92#endif93}94 95template <class _Tp>96inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT {97#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)98 return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);99#else100 return __t += 1;101#endif102}103 104template <class _Tp>105inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT {106#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)107 return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);108#else109 return __t -= 1;110#endif111}112 113class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr : public std::exception {114public:115 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr() _NOEXCEPT = default;116 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;117 _LIBCPP_HIDE_FROM_ABI bad_weak_ptr& operator=(const bad_weak_ptr&) _NOEXCEPT = default;118 ~bad_weak_ptr() _NOEXCEPT override;119 const char* what() const _NOEXCEPT override;120};121 122_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_weak_ptr() {123#ifndef _LIBCPP_HAS_NO_EXCEPTIONS124 throw bad_weak_ptr();125#else126 _LIBCPP_VERBOSE_ABORT("bad_weak_ptr was thrown in -fno-exceptions mode");127#endif128}129 130template <class _Tp>131class _LIBCPP_TEMPLATE_VIS weak_ptr;132 133class _LIBCPP_EXPORTED_FROM_ABI __shared_count {134 __shared_count(const __shared_count&);135 __shared_count& operator=(const __shared_count&);136 137protected:138 long __shared_owners_;139 virtual ~__shared_count();140 141private:142 virtual void __on_zero_shared() _NOEXCEPT = 0;143 144public:145 _LIBCPP_HIDE_FROM_ABI explicit __shared_count(long __refs = 0) _NOEXCEPT : __shared_owners_(__refs) {}146 147#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)148 void __add_shared() noexcept;149 bool __release_shared() noexcept;150#else151 _LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_owners_); }152 _LIBCPP_HIDE_FROM_ABI bool __release_shared() _NOEXCEPT {153 if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {154 __on_zero_shared();155 return true;156 }157 return false;158 }159#endif160 _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __libcpp_relaxed_load(&__shared_owners_) + 1; }161};162 163class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count : private __shared_count {164 long __shared_weak_owners_;165 166public:167 _LIBCPP_HIDE_FROM_ABI explicit __shared_weak_count(long __refs = 0) _NOEXCEPT168 : __shared_count(__refs),169 __shared_weak_owners_(__refs) {}170 171protected:172 ~__shared_weak_count() override;173 174public:175#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)176 void __add_shared() noexcept;177 void __add_weak() noexcept;178 void __release_shared() noexcept;179#else180 _LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __shared_count::__add_shared(); }181 _LIBCPP_HIDE_FROM_ABI void __add_weak() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_weak_owners_); }182 _LIBCPP_HIDE_FROM_ABI void __release_shared() _NOEXCEPT {183 if (__shared_count::__release_shared())184 __release_weak();185 }186#endif187 void __release_weak() _NOEXCEPT;188 _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __shared_count::use_count(); }189 __shared_weak_count* lock() _NOEXCEPT;190 191 virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;192 193private:194 virtual void __on_zero_shared_weak() _NOEXCEPT = 0;195};196 197template <class _Tp, class _Dp, class _Alloc>198class __shared_ptr_pointer : public __shared_weak_count {199 __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;200 201public:202 _LIBCPP_HIDE_FROM_ABI __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)203 : __data_(__compressed_pair<_Tp, _Dp>(__p, std::move(__d)), std::move(__a)) {}204 205#ifndef _LIBCPP_HAS_NO_RTTI206 _LIBCPP_HIDE_FROM_ABI_VIRTUAL const void* __get_deleter(const type_info&) const _NOEXCEPT override;207#endif208 209private:210 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override;211 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override;212};213 214#ifndef _LIBCPP_HAS_NO_RTTI215 216template <class _Tp, class _Dp, class _Alloc>217const void* __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT {218 return __t == typeid(_Dp) ? std::addressof(__data_.first().second()) : nullptr;219}220 221#endif // _LIBCPP_HAS_NO_RTTI222 223template <class _Tp, class _Dp, class _Alloc>224void __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT {225 __data_.first().second()(__data_.first().first());226 __data_.first().second().~_Dp();227}228 229template <class _Tp, class _Dp, class _Alloc>230void __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT {231 typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;232 typedef allocator_traits<_Al> _ATraits;233 typedef pointer_traits<typename _ATraits::pointer> _PTraits;234 235 _Al __a(__data_.second());236 __data_.second().~_Alloc();237 __a.deallocate(_PTraits::pointer_to(*this), 1);238}239 240// This tag is used to instantiate an allocator type. The various shared_ptr control blocks241// detect that the allocator has been instantiated for this type and perform alternative242// initialization/destruction based on that.243struct __for_overwrite_tag {};244 245template <class _Tp, class _Alloc>246struct __shared_ptr_emplace : __shared_weak_count {247 template <class... _Args,248 class _Allocator = _Alloc,249 __enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>250 _LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&...) : __storage_(std::move(__a)) {251 static_assert(252 sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");253 ::new ((void*)__get_elem()) _Tp;254 }255 256 template <class... _Args,257 class _Allocator = _Alloc,258 __enable_if_t<!is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>259 _LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&... __args) : __storage_(std::move(__a)) {260 using _TpAlloc = typename __allocator_traits_rebind<_Alloc, __remove_cv_t<_Tp> >::type;261 _TpAlloc __tmp(*__get_alloc());262 allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), std::forward<_Args>(__args)...);263 }264 265 _LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }266 267 _LIBCPP_HIDE_FROM_ABI _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }268 269private:270 template <class _Allocator = _Alloc,271 __enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>272 _LIBCPP_HIDE_FROM_ABI void __on_zero_shared_impl() _NOEXCEPT {273 __get_elem()->~_Tp();274 }275 276 template <class _Allocator = _Alloc,277 __enable_if_t<!is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>278 _LIBCPP_HIDE_FROM_ABI void __on_zero_shared_impl() _NOEXCEPT {279 using _TpAlloc = typename __allocator_traits_rebind<_Allocator, __remove_cv_t<_Tp> >::type;280 _TpAlloc __tmp(*__get_alloc());281 allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());282 }283 284 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { __on_zero_shared_impl(); }285 286 _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {287 using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;288 using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;289 _ControlBlockAlloc __tmp(*__get_alloc());290 __storage_.~_Storage();291 allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1);292 }293 294 // This class implements the control block for non-array shared pointers created295 // through `std::allocate_shared` and `std::make_shared`.296 //297 // In previous versions of the library, we used a compressed pair to store298 // both the _Alloc and the _Tp. This implies using EBO, which is incompatible299 // with Allocator construction for _Tp. To allow implementing P0674 in C++20,300 // we now use a properly aligned char buffer while making sure that we maintain301 // the same layout that we had when we used a compressed pair.302 using _CompressedPair = __compressed_pair<_Alloc, _Tp>;303 struct _ALIGNAS_TYPE(_CompressedPair) _Storage {304 char __blob_[sizeof(_CompressedPair)];305 306 _LIBCPP_HIDE_FROM_ABI explicit _Storage(_Alloc&& __a) { ::new ((void*)__get_alloc()) _Alloc(std::move(__a)); }307 _LIBCPP_HIDE_FROM_ABI ~_Storage() { __get_alloc()->~_Alloc(); }308 _LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT {309 _CompressedPair* __as_pair = reinterpret_cast<_CompressedPair*>(__blob_);310 typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair);311 _Alloc* __alloc = reinterpret_cast<_Alloc*>(__first);312 return __alloc;313 }314 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {315 _CompressedPair* __as_pair = reinterpret_cast<_CompressedPair*>(__blob_);316 typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair);317 _Tp* __elem = reinterpret_cast<_Tp*>(__second);318 return __elem;319 }320 };321 322 static_assert(_LIBCPP_ALIGNOF(_Storage) == _LIBCPP_ALIGNOF(_CompressedPair), "");323 static_assert(sizeof(_Storage) == sizeof(_CompressedPair), "");324 _Storage __storage_;325};326 327struct __shared_ptr_dummy_rebind_allocator_type;328template <>329class _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type> {330public:331 template <class _Other>332 struct rebind {333 typedef allocator<_Other> other;334 };335};336 337template <class _Tp>338class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;339 340// http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.general-6341// A pointer type Y* is said to be compatible with a pointer type T*342// when either Y* is convertible to T* or Y is U[N] and T is cv U[].343template <class _Yp, class _Tp>344struct __compatible_with : is_convertible<_Yp*, _Tp*> {};345 346// Constructors that take raw pointers have a different set of "compatible" constraints347// http://eel.is/c++draft/util.sharedptr#util.smartptr.shared.const-9.1348// - If T is an array type, then either T is U[N] and Y(*)[N] is convertible to T*,349// or T is U[] and Y(*)[] is convertible to T*.350// - If T is not an array type, then Y* is convertible to T*.351template <class _Yp, class _Tp>352struct __raw_pointer_compatible_with : is_convertible<_Yp*, _Tp*> {};353 354template <class _Ptr, class = void>355struct __is_deletable : false_type {};356template <class _Ptr>357struct __is_deletable<_Ptr, decltype(delete std::declval<_Ptr>())> : true_type {};358 359template <class _Ptr, class = void>360struct __is_array_deletable : false_type {};361template <class _Ptr>362struct __is_array_deletable<_Ptr, decltype(delete[] std::declval<_Ptr>())> : true_type {};363 364template <class _Dp, class _Pt, class = decltype(std::declval<_Dp>()(std::declval<_Pt>()))>365true_type __well_formed_deleter_test(int);366 367template <class, class>368false_type __well_formed_deleter_test(...);369 370template <class _Dp, class _Pt>371struct __well_formed_deleter : decltype(std::__well_formed_deleter_test<_Dp, _Pt>(0)) {};372 373template <class _Dp, class _Yp, class _Tp>374struct __shared_ptr_deleter_ctor_reqs {375 static const bool value = __raw_pointer_compatible_with<_Yp, _Tp>::value && is_move_constructible<_Dp>::value &&376 __well_formed_deleter<_Dp, _Yp*>::value;377};378 379template <class _Dp>380using __shared_ptr_nullptr_deleter_ctor_reqs = _And<is_move_constructible<_Dp>, __well_formed_deleter<_Dp, nullptr_t> >;381 382#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)383# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))384#else385# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI386#endif387 388template <class _Tp>389class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr {390 struct __nullptr_sfinae_tag {};391 392public:393 typedef _Tp element_type;394 395 // A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require396 // any bookkeeping, so it's always trivially relocatable.397 using __trivially_relocatable = shared_ptr;398 399private:400 element_type* __ptr_;401 __shared_weak_count* __cntrl_;402 403public:404 _LIBCPP_HIDE_FROM_ABI shared_ptr() _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {}405 406 _LIBCPP_HIDE_FROM_ABI shared_ptr(nullptr_t) _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {}407 408 template <class _Yp, __enable_if_t< _And< __raw_pointer_compatible_with<_Yp, _Tp> >::value, int> = 0>409 _LIBCPP_HIDE_FROM_ABI explicit shared_ptr(_Yp* __p) : __ptr_(__p) {410 unique_ptr<_Yp> __hold(__p);411 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;412 typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT> _CntrlBlk;413 __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());414 __hold.release();415 __enable_weak_this(__p, __p);416 }417 418 template <class _Yp, class _Dp, __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0>419 _LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d) : __ptr_(__p) {420#ifndef _LIBCPP_HAS_NO_EXCEPTIONS421 try {422#endif // _LIBCPP_HAS_NO_EXCEPTIONS423 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;424 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk;425 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());426 __enable_weak_this(__p, __p);427#ifndef _LIBCPP_HAS_NO_EXCEPTIONS428 } catch (...) {429 __d(__p);430 throw;431 }432#endif // _LIBCPP_HAS_NO_EXCEPTIONS433 }434 435 template <class _Yp,436 class _Dp,437 class _Alloc,438 __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0>439 _LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d, _Alloc __a) : __ptr_(__p) {440#ifndef _LIBCPP_HAS_NO_EXCEPTIONS441 try {442#endif // _LIBCPP_HAS_NO_EXCEPTIONS443 typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;444 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;445 typedef __allocator_destructor<_A2> _D2;446 _A2 __a2(__a);447 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));448 ::new ((void*)std::addressof(*__hold2.get())) _CntrlBlk(__p, __d, __a);449 __cntrl_ = std::addressof(*__hold2.release());450 __enable_weak_this(__p, __p);451#ifndef _LIBCPP_HAS_NO_EXCEPTIONS452 } catch (...) {453 __d(__p);454 throw;455 }456#endif // _LIBCPP_HAS_NO_EXCEPTIONS457 }458 459 template <class _Dp>460 _LIBCPP_HIDE_FROM_ABI shared_ptr(461 nullptr_t __p,462 _Dp __d,463 __enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs<_Dp>::value, __nullptr_sfinae_tag> = __nullptr_sfinae_tag())464 : __ptr_(nullptr) {465#ifndef _LIBCPP_HAS_NO_EXCEPTIONS466 try {467#endif // _LIBCPP_HAS_NO_EXCEPTIONS468 typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;469 typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk;470 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());471#ifndef _LIBCPP_HAS_NO_EXCEPTIONS472 } catch (...) {473 __d(__p);474 throw;475 }476#endif // _LIBCPP_HAS_NO_EXCEPTIONS477 }478 479 template <class _Dp, class _Alloc>480 _LIBCPP_HIDE_FROM_ABI shared_ptr(481 nullptr_t __p,482 _Dp __d,483 _Alloc __a,484 __enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs<_Dp>::value, __nullptr_sfinae_tag> = __nullptr_sfinae_tag())485 : __ptr_(nullptr) {486#ifndef _LIBCPP_HAS_NO_EXCEPTIONS487 try {488#endif // _LIBCPP_HAS_NO_EXCEPTIONS489 typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;490 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;491 typedef __allocator_destructor<_A2> _D2;492 _A2 __a2(__a);493 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));494 ::new ((void*)std::addressof(*__hold2.get())) _CntrlBlk(__p, __d, __a);495 __cntrl_ = std::addressof(*__hold2.release());496#ifndef _LIBCPP_HAS_NO_EXCEPTIONS497 } catch (...) {498 __d(__p);499 throw;500 }501#endif // _LIBCPP_HAS_NO_EXCEPTIONS502 }503 504 template <class _Yp>505 _LIBCPP_HIDE_FROM_ABI shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT506 : __ptr_(__p),507 __cntrl_(__r.__cntrl_) {508 if (__cntrl_)509 __cntrl_->__add_shared();510 }511 512 _LIBCPP_HIDE_FROM_ABI shared_ptr(const shared_ptr& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {513 if (__cntrl_)514 __cntrl_->__add_shared();515 }516 517 template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0>518 _LIBCPP_HIDE_FROM_ABI shared_ptr(const shared_ptr<_Yp>& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {519 if (__cntrl_)520 __cntrl_->__add_shared();521 }522 523 _LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr&& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {524 __r.__ptr_ = nullptr;525 __r.__cntrl_ = nullptr;526 }527 528 template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0>529 _LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr<_Yp>&& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {530 __r.__ptr_ = nullptr;531 __r.__cntrl_ = nullptr;532 }533 534 template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0>535 _LIBCPP_HIDE_FROM_ABI explicit shared_ptr(const weak_ptr<_Yp>& __r)536 : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_) {537 if (__cntrl_ == nullptr)538 __throw_bad_weak_ptr();539 }540 541 template <class _Yp, __enable_if_t<is_convertible<_Yp*, element_type*>::value, int> = 0>542 _LIBCPP_HIDE_FROM_ABI shared_ptr(auto_ptr<_Yp>&& __r) : __ptr_(__r.get()) {543 typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<__remove_cv_t<_Yp> > > _CntrlBlk;544 __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<__remove_cv_t<_Yp> >());545 __enable_weak_this(__r.get(), __r.get());546 __r.release();547 }548 549 template <class _Yp,550 class _Dp,551 __enable_if_t<!is_lvalue_reference<_Dp>::value && __compatible_with<_Yp, _Tp>::value &&552 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,553 int> = 0>554 _LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) : __ptr_(__r.get()) {555 {556 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;557 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT> _CntrlBlk;558 __cntrl_ = new _CntrlBlk(__r.get(), std::move(__r.get_deleter()), _AllocT());559 __enable_weak_this(__r.get(), __r.get());560 }561 __r.release();562 }563 564 template <class _Yp,565 class _Dp,566 class = void,567 __enable_if_t<is_lvalue_reference<_Dp>::value && __compatible_with<_Yp, _Tp>::value &&568 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,569 int> = 0>570 _LIBCPP_HIDE_FROM_ABI shared_ptr(unique_ptr<_Yp, _Dp>&& __r) : __ptr_(__r.get()) {571 {572 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;573 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer,574 reference_wrapper<__libcpp_remove_reference_t<_Dp> >,575 _AllocT>576 _CntrlBlk;577 __cntrl_ = new _CntrlBlk(__r.get(), std::ref(__r.get_deleter()), _AllocT());578 __enable_weak_this(__r.get(), __r.get());579 }580 __r.release();581 }582 583 _LIBCPP_HIDE_FROM_ABI ~shared_ptr() {584 if (__cntrl_)585 __cntrl_->__release_shared();586 }587 588 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(const shared_ptr& __r) _NOEXCEPT {589 shared_ptr(__r).swap(*this);590 return *this;591 }592 593 template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0>594 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT {595 shared_ptr(__r).swap(*this);596 return *this;597 }598 599 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(shared_ptr&& __r) _NOEXCEPT {600 shared_ptr(std::move(__r)).swap(*this);601 return *this;602 }603 604 template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0>605 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(shared_ptr<_Yp>&& __r) {606 shared_ptr(std::move(__r)).swap(*this);607 return *this;608 }609 610 template <class _Yp,611 __enable_if_t<!is_array<_Yp>::value && is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,612 int> = 0>613 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(auto_ptr<_Yp>&& __r) {614 shared_ptr(std::move(__r)).swap(*this);615 return *this;616 }617 618 template <class _Yp,619 class _Dp,620 __enable_if_t<_And< __compatible_with<_Yp, _Tp>,621 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*> >::value,622 int> = 0>623 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(unique_ptr<_Yp, _Dp>&& __r) {624 shared_ptr(std::move(__r)).swap(*this);625 return *this;626 }627 628 _LIBCPP_HIDE_FROM_ABI void swap(shared_ptr& __r) _NOEXCEPT {629 std::swap(__ptr_, __r.__ptr_);630 std::swap(__cntrl_, __r.__cntrl_);631 }632 633 _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT { shared_ptr().swap(*this); }634 635 template <class _Yp, __enable_if_t<__raw_pointer_compatible_with<_Yp, _Tp>::value, int> = 0>636 _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p) {637 shared_ptr(__p).swap(*this);638 }639 640 template <class _Yp, class _Dp, __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0>641 _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p, _Dp __d) {642 shared_ptr(__p, __d).swap(*this);643 }644 645 template <class _Yp,646 class _Dp,647 class _Alloc,648 __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0>649 _LIBCPP_HIDE_FROM_ABI void reset(_Yp* __p, _Dp __d, _Alloc __a) {650 shared_ptr(__p, __d, __a).swap(*this);651 }652 653 _LIBCPP_HIDE_FROM_ABI element_type* get() const _NOEXCEPT { return __ptr_; }654 655 _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<element_type> operator*() const _NOEXCEPT { return *__ptr_; }656 657 _LIBCPP_HIDE_FROM_ABI element_type* operator->() const _NOEXCEPT {658 static_assert(!is_array<_Tp>::value, "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");659 return __ptr_;660 }661 662 _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; }663 664 _LIBCPP_HIDE_FROM_ABI bool unique() const _NOEXCEPT { return use_count() == 1; }665 666 _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return get() != nullptr; }667 668 template <class _Up>669 _LIBCPP_HIDE_FROM_ABI bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT {670 return __cntrl_ < __p.__cntrl_;671 }672 673 template <class _Up>674 _LIBCPP_HIDE_FROM_ABI bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT {675 return __cntrl_ < __p.__cntrl_;676 }677 678 _LIBCPP_HIDE_FROM_ABI bool __owner_equivalent(const shared_ptr& __p) const { return __cntrl_ == __p.__cntrl_; }679 680#ifndef _LIBCPP_HAS_NO_RTTI681 template <class _Dp>682 _LIBCPP_HIDE_FROM_ABI _Dp* __get_deleter() const _NOEXCEPT {683 return static_cast<_Dp*>(__cntrl_ ? const_cast<void*>(__cntrl_->__get_deleter(typeid(_Dp))) : nullptr);684 }685#endif // _LIBCPP_HAS_NO_RTTI686 687 template <class _Yp, class _CntrlBlk>688 _LIBCPP_HIDE_FROM_ABI static shared_ptr<_Tp> __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT {689 shared_ptr<_Tp> __r;690 __r.__ptr_ = __p;691 __r.__cntrl_ = __cntrl;692 __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);693 return __r;694 }695 696private:697 template <class _Yp, bool = is_function<_Yp>::value>698 struct __shared_ptr_default_allocator {699 typedef allocator<__remove_cv_t<_Yp> > type;700 };701 702 template <class _Yp>703 struct __shared_ptr_default_allocator<_Yp, true> {704 typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;705 };706 707 template <class _Yp,708 class _OrigPtr,709 __enable_if_t<is_convertible<_OrigPtr*, const enable_shared_from_this<_Yp>*>::value, int> = 0>710 _LIBCPP_HIDE_FROM_ABI void __enable_weak_this(const enable_shared_from_this<_Yp>* __e, _OrigPtr* __ptr) _NOEXCEPT {711 typedef __remove_cv_t<_Yp> _RawYp;712 if (__e && __e->__weak_this_.expired()) {713 __e->__weak_this_ = shared_ptr<_RawYp>(*this, const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));714 }715 }716 717 _LIBCPP_HIDE_FROM_ABI void __enable_weak_this(...) _NOEXCEPT {}718 719 template <class, class _Yp>720 struct __shared_ptr_default_delete : default_delete<_Yp> {};721 722 template <class _Yp, class _Un, size_t _Sz>723 struct __shared_ptr_default_delete<_Yp[_Sz], _Un> : default_delete<_Yp[]> {};724 725 template <class _Yp, class _Un>726 struct __shared_ptr_default_delete<_Yp[], _Un> : default_delete<_Yp[]> {};727 728 template <class _Up>729 friend class _LIBCPP_TEMPLATE_VIS shared_ptr;730 template <class _Up>731 friend class _LIBCPP_TEMPLATE_VIS weak_ptr;732};733 734//735// std::allocate_shared and std::make_shared736//737template <class _Tp, class _Alloc, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>738_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) {739 using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;740 using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;741 __allocation_guard<_ControlBlockAllocator> __guard(__a, 1);742 ::new ((void*)std::addressof(*__guard.__get())) _ControlBlock(__a, std::forward<_Args>(__args)...);743 auto __control_block = __guard.__release_ptr();744 return shared_ptr<_Tp>::__create_with_control_block(745 (*__control_block).__get_elem(), std::addressof(*__control_block));746}747 748template <class _Tp, class... _Args, __enable_if_t<!is_array<_Tp>::value, int> = 0>749_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&&... __args) {750 return std::allocate_shared<_Tp>(allocator<__remove_cv_t<_Tp> >(), std::forward<_Args>(__args)...);751}752 753template <class _Tp, class _Up>754inline _LIBCPP_HIDE_FROM_ABI bool operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {755 return __x.get() == __y.get();756}757 758template <class _Tp, class _Up>759inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {760 return !(__x == __y);761}762 763template <class _Tp, class _Up>764inline _LIBCPP_HIDE_FROM_ABI bool operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {765 typedef typename common_type<_Tp*, _Up*>::type _Vp;766 return less<_Vp>()(__x.get(), __y.get());767}768 769template <class _Tp, class _Up>770inline _LIBCPP_HIDE_FROM_ABI bool operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {771 return __y < __x;772}773 774template <class _Tp, class _Up>775inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {776 return !(__y < __x);777}778 779template <class _Tp, class _Up>780inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT {781 return !(__x < __y);782}783 784template <class _Tp>785inline _LIBCPP_HIDE_FROM_ABI bool operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {786 return !__x;787}788 789template <class _Tp>790inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {791 return !__x;792}793 794template <class _Tp>795inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {796 return static_cast<bool>(__x);797}798 799template <class _Tp>800inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {801 return static_cast<bool>(__x);802}803 804template <class _Tp>805inline _LIBCPP_HIDE_FROM_ABI bool operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {806 return less<typename shared_ptr<_Tp>::element_type*>()(__x.get(), nullptr);807}808 809template <class _Tp>810inline _LIBCPP_HIDE_FROM_ABI bool operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {811 return less<typename shared_ptr<_Tp>::element_type*>()(nullptr, __x.get());812}813 814template <class _Tp>815inline _LIBCPP_HIDE_FROM_ABI bool operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {816 return nullptr < __x;817}818 819template <class _Tp>820inline _LIBCPP_HIDE_FROM_ABI bool operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {821 return __x < nullptr;822}823 824template <class _Tp>825inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {826 return !(nullptr < __x);827}828 829template <class _Tp>830inline _LIBCPP_HIDE_FROM_ABI bool operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {831 return !(__x < nullptr);832}833 834template <class _Tp>835inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT {836 return !(__x < nullptr);837}838 839template <class _Tp>840inline _LIBCPP_HIDE_FROM_ABI bool operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT {841 return !(nullptr < __x);842}843 844template <class _Tp>845inline _LIBCPP_HIDE_FROM_ABI void swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT {846 __x.swap(__y);847}848 849template <class _Tp, class _Up>850inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {851 return shared_ptr<_Tp>(__r, static_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));852}853 854template <class _Tp, class _Up>855inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {856 typedef typename shared_ptr<_Tp>::element_type _ET;857 _ET* __p = dynamic_cast<_ET*>(__r.get());858 return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();859}860 861template <class _Tp, class _Up>862_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {863 typedef typename shared_ptr<_Tp>::element_type _RTp;864 return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));865}866 867template <class _Tp, class _Up>868_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT {869 return shared_ptr<_Tp>(__r, reinterpret_cast< typename shared_ptr<_Tp>::element_type*>(__r.get()));870}871 872#ifndef _LIBCPP_HAS_NO_RTTI873 874template <class _Dp, class _Tp>875inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT {876 return __p.template __get_deleter<_Dp>();877}878 879#endif // _LIBCPP_HAS_NO_RTTI880 881template <class _Tp>882class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr {883public:884 typedef _Tp element_type;885 886 // A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require887 // any bookkeeping, so it's always trivially relocatable.888 using __trivially_relocatable = weak_ptr;889 890private:891 element_type* __ptr_;892 __shared_weak_count* __cntrl_;893 894public:895 _LIBCPP_HIDE_FROM_ABI weak_ptr() _NOEXCEPT;896 897 template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0>898 _LIBCPP_HIDE_FROM_ABI weak_ptr(shared_ptr<_Yp> const& __r) _NOEXCEPT;899 900 _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr const& __r) _NOEXCEPT;901 902 template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0>903 _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr<_Yp> const& __r) _NOEXCEPT;904 905 _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr&& __r) _NOEXCEPT;906 907 template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0>908 _LIBCPP_HIDE_FROM_ABI weak_ptr(weak_ptr<_Yp>&& __r) _NOEXCEPT;909 910 _LIBCPP_HIDE_FROM_ABI ~weak_ptr();911 912 _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;913 template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0>914 _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;915 916 _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;917 template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0>918 _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;919 920 template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> = 0>921 _LIBCPP_HIDE_FROM_ABI weak_ptr& operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;922 923 _LIBCPP_HIDE_FROM_ABI void swap(weak_ptr& __r) _NOEXCEPT;924 _LIBCPP_HIDE_FROM_ABI void reset() _NOEXCEPT;925 926 _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __cntrl_ ? __cntrl_->use_count() : 0; }927 _LIBCPP_HIDE_FROM_ABI bool expired() const _NOEXCEPT { return __cntrl_ == nullptr || __cntrl_->use_count() == 0; }928 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT;929 template <class _Up>930 _LIBCPP_HIDE_FROM_ABI bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT {931 return __cntrl_ < __r.__cntrl_;932 }933 template <class _Up>934 _LIBCPP_HIDE_FROM_ABI bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT {935 return __cntrl_ < __r.__cntrl_;936 }937 938 template <class _Up>939 friend class _LIBCPP_TEMPLATE_VIS weak_ptr;940 template <class _Up>941 friend class _LIBCPP_TEMPLATE_VIS shared_ptr;942};943 944template <class _Tp>945inline weak_ptr<_Tp>::weak_ptr() _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {}946 947template <class _Tp>948inline weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {949 if (__cntrl_)950 __cntrl_->__add_weak();951}952 953template <class _Tp>954template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> >955inline weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {956 if (__cntrl_)957 __cntrl_->__add_weak();958}959 960template <class _Tp>961template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> >962inline weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r) _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {963 shared_ptr<_Yp> __s = __r.lock();964 *this = weak_ptr<_Tp>(__s);965}966 967template <class _Tp>968inline weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT : __ptr_(__r.__ptr_), __cntrl_(__r.__cntrl_) {969 __r.__ptr_ = nullptr;970 __r.__cntrl_ = nullptr;971}972 973template <class _Tp>974template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> >975inline weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r) _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {976 shared_ptr<_Yp> __s = __r.lock();977 *this = weak_ptr<_Tp>(__s);978 __r.reset();979}980 981template <class _Tp>982weak_ptr<_Tp>::~weak_ptr() {983 if (__cntrl_)984 __cntrl_->__release_weak();985}986 987template <class _Tp>988inline weak_ptr<_Tp>& weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT {989 weak_ptr(__r).swap(*this);990 return *this;991}992 993template <class _Tp>994template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> >995inline weak_ptr<_Tp>& weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT {996 weak_ptr(__r).swap(*this);997 return *this;998}999 1000template <class _Tp>1001inline weak_ptr<_Tp>& weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT {1002 weak_ptr(std::move(__r)).swap(*this);1003 return *this;1004}1005 1006template <class _Tp>1007template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> >1008inline weak_ptr<_Tp>& weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT {1009 weak_ptr(std::move(__r)).swap(*this);1010 return *this;1011}1012 1013template <class _Tp>1014template <class _Yp, __enable_if_t<__compatible_with<_Yp, _Tp>::value, int> >1015inline weak_ptr<_Tp>& weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT {1016 weak_ptr(__r).swap(*this);1017 return *this;1018}1019 1020template <class _Tp>1021inline void weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT {1022 std::swap(__ptr_, __r.__ptr_);1023 std::swap(__cntrl_, __r.__cntrl_);1024}1025 1026template <class _Tp>1027inline _LIBCPP_HIDE_FROM_ABI void swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT {1028 __x.swap(__y);1029}1030 1031template <class _Tp>1032inline void weak_ptr<_Tp>::reset() _NOEXCEPT {1033 weak_ptr().swap(*this);1034}1035 1036template <class _Tp>1037shared_ptr<_Tp> weak_ptr<_Tp>::lock() const _NOEXCEPT {1038 shared_ptr<_Tp> __r;1039 __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;1040 if (__r.__cntrl_)1041 __r.__ptr_ = __ptr_;1042 return __r;1043}1044 1045template <class _Tp>1046struct owner_less;1047 1048template <class _Tp>1049struct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> > : __binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool> {1050 _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT {1051 return __x.owner_before(__y);1052 }1053 _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT {1054 return __x.owner_before(__y);1055 }1056 _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT {1057 return __x.owner_before(__y);1058 }1059};1060 1061template <class _Tp>1062struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> > : __binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool> {1063 _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT {1064 return __x.owner_before(__y);1065 }1066 _LIBCPP_HIDE_FROM_ABI bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPT {1067 return __x.owner_before(__y);1068 }1069 _LIBCPP_HIDE_FROM_ABI bool operator()(weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT {1070 return __x.owner_before(__y);1071 }1072};1073 1074template <class _Tp>1075class _LIBCPP_TEMPLATE_VIS enable_shared_from_this {1076 mutable weak_ptr<_Tp> __weak_this_;1077 1078protected:1079 _LIBCPP_HIDE_FROM_ABI enable_shared_from_this() _NOEXCEPT {}1080 _LIBCPP_HIDE_FROM_ABI enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}1081 _LIBCPP_HIDE_FROM_ABI enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT { return *this; }1082 _LIBCPP_HIDE_FROM_ABI ~enable_shared_from_this() {}1083 1084public:1085 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(__weak_this_); }1086 _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp const> shared_from_this() const { return shared_ptr<const _Tp>(__weak_this_); }1087 1088 template <class _Up>1089 friend class shared_ptr;1090};1091 1092template <class _Tp>1093struct _LIBCPP_TEMPLATE_VIS hash;1094 1095template <class _Tp>1096struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> > {1097 typedef shared_ptr<_Tp> argument_type;1098 typedef size_t result_type;1099 1100 _LIBCPP_HIDE_FROM_ABI size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPT {1101 return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());1102 }1103};1104 1105template <class _CharT, class _Traits, class _Yp>1106inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&1107operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);1108 1109#if !defined(_LIBCPP_HAS_NO_THREADS)1110 1111class _LIBCPP_EXPORTED_FROM_ABI __sp_mut {1112 void* __lx_;1113 1114public:1115 void lock() _NOEXCEPT;1116 void unlock() _NOEXCEPT;1117 1118private:1119 __sp_mut(void*) _NOEXCEPT;1120 __sp_mut(const __sp_mut&);1121 __sp_mut& operator=(const __sp_mut&);1122 1123 friend _LIBCPP_EXPORTED_FROM_ABI __sp_mut& __get_sp_mut(const void*);1124};1125 1126_LIBCPP_EXPORTED_FROM_ABI __sp_mut& __get_sp_mut(const void*);1127 1128template <class _Tp>1129inline _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const shared_ptr<_Tp>*) {1130 return false;1131}1132 1133template <class _Tp>1134_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p) {1135 __sp_mut& __m = std::__get_sp_mut(__p);1136 __m.lock();1137 shared_ptr<_Tp> __q = *__p;1138 __m.unlock();1139 return __q;1140}1141 1142template <class _Tp>1143inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order) {1144 return std::atomic_load(__p);1145}1146 1147template <class _Tp>1148_LIBCPP_HIDE_FROM_ABI void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) {1149 __sp_mut& __m = std::__get_sp_mut(__p);1150 __m.lock();1151 __p->swap(__r);1152 __m.unlock();1153}1154 1155template <class _Tp>1156inline _LIBCPP_HIDE_FROM_ABI void atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) {1157 std::atomic_store(__p, __r);1158}1159 1160template <class _Tp>1161_LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) {1162 __sp_mut& __m = std::__get_sp_mut(__p);1163 __m.lock();1164 __p->swap(__r);1165 __m.unlock();1166 return __r;1167}1168 1169template <class _Tp>1170inline _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>1171atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) {1172 return std::atomic_exchange(__p, __r);1173}1174 1175template <class _Tp>1176_LIBCPP_HIDE_FROM_ABI bool1177atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) {1178 shared_ptr<_Tp> __temp;1179 __sp_mut& __m = std::__get_sp_mut(__p);1180 __m.lock();1181 if (__p->__owner_equivalent(*__v)) {1182 std::swap(__temp, *__p);1183 *__p = __w;1184 __m.unlock();1185 return true;1186 }1187 std::swap(__temp, *__v);1188 *__v = *__p;1189 __m.unlock();1190 return false;1191}1192 1193template <class _Tp>1194inline _LIBCPP_HIDE_FROM_ABI bool1195atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) {1196 return std::atomic_compare_exchange_strong(__p, __v, __w);1197}1198 1199template <class _Tp>1200inline _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit(1201 shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w, memory_order, memory_order) {1202 return std::atomic_compare_exchange_strong(__p, __v, __w);1203}1204 1205template <class _Tp>1206inline _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit(1207 shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w, memory_order, memory_order) {1208 return std::atomic_compare_exchange_weak(__p, __v, __w);1209}1210 1211#endif // !defined(_LIBCPP_HAS_NO_THREADS)1212 1213_LIBCPP_END_NAMESPACE_STD1214 1215_LIBCPP_POP_MACROS1216 1217#endif // _LIBCPP___CXX03___MEMORY_SHARED_PTR_H1218