internal/utils: performCallback should preserve argument references

Arguments including the function are now passed with reference types
forwarded.

Change-Id: I32cf4704737faa6c140d16352528ceb0d738f5b8
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/sdeventplus/internal/utils.hpp b/src/sdeventplus/internal/utils.hpp
index 193a52c..9d612e5 100644
--- a/src/sdeventplus/internal/utils.hpp
+++ b/src/sdeventplus/internal/utils.hpp
@@ -4,6 +4,7 @@
 #include <chrono>
 #include <cstdio>
 #include <exception>
+#include <functional>
 #include <sdeventplus/exception.hpp>
 #include <stdexcept>
 #include <stdplus/util/cexec.hpp>
@@ -23,12 +24,12 @@
  *  @details A generic wrapper that turns exceptions into
  *           error messages and return codes.
  */
-template <typename Func, typename... Args>
-inline int performCallback(const char* name, Func func, Args... args)
+template <typename... Args>
+inline int performCallback(const char* name, Args&&... args)
 {
     try
     {
-        func(args...);
+        std::invoke(std::forward<Args>(args)...);
         return 0;
     }
     catch (const std::system_error& e)
diff --git a/test/internal/utils.cpp b/test/internal/utils.cpp
index 403964c..8f5d75c 100644
--- a/test/internal/utils.cpp
+++ b/test/internal/utils.cpp
@@ -1,7 +1,10 @@
+#include <functional>
 #include <gtest/gtest.h>
+#include <memory>
 #include <sdeventplus/internal/utils.hpp>
 #include <stdexcept>
 #include <system_error>
+#include <utility>
 
 namespace sdeventplus
 {
@@ -15,6 +18,20 @@
     EXPECT_EQ(0, performCallback(nullptr, []() {}));
 }
 
+TEST(UtilsTest, PerformCallbackAcceptsReference)
+{
+    auto f =
+        std::bind([](const std::unique_ptr<int>&) {}, std::make_unique<int>(1));
+    EXPECT_EQ(0, performCallback(nullptr, f));
+}
+
+TEST(UtilsTest, PerformCallbackAcceptsMove)
+{
+    auto f =
+        std::bind([](const std::unique_ptr<int>&) {}, std::make_unique<int>(1));
+    EXPECT_EQ(0, performCallback(nullptr, std::move(f)));
+}
+
 TEST(UtilsTest, SetPrepareSystemError)
 {
     EXPECT_EQ(-EBUSY, performCallback("system_error", []() {