-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace C-style cast with move() in let* algos #552
base: main
Are you sure you want to change the base?
Changes from 5 commits
665e3a0
69a7ff9
9e28159
f58d770
f79acfd
53ebcca
908df96
195503e
cc99df8
be442cd
6000dfd
e73aaf9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -25,6 +25,8 @@ | |||||
#include <unifex/execution_policy.hpp> | ||||||
#include <unifex/type_list.hpp> | ||||||
|
||||||
#include <utility> | ||||||
|
||||||
#include <unifex/detail/prologue.hpp> | ||||||
|
||||||
namespace unifex { | ||||||
|
@@ -165,7 +167,7 @@ struct _stop_source_operation<SuccessorFactory, Receiver>::type { | |||||
nothrow_connectable) { | ||||||
return unifex::connect( | ||||||
static_cast<SuccessorFactory&&>(func)(stopSource_), | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably be a
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||
receiver_t{*this, static_cast<Receiver&&>(r)}); | ||||||
receiver_t{*this, std::move(r)}); | ||||||
} | ||||||
|
||||||
public: | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include <unifex/let_value_with.hpp> | ||
|
||
#include <unifex/just.hpp> | ||
#include <unifex/let_value_with.hpp> | ||
#include <unifex/sync_wait.hpp> | ||
#include <unifex/then.hpp> | ||
#include <unifex/timed_single_thread_context.hpp> | ||
#include <chrono> | ||
#include <iostream> | ||
#include <optional> | ||
#include <variant> | ||
|
||
#include <gtest/gtest.h> | ||
|
||
using namespace unifex; | ||
|
||
namespace { | ||
constexpr auto async = [](auto& context, auto&& func) { | ||
return then( | ||
schedule_after(context.get_scheduler(), std::chrono::milliseconds(10)), | ||
(decltype(func))func); | ||
}; | ||
} | ||
|
||
TEST(LetValueWith, StatefulFactory) { | ||
// Verifies the let_value_with operation state holds onto the | ||
// Factory object until the operation is complete. | ||
timed_single_thread_context context; | ||
std::optional<int> result = sync_wait( | ||
let_value(just(), [&] { | ||
return let_value_with([x = std::make_unique<int>(10)]() -> int* { return x.get(); }, [&](int*& v) { | ||
return async(context, [&v]() { return *v; }); | ||
}); | ||
}) | ||
); | ||
ASSERT_TRUE(!!result); | ||
EXPECT_EQ(*result, 10); | ||
} | ||
|
||
TEST(LetValueWith, CallOperatorRvalueRefOverload) { | ||
struct Factory { | ||
int operator()() && { | ||
return 10; | ||
} | ||
}; | ||
std::optional<int> result = sync_wait(let_value_with(Factory{}, [&](int& v) { | ||
return just(v); | ||
})); | ||
ASSERT_TRUE(!!result); | ||
EXPECT_EQ(*result, 10); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somehow this has broken the MSVC build. I wonder if
Source
is sometimes an lvalue reference.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup; line 324 instantiates an operation with an lvalue ref
Source
if the Sender argument is an lvalue ref. This is astd::forward
.However, most of the operation state types that I've written myself have a templated constructor that takes a forwarding reference to the Sender, rather than templating the whole type on a forwarding reference. It seems like there'd be less duplicated code in the resulting binary if we could follow that pattern.