[orc-rt] Restore perfect forwarding to move_only_function init (#157784)

After the recent change to hoist std::decay_t (cd8f47b2d4e) we were
forcing move-initialization of the callable type. This commit restores
perfect forwarding so that we copy-initialize where expected.
This commit is contained in:
Lang Hames 2025-09-10 13:26:23 +10:00 committed by GitHub
parent 55906374f8
commit 735522a3c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 26 additions and 5 deletions

View File

@ -41,7 +41,9 @@ public:
template <typename CallableT, typename RetT, typename... ArgTs>
class GenericCallableImpl : public GenericCallable<RetT, ArgTs...> {
public:
GenericCallableImpl(CallableT &&Callable) : Callable(std::move(Callable)) {}
template <typename CallableInitT>
GenericCallableImpl(CallableInitT &&Callable)
: Callable(std::forward<CallableInitT>(Callable)) {}
RetT call(ArgTs &&...Args) override {
return Callable(std::forward<ArgTs>(Args)...);
}
@ -59,8 +61,9 @@ public:
template <typename CallableT, typename RetT, typename... ArgTs>
class GenericConstCallableImpl : public GenericConstCallable<RetT, ArgTs...> {
public:
GenericConstCallableImpl(CallableT &&Callable)
: Callable(std::move(Callable)) {}
template <typename CallableInitT>
GenericConstCallableImpl(CallableInitT &&Callable)
: Callable(std::forward<CallableInitT>(Callable)) {}
RetT call(ArgTs &&...Args) const override {
return Callable(std::forward<ArgTs>(Args)...);
}
@ -93,7 +96,7 @@ public:
template <typename CallableT>
move_only_function(CallableT &&Callable)
: C(std::make_unique<GenericCallableImpl<std::decay_t<CallableT>>>(
std::move(Callable))) {}
std::forward<CallableT>(Callable))) {}
RetT operator()(ArgTs... Params) const {
return C->call(std::forward<ArgTs>(Params)...);
@ -126,7 +129,7 @@ public:
template <typename CallableT>
move_only_function(CallableT &&Callable)
: C(std::make_unique<const GenericCallableImpl<std::decay_t<CallableT>>>(
std::move(Callable))) {}
std::forward<CallableT>(Callable))) {}
RetT operator()(ArgTs... Params) const {
return C->call(std::forward<ArgTs>(Params)...);

View File

@ -228,3 +228,21 @@ TEST(MoveOnlyFunctionTest, Constness) {
EXPECT_EQ(Const, 1U);
}
}
TEST(MoveOnlyFunctionTest, ShouldCopyInitialize) {
// Check that we don't accidentally move-initialize move_only_functions.
class ShouldCopy {
public:
ShouldCopy(bool &Moved) : Moved(Moved) {}
ShouldCopy(const ShouldCopy &) = default;
ShouldCopy(ShouldCopy &&Other) : Moved(Other.Moved) { Moved = true; }
void operator()() {}
private:
bool &Moved;
};
bool DidMove = false;
ShouldCopy SC(DidMove);
move_only_function<void()> F(SC);
EXPECT_FALSE(DidMove);
}