aboutsummaryrefslogtreecommitdiff
path: root/lib/libcxx/include/__memory/shared_ptr.h
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-04-05 01:46:13 -0400
committerGitHub <noreply@github.com>2025-04-05 01:46:13 -0400
commit0cd31fc7ff157551cfbba5da35cd79f118d2a2e3 (patch)
treea308488f5d85184c8ec402fb3f55f1cf2704443e /lib/libcxx/include/__memory/shared_ptr.h
parent8acedfd5baabab705946ad097746f9183ef62420 (diff)
parentcefe65c1b8abe65a22d4b68410db1be264fdeda0 (diff)
downloadzig-0cd31fc7ff157551cfbba5da35cd79f118d2a2e3.tar.gz
zig-0cd31fc7ff157551cfbba5da35cd79f118d2a2e3.zip
Merge pull request #22780 from ziglang/llvm20
LLVM 20
Diffstat (limited to 'lib/libcxx/include/__memory/shared_ptr.h')
-rw-r--r--lib/libcxx/include/__memory/shared_ptr.h244
1 files changed, 67 insertions, 177 deletions
diff --git a/lib/libcxx/include/__memory/shared_ptr.h b/lib/libcxx/include/__memory/shared_ptr.h
index d487e4fbe3..06b1fc488c 100644
--- a/lib/libcxx/include/__memory/shared_ptr.h
+++ b/lib/libcxx/include/__memory/shared_ptr.h
@@ -13,6 +13,8 @@
#include <__compare/compare_three_way.h>
#include <__compare/ordering.h>
#include <__config>
+#include <__cstddef/nullptr_t.h>
+#include <__cstddef/ptrdiff_t.h>
#include <__exception/exception.h>
#include <__functional/binary_function.h>
#include <__functional/operations.h>
@@ -28,20 +30,26 @@
#include <__memory/compressed_pair.h>
#include <__memory/construct_at.h>
#include <__memory/pointer_traits.h>
+#include <__memory/shared_count.h>
#include <__memory/uninitialized_algorithms.h>
#include <__memory/unique_ptr.h>
#include <__type_traits/add_lvalue_reference.h>
#include <__type_traits/conditional.h>
#include <__type_traits/conjunction.h>
#include <__type_traits/disjunction.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
#include <__type_traits/is_array.h>
#include <__type_traits/is_bounded_array.h>
#include <__type_traits/is_constructible.h>
#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_function.h>
#include <__type_traits/is_reference.h>
+#include <__type_traits/is_same.h>
#include <__type_traits/is_unbounded_array.h>
#include <__type_traits/nat.h>
#include <__type_traits/negation.h>
+#include <__type_traits/remove_cv.h>
#include <__type_traits/remove_extent.h>
#include <__type_traits/remove_reference.h>
#include <__utility/declval.h>
@@ -49,10 +57,8 @@
#include <__utility/move.h>
#include <__utility/swap.h>
#include <__verbose_abort>
-#include <cstddef>
-#include <new>
#include <typeinfo>
-#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
+#if _LIBCPP_HAS_ATOMIC_HEADER
# include <__atomic/memory_order.h>
#endif
@@ -65,53 +71,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
-// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
-// should be sufficient for thread safety.
-// See https://llvm.org/PR22803
-#if defined(__clang__) && __has_builtin(__atomic_add_fetch) && defined(__ATOMIC_RELAXED) && defined(__ATOMIC_ACQ_REL)
-# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
-#elif defined(_LIBCPP_COMPILER_GCC)
-# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
-#endif
-
-template <class _ValueType>
-inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_relaxed_load(_ValueType const* __value) {
-#if !defined(_LIBCPP_HAS_NO_THREADS) && defined(__ATOMIC_RELAXED) && \
- (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
- return __atomic_load_n(__value, __ATOMIC_RELAXED);
-#else
- return *__value;
-#endif
-}
-
-template <class _ValueType>
-inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_acquire_load(_ValueType const* __value) {
-#if !defined(_LIBCPP_HAS_NO_THREADS) && defined(__ATOMIC_ACQUIRE) && \
- (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
- return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
-#else
- return *__value;
-#endif
-}
-
-template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT {
-#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
- return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
-#else
- return __t += 1;
-#endif
-}
-
-template <class _Tp>
-inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT {
-#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
- return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
-#else
- return __t -= 1;
-#endif
-}
-
class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr : public std::exception {
public:
_LIBCPP_HIDE_FROM_ABI bad_weak_ptr() _NOEXCEPT = default;
@@ -121,8 +80,8 @@ public:
const char* what() const _NOEXCEPT override;
};
-_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_weak_ptr() {
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+[[__noreturn__]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_weak_ptr() {
+#if _LIBCPP_HAS_EXCEPTIONS
throw bad_weak_ptr();
#else
_LIBCPP_VERBOSE_ABORT("bad_weak_ptr was thrown in -fno-exceptions mode");
@@ -132,79 +91,15 @@ _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_weak_ptr() {
template <class _Tp>
class _LIBCPP_TEMPLATE_VIS weak_ptr;
-class _LIBCPP_EXPORTED_FROM_ABI __shared_count {
- __shared_count(const __shared_count&);
- __shared_count& operator=(const __shared_count&);
-
-protected:
- long __shared_owners_;
- virtual ~__shared_count();
-
-private:
- virtual void __on_zero_shared() _NOEXCEPT = 0;
-
-public:
- _LIBCPP_HIDE_FROM_ABI explicit __shared_count(long __refs = 0) _NOEXCEPT : __shared_owners_(__refs) {}
-
-#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
- void __add_shared() noexcept;
- bool __release_shared() noexcept;
-#else
- _LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_owners_); }
- _LIBCPP_HIDE_FROM_ABI bool __release_shared() _NOEXCEPT {
- if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
- __on_zero_shared();
- return true;
- }
- return false;
- }
-#endif
- _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __libcpp_relaxed_load(&__shared_owners_) + 1; }
-};
-
-class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count : private __shared_count {
- long __shared_weak_owners_;
-
-public:
- _LIBCPP_HIDE_FROM_ABI explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
- : __shared_count(__refs),
- __shared_weak_owners_(__refs) {}
-
-protected:
- ~__shared_weak_count() override;
-
-public:
-#if defined(_LIBCPP_SHARED_PTR_DEFINE_LEGACY_INLINE_FUNCTIONS)
- void __add_shared() noexcept;
- void __add_weak() noexcept;
- void __release_shared() noexcept;
-#else
- _LIBCPP_HIDE_FROM_ABI void __add_shared() _NOEXCEPT { __shared_count::__add_shared(); }
- _LIBCPP_HIDE_FROM_ABI void __add_weak() _NOEXCEPT { __libcpp_atomic_refcount_increment(__shared_weak_owners_); }
- _LIBCPP_HIDE_FROM_ABI void __release_shared() _NOEXCEPT {
- if (__shared_count::__release_shared())
- __release_weak();
- }
-#endif
- void __release_weak() _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI long use_count() const _NOEXCEPT { return __shared_count::use_count(); }
- __shared_weak_count* lock() _NOEXCEPT;
-
- virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
-
-private:
- virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
-};
-
template <class _Tp, class _Dp, class _Alloc>
class __shared_ptr_pointer : public __shared_weak_count {
- __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
+ _LIBCPP_COMPRESSED_TRIPLE(_Tp, __ptr_, _Dp, __deleter_, _Alloc, __alloc_);
public:
_LIBCPP_HIDE_FROM_ABI __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
- : __data_(__compressed_pair<_Tp, _Dp>(__p, std::move(__d)), std::move(__a)) {}
+ : __ptr_(__p), __deleter_(std::move(__d)), __alloc_(std::move(__a)) {}
-#ifndef _LIBCPP_HAS_NO_RTTI
+#if _LIBCPP_HAS_RTTI
_LIBCPP_HIDE_FROM_ABI_VIRTUAL const void* __get_deleter(const type_info&) const _NOEXCEPT override;
#endif
@@ -213,19 +108,19 @@ private:
_LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override;
};
-#ifndef _LIBCPP_HAS_NO_RTTI
+#if _LIBCPP_HAS_RTTI
template <class _Tp, class _Dp, class _Alloc>
const void* __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT {
- return __t == typeid(_Dp) ? std::addressof(__data_.first().second()) : nullptr;
+ return __t == typeid(_Dp) ? std::addressof(__deleter_) : nullptr;
}
-#endif // _LIBCPP_HAS_NO_RTTI
+#endif // _LIBCPP_HAS_RTTI
template <class _Tp, class _Dp, class _Alloc>
void __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT {
- __data_.first().second()(__data_.first().first());
- __data_.first().second().~_Dp();
+ __deleter_(__ptr_);
+ __deleter_.~_Dp();
}
template <class _Tp, class _Dp, class _Alloc>
@@ -234,8 +129,8 @@ void __shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT {
typedef allocator_traits<_Al> _ATraits;
typedef pointer_traits<typename _ATraits::pointer> _PTraits;
- _Al __a(__data_.second());
- __data_.second().~_Alloc();
+ _Al __a(__alloc_);
+ __alloc_.~_Alloc();
__a.deallocate(_PTraits::pointer_to(*this), 1);
}
@@ -246,33 +141,35 @@ struct __for_overwrite_tag {};
template <class _Tp, class _Alloc>
struct __shared_ptr_emplace : __shared_weak_count {
+ using __value_type _LIBCPP_NODEBUG = __remove_cv_t<_Tp>;
+
template <class... _Args,
class _Allocator = _Alloc,
__enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&...) : __storage_(std::move(__a)) {
static_assert(
sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");
- ::new ((void*)__get_elem()) _Tp;
+ ::new (static_cast<void*>(__get_elem())) __value_type;
}
template <class... _Args,
class _Allocator = _Alloc,
__enable_if_t<!is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&... __args) : __storage_(std::move(__a)) {
- using _TpAlloc = typename __allocator_traits_rebind<_Alloc, __remove_cv_t<_Tp> >::type;
+ using _TpAlloc = typename __allocator_traits_rebind<_Alloc, __value_type>::type;
_TpAlloc __tmp(*__get_alloc());
allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), std::forward<_Args>(__args)...);
}
_LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
- _LIBCPP_HIDE_FROM_ABI _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
+ _LIBCPP_HIDE_FROM_ABI __value_type* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
private:
template <class _Allocator = _Alloc,
__enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI void __on_zero_shared_impl() _NOEXCEPT {
- __get_elem()->~_Tp();
+ __get_elem()->~__value_type();
}
template <class _Allocator = _Alloc,
@@ -293,36 +190,28 @@ private:
allocator_traits<_ControlBlockAlloc>::deallocate(__tmp, pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1);
}
+ // TODO: It should be possible to refactor this to remove `_Storage` entirely.
// This class implements the control block for non-array shared pointers created
// through `std::allocate_shared` and `std::make_shared`.
- //
- // In previous versions of the library, we used a compressed pair to store
- // both the _Alloc and the _Tp. This implies using EBO, which is incompatible
- // with Allocator construction for _Tp. To allow implementing P0674 in C++20,
- // we now use a properly aligned char buffer while making sure that we maintain
- // the same layout that we had when we used a compressed pair.
- using _CompressedPair = __compressed_pair<_Alloc, _Tp>;
- struct _ALIGNAS_TYPE(_CompressedPair) _Storage {
- char __blob_[sizeof(_CompressedPair)];
+ struct _Storage {
+ struct _Data {
+ _LIBCPP_COMPRESSED_PAIR(_Alloc, __alloc_, __value_type, __elem_);
+ };
+
+ _ALIGNAS_TYPE(_Data) char __buffer_[sizeof(_Data)];
_LIBCPP_HIDE_FROM_ABI explicit _Storage(_Alloc&& __a) { ::new ((void*)__get_alloc()) _Alloc(std::move(__a)); }
_LIBCPP_HIDE_FROM_ABI ~_Storage() { __get_alloc()->~_Alloc(); }
+
_LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT {
- _CompressedPair* __as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
- typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair);
- _Alloc* __alloc = reinterpret_cast<_Alloc*>(__first);
- return __alloc;
+ return std::addressof(reinterpret_cast<_Data*>(__buffer_)->__alloc_);
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {
- _CompressedPair* __as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
- typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair);
- _Tp* __elem = reinterpret_cast<_Tp*>(__second);
- return __elem;
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI __value_type* __get_elem() _NOEXCEPT {
+ return std::addressof(reinterpret_cast<_Data*>(__buffer_)->__elem_);
}
};
- static_assert(_LIBCPP_ALIGNOF(_Storage) == _LIBCPP_ALIGNOF(_CompressedPair), "");
- static_assert(sizeof(_Storage) == sizeof(_CompressedPair), "");
_Storage __storage_;
};
@@ -404,7 +293,8 @@ struct __shared_ptr_deleter_ctor_reqs {
};
template <class _Dp>
-using __shared_ptr_nullptr_deleter_ctor_reqs = _And<is_move_constructible<_Dp>, __well_formed_deleter<_Dp, nullptr_t> >;
+using __shared_ptr_nullptr_deleter_ctor_reqs _LIBCPP_NODEBUG =
+ _And<is_move_constructible<_Dp>, __well_formed_deleter<_Dp, nullptr_t> >;
#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
@@ -426,7 +316,7 @@ public:
// A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
// any bookkeeping, so it's always trivially relocatable.
- using __trivially_relocatable = shared_ptr;
+ using __trivially_relocatable _LIBCPP_NODEBUG = shared_ptr;
private:
element_type* __ptr_;
@@ -459,9 +349,9 @@ public:
template <class _Yp, class _Dp, __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d) : __ptr_(__p) {
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#if _LIBCPP_HAS_EXCEPTIONS
try {
-#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_EXCEPTIONS
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk;
#ifndef _LIBCPP_CXX03_LANG
@@ -470,12 +360,12 @@ public:
__cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
#endif // not _LIBCPP_CXX03_LANG
__enable_weak_this(__p, __p);
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
__d(__p);
throw;
}
-#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_EXCEPTIONS
}
template <class _Yp,
@@ -483,9 +373,9 @@ public:
class _Alloc,
__enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI shared_ptr(_Yp* __p, _Dp __d, _Alloc __a) : __ptr_(__p) {
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#if _LIBCPP_HAS_EXCEPTIONS
try {
-#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_EXCEPTIONS
typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
typedef __allocator_destructor<_A2> _D2;
@@ -499,12 +389,12 @@ public:
#endif // not _LIBCPP_CXX03_LANG
__cntrl_ = std::addressof(*__hold2.release());
__enable_weak_this(__p, __p);
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
__d(__p);
throw;
}
-#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_EXCEPTIONS
}
template <class _Dp>
@@ -513,9 +403,9 @@ public:
_Dp __d,
__enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs<_Dp>::value, __nullptr_sfinae_tag> = __nullptr_sfinae_tag())
: __ptr_(nullptr) {
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#if _LIBCPP_HAS_EXCEPTIONS
try {
-#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_EXCEPTIONS
typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk;
#ifndef _LIBCPP_CXX03_LANG
@@ -523,12 +413,12 @@ public:
#else
__cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
#endif // not _LIBCPP_CXX03_LANG
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
__d(__p);
throw;
}
-#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_EXCEPTIONS
}
template <class _Dp, class _Alloc>
@@ -538,9 +428,9 @@ public:
_Alloc __a,
__enable_if_t<__shared_ptr_nullptr_deleter_ctor_reqs<_Dp>::value, __nullptr_sfinae_tag> = __nullptr_sfinae_tag())
: __ptr_(nullptr) {
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#if _LIBCPP_HAS_EXCEPTIONS
try {
-#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_EXCEPTIONS
typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
typedef __allocator_destructor<_A2> _D2;
@@ -553,12 +443,12 @@ public:
_CntrlBlk(__p, __d, __a);
#endif // not _LIBCPP_CXX03_LANG
__cntrl_ = std::addressof(*__hold2.release());
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
__d(__p);
throw;
}
-#endif // _LIBCPP_HAS_NO_EXCEPTIONS
+#endif // _LIBCPP_HAS_EXCEPTIONS
}
template <class _Yp>
@@ -771,12 +661,12 @@ public:
}
#endif
-#ifndef _LIBCPP_HAS_NO_RTTI
+#if _LIBCPP_HAS_RTTI
template <class _Dp>
_LIBCPP_HIDE_FROM_ABI _Dp* __get_deleter() const _NOEXCEPT {
return static_cast<_Dp*>(__cntrl_ ? const_cast<void*>(__cntrl_->__get_deleter(typeid(_Dp))) : nullptr);
}
-#endif // _LIBCPP_HAS_NO_RTTI
+#endif // _LIBCPP_HAS_RTTI
template <class _Yp, class _CntrlBlk>
_LIBCPP_HIDE_FROM_ABI static shared_ptr<_Tp> __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT {
@@ -959,7 +849,7 @@ private:
template <class _Array, class _Alloc, class... _Arg>
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Array>
__allocate_shared_unbounded_array(const _Alloc& __a, size_t __n, _Arg&&... __arg) {
- static_assert(__libcpp_is_unbounded_array<_Array>::value);
+ static_assert(__is_unbounded_array_v<_Array>);
// We compute the number of bytes necessary to hold the control block and the
// array elements. Then, we allocate an array of properly-aligned dummy structs
// large enough to hold the control block and array. This allows shifting the
@@ -1036,7 +926,7 @@ private:
template <class _Array, class _Alloc, class... _Arg>
_LIBCPP_HIDE_FROM_ABI shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&&... __arg) {
- static_assert(__libcpp_is_bounded_array<_Array>::value);
+ static_assert(__is_bounded_array_v<_Array>);
using _ControlBlock = __bounded_array_control_block<_Array, _Alloc>;
using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, _ControlBlock>;
@@ -1301,14 +1191,14 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&&
}
#endif
-#ifndef _LIBCPP_HAS_NO_RTTI
+#if _LIBCPP_HAS_RTTI
template <class _Dp, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _Dp* get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT {
return __p.template __get_deleter<_Dp>();
}
-#endif // _LIBCPP_HAS_NO_RTTI
+#endif // _LIBCPP_HAS_RTTI
template <class _Tp>
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr {
@@ -1321,7 +1211,7 @@ public:
// A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
// any bookkeeping, so it's always trivially relocatable.
- using __trivially_relocatable = weak_ptr;
+ using __trivially_relocatable _LIBCPP_NODEBUG = weak_ptr;
private:
element_type* __ptr_;
@@ -1583,7 +1473,7 @@ template <class _CharT, class _Traits, class _Yp>
inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
-#if !defined(_LIBCPP_HAS_NO_THREADS)
+#if _LIBCPP_HAS_THREADS
class _LIBCPP_EXPORTED_FROM_ABI __sp_mut {
void* __lx_;
@@ -1685,7 +1575,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit(
return std::atomic_compare_exchange_weak(__p, __v, __w);
}
-#endif // !defined(_LIBCPP_HAS_NO_THREADS)
+#endif // _LIBCPP_HAS_THREADS
_LIBCPP_END_NAMESPACE_STD