[libcxx-commits] [libcxx] [libc++][NFC] Use `if constexpr` instead of SFINAE to simplify shared_ptr (PR #113495)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Oct 23 14:18:11 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Louis Dionne (ldionne)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/113495.diff


1 Files Affected:

- (modified) libcxx/include/__memory/shared_ptr.h (+18-29) 


``````````diff
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 65870ba574c25b..080ced077b7338 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -252,22 +252,17 @@ template <class _Tp, class _Alloc>
 struct __shared_ptr_emplace : __shared_weak_count {
   using __value_type = __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>
+  template <class... _Args>
   _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 (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, __value_type>::type;
-    _TpAlloc __tmp(*__get_alloc());
-    allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), std::forward<_Args>(__args)...);
+    if constexpr (is_same<typename _Alloc::value_type, __for_overwrite_tag>::value) {
+      static_assert(
+          sizeof...(_Args) == 0, "No argument should be provided to the control block when using _for_overwrite");
+      ::new (static_cast<void*>(__get_elem())) __value_type;
+    } else {
+      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(); }
@@ -275,22 +270,16 @@ struct __shared_ptr_emplace : __shared_weak_count {
   _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()->~__value_type();
-  }
-
-  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 {
-    using _TpAlloc = typename __allocator_traits_rebind<_Allocator, __remove_cv_t<_Tp> >::type;
-    _TpAlloc __tmp(*__get_alloc());
-    allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
+  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override {
+    if constexpr (is_same<typename _Alloc::value_type, __for_overwrite_tag>::value) {
+      __get_elem()->~__value_type();
+    } else {
+      using _TpAlloc = typename __allocator_traits_rebind<_Alloc, __remove_cv_t<_Tp> >::type;
+      _TpAlloc __tmp(*__get_alloc());
+      allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
+    }
   }
 
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { __on_zero_shared_impl(); }
-
   _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override {
     using _ControlBlockAlloc   = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
     using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;

``````````

</details>


https://github.com/llvm/llvm-project/pull/113495


More information about the libcxx-commits mailing list