Skip to content

Conversation

@frederick-vs-ja
Copy link
Contributor

@frederick-vs-ja frederick-vs-ja commented Nov 28, 2025

For __has_result_type, it can be replaced with a variable template __has_result_type_v. Note that the pre-existing extraneous * used in detection is buggy, but it's a functional change to fix it.

false_type and true_type are no longer directly used, so direct inclusion of <__type_traits/integral_constant.h> is removed.

For __derives_from_{unary,binary}_function, it's unnecessary to invent a __two type for each specialization. So void is used instead. Also, nullptr is now used instead of 0.

For `__has_result_type`, it can be replaced with a variable template
`__has_result_type_v`. Note that the pre-existing extraneous `*` used in
detection buggy, but it's a functional change to fix it.

`false_type` and `true_type` are no longer directly used, so direct
inclusion of `<__type_traits/integral_constant.h>` is removed.

For `__derives_from_{unary,binary}_function`, it's unnecessary to invent
a `__two` type for each specialization. So `void` is used instead. Also,
`nullptr` is now used instead of `0`.
@frederick-vs-ja frederick-vs-ja requested a review from a team as a code owner November 28, 2025 04:06
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Nov 28, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 28, 2025

@llvm/pr-subscribers-libcxx

Author: A. Jiang (frederick-vs-ja)

Changes

For __has_result_type, it can be replaced with a variable template __has_result_type_v. Note that the pre-existing extraneous * used in detection buggy, but it's a functional change to fix it.

false_type and true_type are no longer directly used, so direct inclusion of &lt;__type_traits/integral_constant.h&gt; is removed.

For __derives_from_{unary,binary}_function, it's unnecessary to invent a __two type for each specialization. So void is used instead. Also, nullptr is now used instead of 0.


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

1 Files Affected:

  • (modified) libcxx/include/__functional/weak_result_type.h (+14-28)
diff --git a/libcxx/include/__functional/weak_result_type.h b/libcxx/include/__functional/weak_result_type.h
index aa462e4d5c56f..4232bdc69dd00 100644
--- a/libcxx/include/__functional/weak_result_type.h
+++ b/libcxx/include/__functional/weak_result_type.h
@@ -13,9 +13,9 @@
 #include <__config>
 #include <__functional/binary_function.h>
 #include <__functional/unary_function.h>
-#include <__type_traits/integral_constant.h>
 #include <__type_traits/invoke.h>
 #include <__type_traits/is_same.h>
+#include <__type_traits/void_t.h>
 #include <__utility/declval.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -24,50 +24,36 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _Tp>
-struct __has_result_type {
-private:
-  template <class _Up>
-  static false_type __test(...);
-  template <class _Up>
-  static true_type __test(typename _Up::result_type* = 0);
+template <class _Tp, class = void>
+inline const bool __has_result_type_v = false;
 
-public:
-  static const bool value = decltype(__test<_Tp>(0))::value;
-};
+template <class _Tp>
+inline const bool __has_result_type_v<_Tp, __void_t<typename _Tp::result_type*> > = true;
 
 // __weak_result_type
 
 template <class _Tp>
 struct __derives_from_unary_function {
 private:
-  struct __two {
-    char __lx;
-    char __lxx;
-  };
-  static __two __test(...);
+  static void __find_base(...);
   template <class _Ap, class _Rp>
-  static __unary_function<_Ap, _Rp> __test(const volatile __unary_function<_Ap, _Rp>*);
+  static __unary_function<_Ap, _Rp> __find_base(const volatile __unary_function<_Ap, _Rp>*);
 
 public:
-  static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
-  typedef decltype(__test((_Tp*)0)) type;
+  using type              = decltype(__find_base(static_cast<_Tp*>(nullptr)));
+  static const bool value = !is_same<type, void>::value;
 };
 
 template <class _Tp>
 struct __derives_from_binary_function {
 private:
-  struct __two {
-    char __lx;
-    char __lxx;
-  };
-  static __two __test(...);
+  static void __find_base(...);
   template <class _A1, class _A2, class _Rp>
-  static __binary_function<_A1, _A2, _Rp> __test(const volatile __binary_function<_A1, _A2, _Rp>*);
+  static __binary_function<_A1, _A2, _Rp> __find_base(const volatile __binary_function<_A1, _A2, _Rp>*);
 
 public:
-  static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
-  typedef decltype(__test((_Tp*)0)) type;
+  using type              = decltype(__find_base(static_cast<_Tp*>(nullptr)));
+  static const bool value = !is_same<type, void>::value;
 };
 
 template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
@@ -85,7 +71,7 @@ struct __maybe_derive_from_binary_function // bool is true
 template <class _Tp>
 struct __maybe_derive_from_binary_function<_Tp, false> {};
 
-template <class _Tp, bool = __has_result_type<_Tp>::value>
+template <class _Tp, bool = __has_result_type_v<_Tp> >
 struct __weak_result_type_imp // bool is true
     : public __maybe_derive_from_unary_function<_Tp>,
       public __maybe_derive_from_binary_function<_Tp> {

Copy link
Contributor

@philnik777 philnik777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@frederick-vs-ja frederick-vs-ja merged commit 7415a7f into llvm:main Nov 28, 2025
82 checks passed
@frederick-vs-ja frederick-vs-ja deleted the tweak-weak-result-type-sfinae branch November 28, 2025 10:55
aahrun pushed a commit to aahrun/llvm-project that referenced this pull request Dec 1, 2025
…m#169870)

For `__has_result_type`, it can be replaced with a variable template
`__has_result_type_v`. Note that the pre-existing extraneous `*` used in
detection is buggy, but it's a functional change to fix it.

`false_type` and `true_type` are no longer directly used, so direct
inclusion of `<__type_traits/integral_constant.h>` is removed.

For `__derives_from_{unary,binary}_function`, it's unnecessary to invent
a `__two` type for each specialization. So `void` is used instead. Also,
`nullptr` is now used instead of `0`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants