summaryrefslogtreecommitdiff
path: root/absl/base/internal
diff options
context:
space:
mode:
authorGravatar Dino Radakovic <dinor@google.com>2022-05-26 08:50:21 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2022-05-26 08:50:58 -0700
commit0bc4bc237786a78e7b00a7c663d53ac81a03ec95 (patch)
treef7d20199a9ceb9a481b34ba1264099cea3d516a0 /absl/base/internal
parent591a2cdacb728f7c4f29782c31d7b694bb3a0782 (diff)
Add implementation of is_invocable_r to absl::base_internal for C++ < 17, define it as alias of std::is_invocable_r when C++ >= 17
PiperOrigin-RevId: 451171660 Change-Id: I6dc0e40eabac72b82c4a19e292158e43118cb080
Diffstat (limited to 'absl/base/internal')
-rw-r--r--absl/base/internal/invoke.h21
1 files changed, 21 insertions, 0 deletions
diff --git a/absl/base/internal/invoke.h b/absl/base/internal/invoke.h
index e9efb2fc..4a644c68 100644
--- a/absl/base/internal/invoke.h
+++ b/absl/base/internal/invoke.h
@@ -49,6 +49,7 @@ namespace base_internal {
using std::invoke;
using std::invoke_result_t;
+using std::is_invocable_r;
} // namespace base_internal
ABSL_NAMESPACE_END
@@ -201,6 +202,26 @@ invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) {
return Invoker<F, Args...>::type::Invoke(std::forward<F>(f),
std::forward<Args>(args)...);
}
+
+template <typename AlwaysVoid, typename, typename, typename...>
+struct IsInvocableRImpl : std::false_type {};
+
+template <typename R, typename F, typename... Args>
+struct IsInvocableRImpl<
+ absl::void_t<absl::base_internal::invoke_result_t<F, Args...> >, R, F,
+ Args...>
+ : std::integral_constant<
+ bool,
+ std::is_convertible<absl::base_internal::invoke_result_t<F, Args...>,
+ R>::value ||
+ std::is_void<R>::value> {};
+
+// Type trait whose member `value` is true if invoking `F` with `Args` is valid,
+// and either the return type is convertible to `R`, or `R` is void.
+// C++11-compatible version of `std::is_invocable_r`.
+template <typename R, typename F, typename... Args>
+using is_invocable_r = IsInvocableRImpl<void, R, F, Args...>;
+
} // namespace base_internal
ABSL_NAMESPACE_END
} // namespace absl