Skip to content

Commit 7519eb1

Browse files
zeitgeist87copybara-github
authored andcommitted
Use perfect forwarding in the function adapter instead of wrapping it into two layers of absl::AnyInvocable
The current implementation uses a type erased `absl::AnyInvocable` and then wraps it into another `absl::AnyInvocable`, which can be avoided by using a template and perfect forwarding. PiperOrigin-RevId: 825059992
1 parent 6c51dac commit 7519eb1

File tree

1 file changed

+23
-18
lines changed

1 file changed

+23
-18
lines changed

runtime/function_adapter.h

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <functional>
2323
#include <memory>
2424
#include <tuple>
25+
#include <type_traits>
2526
#include <utility>
2627
#include <vector>
2728

@@ -200,10 +201,10 @@ class NullaryFunctionAdapter
200201
return std::make_unique<UnaryFunctionImpl>(std::move(fn));
201202
}
202203

203-
static std::unique_ptr<cel::Function> WrapFunction(
204-
absl::AnyInvocable<T() const> function) {
204+
template <typename F, typename = std::enable_if_t<std::is_invocable_v<F>>>
205+
static std::unique_ptr<cel::Function> WrapFunction(F&& function) {
205206
return WrapFunction(
206-
[function = std::move(function)](
207+
[function = std::forward<F>(function)](
207208
const google::protobuf::DescriptorPool* absl_nonnull,
208209
google::protobuf::MessageFactory* absl_nonnull,
209210
google::protobuf::Arena* absl_nonnull) -> T { return function(); });
@@ -276,10 +277,10 @@ class UnaryFunctionAdapter : public RegisterHelper<UnaryFunctionAdapter<T, U>> {
276277
return std::make_unique<UnaryFunctionImpl>(std::move(fn));
277278
}
278279

279-
static std::unique_ptr<cel::Function> WrapFunction(
280-
absl::AnyInvocable<T(U) const> function) {
280+
template <typename F, typename = std::enable_if_t<std::is_invocable_v<F, U>>>
281+
static std::unique_ptr<cel::Function> WrapFunction(F&& function) {
281282
return WrapFunction(
282-
[function = std::move(function)](
283+
[function = std::forward<F>(function)](
283284
U arg1, const google::protobuf::DescriptorPool* absl_nonnull,
284285
google::protobuf::MessageFactory* absl_nonnull,
285286
google::protobuf::Arena* absl_nonnull) -> T { return function(arg1); });
@@ -406,10 +407,11 @@ class BinaryFunctionAdapter
406407
return std::make_unique<BinaryFunctionImpl>(std::move(fn));
407408
}
408409

409-
static std::unique_ptr<cel::Function> WrapFunction(
410-
absl::AnyInvocable<T(U, V) const> function) {
410+
template <typename F,
411+
typename = std::enable_if_t<std::is_invocable_v<F, U, V>>>
412+
static std::unique_ptr<cel::Function> WrapFunction(F&& function) {
411413
return WrapFunction(
412-
[function = std::move(function)](
414+
[function = std::forward<F>(function)](
413415
U arg1, V arg2, const google::protobuf::DescriptorPool* absl_nonnull,
414416
google::protobuf::MessageFactory* absl_nonnull,
415417
google::protobuf::Arena* absl_nonnull) -> T { return function(arg1, arg2); });
@@ -475,9 +477,10 @@ class TernaryFunctionAdapter
475477
return std::make_unique<TernaryFunctionImpl>(std::move(fn));
476478
}
477479

478-
static std::unique_ptr<cel::Function> WrapFunction(
479-
absl::AnyInvocable<T(U, V, W) const> function) {
480-
return WrapFunction([function = std::move(function)](
480+
template <typename F,
481+
typename = std::enable_if_t<std::is_invocable_v<F, U, V, W>>>
482+
static std::unique_ptr<cel::Function> WrapFunction(F&& function) {
483+
return WrapFunction([function = std::forward<F>(function)](
481484
U arg1, V arg2, W arg3,
482485
const google::protobuf::DescriptorPool* absl_nonnull,
483486
google::protobuf::MessageFactory* absl_nonnull,
@@ -553,9 +556,10 @@ class QuaternaryFunctionAdapter
553556
return std::make_unique<QuaternaryFunctionImpl>(std::move(fn));
554557
}
555558

556-
static std::unique_ptr<cel::Function> WrapFunction(
557-
absl::AnyInvocable<T(U, V, W, X) const> function) {
558-
return WrapFunction([function = std::move(function)](
559+
template <typename F,
560+
typename = std::enable_if_t<std::is_invocable_v<F, U, V, W, X>>>
561+
static std::unique_ptr<cel::Function> WrapFunction(F&& function) {
562+
return WrapFunction([function = std::forward<F>(function)](
559563
U arg1, V arg2, W arg3, X arg4,
560564
const google::protobuf::DescriptorPool* absl_nonnull,
561565
google::protobuf::MessageFactory* absl_nonnull,
@@ -670,10 +674,11 @@ class NaryFunctionAdapter
670674
return std::make_unique<NaryFunctionImpl>(std::move(fn));
671675
}
672676

673-
static std::unique_ptr<cel::Function> WrapFunction(
674-
absl::AnyInvocable<T(Args...) const> function) {
677+
template <typename F,
678+
typename = std::enable_if_t<std::is_invocable_v<F, Args...>>>
679+
static std::unique_ptr<cel::Function> WrapFunction(F&& function) {
675680
return WrapFunction(
676-
[function = std::move(function)](
681+
[function = std::forward<F>(function)](
677682
Args... args, const google::protobuf::DescriptorPool* absl_nonnull,
678683
google::protobuf::MessageFactory* absl_nonnull,
679684
google::protobuf::Arena* absl_nonnull) -> T { return function(args...); });

0 commit comments

Comments
 (0)