libcamera: base: bound_method: Move return value

Instead of copying, just move the returned value when the call is made
through an argument pack. This enables, e.g. `Object::invokeMethod()`
to be usable with functions returning types, such as`std::unique_ptr`,
that have no copy ctor/assignment. Since there are no other users of
the argument pack object, this is safe to do. Reference return types
are not supported, so a simple `std::move()` is sufficient.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=273#c1
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Barnabás Pőcze
2025-06-18 15:56:22 +02:00
parent a9c2dd05fa
commit 14618cdd0c
2 changed files with 25 additions and 13 deletions

View File

@@ -38,11 +38,6 @@ public:
{
}
R returnValue()
{
return ret_;
}
std::tuple<typename std::remove_reference_t<Args>...> args_;
R ret_;
};
@@ -56,10 +51,6 @@ public:
{
}
void returnValue()
{
}
std::tuple<typename std::remove_reference_t<Args>...> args_;
};
@@ -140,8 +131,10 @@ public:
return func_(args...);
auto pack = std::make_shared<PackType>(args...);
bool sync = BoundMethodBase::activatePack(pack, deleteMethod);
return sync ? pack->returnValue() : R();
[[maybe_unused]] bool sync = BoundMethodBase::activatePack(pack, deleteMethod);
if constexpr (!std::is_void_v<R>)
return sync ? std::move(pack->ret_) : R();
}
R invoke(Args... args) override
@@ -175,8 +168,10 @@ public:
}
auto pack = std::make_shared<PackType>(args...);
bool sync = BoundMethodBase::activatePack(pack, deleteMethod);
return sync ? pack->returnValue() : R();
[[maybe_unused]] bool sync = BoundMethodBase::activatePack(pack, deleteMethod);
if constexpr (!std::is_void_v<R>)
return sync ? std::move(pack->ret_) : R();
}
R invoke(Args... args) override

View File

@@ -58,6 +58,19 @@ public:
return 42;
}
struct MoveOnly {
MoveOnly() = default;
MoveOnly(const MoveOnly &) = delete;
MoveOnly &operator=(const MoveOnly &) = delete;
MoveOnly(MoveOnly &&) = default;
MoveOnly &operator=(MoveOnly &&) = default;
};
MoveOnly methodWithReturnMoveOnly()
{
return {};
}
private:
Status status_;
int value_;
@@ -186,6 +199,10 @@ protected:
return TestFail;
}
/* Test invoking a method that returns type with no copy ctor/assignment. */
object_.invokeMethod(&InvokedObject::methodWithReturnMoveOnly,
ConnectionTypeBlocking);
return TestPass;
}