pw_function: Fix for move-only types
- Add std::forward to support move-only function arguments.
- Mark default constructors constexpr.
Change-Id: I505ae0a40919b61ad7be927d19273ab22354f568
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/79501
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Reviewed-by: Alexei Frolov <frolv@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
diff --git a/pw_function/function_test.cc b/pw_function/function_test.cc
index 0c2b89a..541a4c7 100644
--- a/pw_function/function_test.cc
+++ b/pw_function/function_test.cc
@@ -247,6 +247,28 @@
#endif // __clang_analyzer__
}
+TEST(Function, MoveOnlyType) {
+ class MoveOnlyType {
+ public:
+ MoveOnlyType() = default;
+
+ MoveOnlyType(const MoveOnlyType& other) = delete;
+ MoveOnlyType& operator=(const MoveOnlyType& other) = delete;
+
+ MoveOnlyType(MoveOnlyType&&) = default;
+ MoveOnlyType& operator=(MoveOnlyType&&) = default;
+
+ bool ItsWorking() const { return true; }
+ };
+
+ pw::Function<bool(MoveOnlyType)> function = [](MoveOnlyType value) {
+ return value.ItsWorking();
+ };
+
+ MoveOnlyType move_only;
+ EXPECT_TRUE(function(std::move(move_only)));
+}
+
} // namespace
} // namespace pw
diff --git a/pw_function/public/pw_function/internal/function.h b/pw_function/public/pw_function/internal/function.h
index de96845..8cffd02 100644
--- a/pw_function/public/pw_function/internal/function.h
+++ b/pw_function/public/pw_function/internal/function.h
@@ -55,7 +55,7 @@
// call operator, which is templated on the function arguments and return type.
class GenericFunctionTarget {
public:
- GenericFunctionTarget() = default;
+ constexpr GenericFunctionTarget() = default;
GenericFunctionTarget(const GenericFunctionTarget&) = delete;
GenericFunctionTarget(GenericFunctionTarget&&) = delete;
@@ -79,7 +79,7 @@
template <typename Return, typename... Args>
class FunctionTarget : public GenericFunctionTarget {
public:
- FunctionTarget() = default;
+ constexpr FunctionTarget() = default;
// Invoke the callable stored by the function target.
virtual Return operator()(Args... args) const = 0;
@@ -122,7 +122,9 @@
: callable_(std::move(other.callable_)) {}
InlineFunctionTarget& operator=(InlineFunctionTarget&&) = default;
- Return operator()(Args... args) const final { return callable_(args...); }
+ Return operator()(Args... args) const final {
+ return callable_(std::forward<Args>(args)...);
+ }
void MoveInitializeTo(void* ptr) final {
new (ptr) InlineFunctionTarget(std::move(*this));