[libcxx-commits] [libcxx] [libc++] Implement the public invoke API in terms of the libc++-internal API (PR #146334)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 2 07:47:26 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

<details>
<summary>Changes</summary>

This adds one additional variable template to the libc++-internal API. This allows us to implement the public API once instead of twice.


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


1 Files Affected:

- (modified) libcxx/include/__type_traits/invoke.h (+40-74) 


``````````diff
diff --git a/libcxx/include/__type_traits/invoke.h b/libcxx/include/__type_traits/invoke.h
index ac38b32b0cd76..5ff2efbe5faaf 100644
--- a/libcxx/include/__type_traits/invoke.h
+++ b/libcxx/include/__type_traits/invoke.h
@@ -42,19 +42,22 @@
 //   return std::invoke_r(std::forward<Args>(args)...);
 // }
 //
-// template <class Ret, class Func, class... Args>
-// inline const bool __is_invocable_r_v = is_invocable_r_v<Ret, Func, Args...>;
-//
 // template <class Func, class... Args>
 // struct __is_invocable : is_invocable<Func, Args...> {};
 //
 // template <class Func, class... Args>
 // inline const bool __is_invocable_v = is_invocable_v<Func, Args...>;
 //
+// template <class Ret, class Func, class... Args>
+// inline const bool __is_invocable_r_v = is_invocable_r_v<Ret, Func, Args...>;
+//
 // template <class Func, class... Args>
 // inline const bool __is_nothrow_invocable_v = is_nothrow_invocable_v<Func, Args...>;
 //
 // template <class Func, class... Args>
+// inline const bool __is_nothrow_invocable_r_v = is_nothrow_invocable_r_v<Func, Args...>;
+//
+// template <class Func, class... Args>
 // struct __invoke_result : invoke_result {};
 //
 // template <class Func, class... Args>
@@ -126,46 +129,6 @@ template <class _Ret, class... _Args>
 inline const bool __is_nothrow_invocable_r_v =
     __is_nothrow_invocable_r_impl<__is_nothrow_invocable_v<_Args...>, _Ret, _Args...>;
 
-#  if _LIBCPP_STD_VER >= 17
-
-// is_invocable
-
-template <class _Fn, class... _Args>
-struct _LIBCPP_NO_SPECIALIZATIONS is_invocable : bool_constant<__is_invocable_v<_Fn, _Args...> > {};
-
-template <class _Ret, class _Fn, class... _Args>
-struct _LIBCPP_NO_SPECIALIZATIONS is_invocable_r : bool_constant<__is_invocable_r_v<_Ret, _Fn, _Args...>> {};
-
-template <class _Fn, class... _Args>
-_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_invocable_v = __is_invocable_v<_Fn, _Args...>;
-
-template <class _Ret, class _Fn, class... _Args>
-_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
-
-// is_nothrow_invocable
-
-template <class _Fn, class... _Args>
-struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_invocable : bool_constant<__is_nothrow_invocable_v<_Fn, _Args...> > {};
-
-template <class _Ret, class _Fn, class... _Args>
-struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_invocable_r
-    : integral_constant<bool, __is_nothrow_invocable_r_v<_Ret, _Fn, _Args...>> {};
-
-template <class _Fn, class... _Args>
-_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_invocable_v = __is_nothrow_invocable_v<_Fn, _Args...>;
-
-template <class _Ret, class _Fn, class... _Args>
-_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_invocable_r_v =
-    __is_nothrow_invocable_r_v<_Ret, _Fn, _Args...>;
-
-template <class _Fn, class... _Args>
-struct _LIBCPP_NO_SPECIALIZATIONS invoke_result : __invoke_result<_Fn, _Args...> {};
-
-template <class _Fn, class... _Args>
-using invoke_result_t = __invoke_result_t<_Fn, _Args...>;
-
-#  endif // _LIBCPP_STD_VER >= 17
-
 #else // __has_builtin(__builtin_invoke)
 
 template <class _DecayedFp>
@@ -352,6 +315,9 @@ inline const bool __is_invocable_r_v = __invokable_r<_Ret, _Func, _Args...>::val
 template <class _Func, class... _Args>
 inline const bool __is_nothrow_invocable_v = __nothrow_invokable<_Func, _Args...>::value;
 
+template <class _Ret, class _Func, class... _Args>
+inline const bool __is_nothrow_invocable_r_v = __nothrow_invokable_r<_Ret, _Func, _Args...>::value;
+
 template <class _Func, class... _Args>
 struct __invoke_result
     : enable_if<__is_invocable_v<_Func, _Args...>, typename __invokable_r<void, _Func, _Args...>::_Result> {};
@@ -359,12 +325,35 @@ struct __invoke_result
 template <class _Func, class... _Args>
 using __invoke_result_t _LIBCPP_NODEBUG = typename __invoke_result<_Func, _Args...>::type;
 
-#  if _LIBCPP_STD_VER >= 17
+#endif // __has_builtin(__builtin_invoke_r)
+
+template <class _Ret, bool = is_void<_Ret>::value>
+struct __invoke_void_return_wrapper {
+  template <class... _Args>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static _Ret __call(_Args&&... __args) {
+    return std::__invoke(std::forward<_Args>(__args)...);
+  }
+};
+
+template <class _Ret>
+struct __invoke_void_return_wrapper<_Ret, true> {
+  template <class... _Args>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void __call(_Args&&... __args) {
+    std::__invoke(std::forward<_Args>(__args)...);
+  }
+};
+
+template <class _Ret, class... _Args>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Ret __invoke_r(_Args&&... __args) {
+  return __invoke_void_return_wrapper<_Ret>::__call(std::forward<_Args>(__args)...);
+}
+
+#if _LIBCPP_STD_VER >= 17
 
 // is_invocable
 
 template <class _Fn, class... _Args>
-struct _LIBCPP_NO_SPECIALIZATIONS is_invocable : bool_constant<__is_invocable_v<_Fn, _Args...>> {};
+struct _LIBCPP_NO_SPECIALIZATIONS is_invocable : bool_constant<__is_invocable_v<_Fn, _Args...> > {};
 
 template <class _Ret, class _Fn, class... _Args>
 struct _LIBCPP_NO_SPECIALIZATIONS is_invocable_r : bool_constant<__is_invocable_r_v<_Ret, _Fn, _Args...>> {};
@@ -378,49 +367,26 @@ _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_invocable_r_v = __is_invocab
 // is_nothrow_invocable
 
 template <class _Fn, class... _Args>
-struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_invocable : bool_constant<__nothrow_invokable<_Fn, _Args...>::value> {};
+struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_invocable : bool_constant<__is_nothrow_invocable_v<_Fn, _Args...> > {};
 
 template <class _Ret, class _Fn, class... _Args>
 struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_invocable_r
-    : bool_constant<__nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {};
+    : bool_constant<__is_nothrow_invocable_r_v<_Ret, _Fn, _Args...>> {};
 
 template <class _Fn, class... _Args>
-_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
+_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_invocable_v = __is_nothrow_invocable_v<_Fn, _Args...>;
 
 template <class _Ret, class _Fn, class... _Args>
 _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_invocable_r_v =
-    is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
+    __is_nothrow_invocable_r_v<_Ret, _Fn, _Args...>;
 
 template <class _Fn, class... _Args>
 struct _LIBCPP_NO_SPECIALIZATIONS invoke_result : __invoke_result<_Fn, _Args...> {};
 
 template <class _Fn, class... _Args>
-using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
-
-#  endif // _LIBCPP_STD_VER >= 17
-
-#endif // __has_builtin(__builtin_invoke_r)
-
-template <class _Ret, bool = is_void<_Ret>::value>
-struct __invoke_void_return_wrapper {
-  template <class... _Args>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static _Ret __call(_Args&&... __args) {
-    return std::__invoke(std::forward<_Args>(__args)...);
-  }
-};
-
-template <class _Ret>
-struct __invoke_void_return_wrapper<_Ret, true> {
-  template <class... _Args>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void __call(_Args&&... __args) {
-    std::__invoke(std::forward<_Args>(__args)...);
-  }
-};
+using invoke_result_t = __invoke_result_t<_Fn, _Args...>;
 
-template <class _Ret, class... _Args>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Ret __invoke_r(_Args&&... __args) {
-  return __invoke_void_return_wrapper<_Ret>::__call(std::forward<_Args>(__args)...);
-}
+#endif
 
 _LIBCPP_END_NAMESPACE_STD
 

``````````

</details>


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


More information about the libcxx-commits mailing list