From 7519eb127c6a0d392f75bbec4bb9d220ddd1d372 Mon Sep 17 00:00:00 2001 From: Andreas Rohner Date: Tue, 28 Oct 2025 08:50:42 -0700 Subject: [PATCH] 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 --- runtime/function_adapter.h | 41 +++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/runtime/function_adapter.h b/runtime/function_adapter.h index f551a2345..0b97e3515 100644 --- a/runtime/function_adapter.h +++ b/runtime/function_adapter.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -200,10 +201,10 @@ class NullaryFunctionAdapter return std::make_unique(std::move(fn)); } - static std::unique_ptr WrapFunction( - absl::AnyInvocable function) { + template >> + static std::unique_ptr WrapFunction(F&& function) { return WrapFunction( - [function = std::move(function)]( + [function = std::forward(function)]( const google::protobuf::DescriptorPool* absl_nonnull, google::protobuf::MessageFactory* absl_nonnull, google::protobuf::Arena* absl_nonnull) -> T { return function(); }); @@ -276,10 +277,10 @@ class UnaryFunctionAdapter : public RegisterHelper> { return std::make_unique(std::move(fn)); } - static std::unique_ptr WrapFunction( - absl::AnyInvocable function) { + template >> + static std::unique_ptr WrapFunction(F&& function) { return WrapFunction( - [function = std::move(function)]( + [function = std::forward(function)]( U arg1, const google::protobuf::DescriptorPool* absl_nonnull, google::protobuf::MessageFactory* absl_nonnull, google::protobuf::Arena* absl_nonnull) -> T { return function(arg1); }); @@ -406,10 +407,11 @@ class BinaryFunctionAdapter return std::make_unique(std::move(fn)); } - static std::unique_ptr WrapFunction( - absl::AnyInvocable function) { + template >> + static std::unique_ptr WrapFunction(F&& function) { return WrapFunction( - [function = std::move(function)]( + [function = std::forward(function)]( U arg1, V arg2, const google::protobuf::DescriptorPool* absl_nonnull, google::protobuf::MessageFactory* absl_nonnull, google::protobuf::Arena* absl_nonnull) -> T { return function(arg1, arg2); }); @@ -475,9 +477,10 @@ class TernaryFunctionAdapter return std::make_unique(std::move(fn)); } - static std::unique_ptr WrapFunction( - absl::AnyInvocable function) { - return WrapFunction([function = std::move(function)]( + template >> + static std::unique_ptr WrapFunction(F&& function) { + return WrapFunction([function = std::forward(function)]( U arg1, V arg2, W arg3, const google::protobuf::DescriptorPool* absl_nonnull, google::protobuf::MessageFactory* absl_nonnull, @@ -553,9 +556,10 @@ class QuaternaryFunctionAdapter return std::make_unique(std::move(fn)); } - static std::unique_ptr WrapFunction( - absl::AnyInvocable function) { - return WrapFunction([function = std::move(function)]( + template >> + static std::unique_ptr WrapFunction(F&& function) { + return WrapFunction([function = std::forward(function)]( U arg1, V arg2, W arg3, X arg4, const google::protobuf::DescriptorPool* absl_nonnull, google::protobuf::MessageFactory* absl_nonnull, @@ -670,10 +674,11 @@ class NaryFunctionAdapter return std::make_unique(std::move(fn)); } - static std::unique_ptr WrapFunction( - absl::AnyInvocable function) { + template >> + static std::unique_ptr WrapFunction(F&& function) { return WrapFunction( - [function = std::move(function)]( + [function = std::forward(function)]( Args... args, const google::protobuf::DescriptorPool* absl_nonnull, google::protobuf::MessageFactory* absl_nonnull, google::protobuf::Arena* absl_nonnull) -> T { return function(args...); });