[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