Skip to content

Commit b66bb69

Browse files
committed
[libc++][NFC] Use if constexpr instead of SFINAE to simplify shared_ptr
Since we can use `if constexpr` in all standard modes (it is supported as a compiler extension), we can simplify the implementation of __shared_ptr_emplace.
1 parent d269ec3 commit b66bb69

File tree

1 file changed

+18
-29
lines changed

1 file changed

+18
-29
lines changed

libcxx/include/__memory/shared_ptr.h

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -252,45 +252,34 @@ template <class _Tp, class _Alloc>
252252
struct __shared_ptr_emplace : __shared_weak_count {
253253
using __value_type = __remove_cv_t<_Tp>;
254254

255-
template <class... _Args,
256-
class _Allocator = _Alloc,
257-
__enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
255+
template <class... _Args>
258256
_LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&...) : __storage_(std::move(__a)) {
259-
static_assert(
260-
sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");
261-
::new (static_cast<void*>(__get_elem())) __value_type;
262-
}
263-
264-
template <class... _Args,
265-
class _Allocator = _Alloc,
266-
__enable_if_t<!is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
267-
_LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&&... __args) : __storage_(std::move(__a)) {
268-
using _TpAlloc = typename __allocator_traits_rebind<_Alloc, __value_type>::type;
269-
_TpAlloc __tmp(*__get_alloc());
270-
allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), std::forward<_Args>(__args)...);
257+
if constexpr (is_same<typename _Alloc::value_type, __for_overwrite_tag>::value) {
258+
static_assert(
259+
sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");
260+
::new (static_cast<void*>(__get_elem())) __value_type;
261+
} else {
262+
using _TpAlloc = typename __allocator_traits_rebind<_Alloc, __value_type>::type;
263+
_TpAlloc __tmp(*__get_alloc());
264+
allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), std::forward<_Args>(__args)...);
265+
}
271266
}
272267

273268
_LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
274269

275270
_LIBCPP_HIDE_FROM_ABI __value_type* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
276271

277272
private:
278-
template <class _Allocator = _Alloc,
279-
__enable_if_t<is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
280-
_LIBCPP_HIDE_FROM_ABI void __on_zero_shared_impl() _NOEXCEPT {
281-
__get_elem()->~__value_type();
282-
}
283-
284-
template <class _Allocator = _Alloc,
285-
__enable_if_t<!is_same<typename _Allocator::value_type, __for_overwrite_tag>::value, int> = 0>
286-
_LIBCPP_HIDE_FROM_ABI void __on_zero_shared_impl() _NOEXCEPT {
287-
using _TpAlloc = typename __allocator_traits_rebind<_Allocator, __remove_cv_t<_Tp> >::type;
288-
_TpAlloc __tmp(*__get_alloc());
289-
allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
273+
_LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
274+
if constexpr (is_same<typename _Alloc::value_type, __for_overwrite_tag>::value) {
275+
__get_elem()->~__value_type();
276+
} else {
277+
using _TpAlloc = typename __allocator_traits_rebind<_Alloc, __remove_cv_t<_Tp> >::type;
278+
_TpAlloc __tmp(*__get_alloc());
279+
allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
280+
}
290281
}
291282

292-
_LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { __on_zero_shared_impl(); }
293-
294283
_LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
295284
using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
296285
using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;

0 commit comments

Comments
 (0)