-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[libc++] Implement the public invoke API in terms of the libc++-internal API #146334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
philnik777
wants to merge
1
commit into
llvm:main
Choose a base branch
from
philnik777:merge_invoke_api
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
EricWF
reviewed
Jun 30, 2025
4e896ea
to
4fa7a86
Compare
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesThis 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:
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
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This adds one additional variable template to the libc++-internal API. This allows us to implement the public API once instead of twice.