Skip to content

Commit

Permalink
Merge pull request #1172 from NVIDIA/fix-sync-wait-with-variant-retur…
Browse files Browse the repository at this point in the history
…n-type

remove erroneous tuple in return type of `sync_wait_with_variant`
  • Loading branch information
ericniebler authored Dec 16, 2023
2 parents bc10e41 + 5433dcd commit e8e27de
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 8 deletions.
11 changes: 9 additions & 2 deletions include/stdexec/execution.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5532,6 +5532,10 @@ namespace stdexec {
template <class _Sender>
using __sync_wait_result_t = __mtry_eval<__sync_wait_result_impl, _Sender, __q<std::tuple>>;

template <class _Sender>
using __sync_wait_with_variant_result_t =
__mtry_eval<__sync_wait_result_impl, __result_of<into_variant, _Sender>, __q<__midentity>>;

template <class... _Values>
struct __state {
using _Tuple = std::tuple<_Values...>;
Expand Down Expand Up @@ -5605,7 +5609,7 @@ namespace stdexec {

template <class _Sender>
struct __variant_for {
using __t = __sync_wait_result_t<__result_of<into_variant, _Sender>>;
using __t = __sync_wait_with_variant_result_t<_Sender>;
};
template <class _Sender>
using __variant_for_t = __t<__variant_for<_Sender>>;
Expand Down Expand Up @@ -5762,7 +5766,10 @@ namespace stdexec {
template <class _Sender>
requires __callable<sync_wait_t, __result_of<into_variant, _Sender>>
auto apply_sender(_Sender&& __sndr) const -> std::optional<__variant_for_t<_Sender>> {
return sync_wait_t()(into_variant((_Sender&&) __sndr));
if (auto __opt_values = sync_wait_t()(into_variant((_Sender&&) __sndr))) {
return std::move(std::get<0>(*__opt_values));
}
return std::nullopt;
}
};
} // namespace __sync_wait
Expand Down
12 changes: 6 additions & 6 deletions test/stdexec/algos/consumers/test_sync_wait.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ namespace {
using my_transfered_multi_value_sender_t =
decltype(ex::transfer(my_multi_value_sender_t{}, inline_scheduler{}));

optional<std::tuple<std::variant<std::tuple<std::string>, std::tuple<int>>>> tag_invoke(
optional<std::variant<std::tuple<std::string>, std::tuple<int>>> tag_invoke(
decltype(sync_wait_with_variant),
inline_scheduler sched,
my_transfered_multi_value_sender_t&& s) {
Expand All @@ -294,7 +294,7 @@ namespace {
return {res};
}

optional<std::tuple<std::variant<std::tuple<std::string>, std::tuple<int>>>>
optional<std::variant<std::tuple<std::string>, std::tuple<int>>>
tag_invoke(decltype(sync_wait_with_variant), my_multi_value_sender_t s) {
CHECK(s.str_ == "hello_multi");
return {std::string{"ciao_multi"}};
Expand All @@ -306,21 +306,21 @@ namespace {
// The customization will return a different value
auto snd = ex::transfer(my_multi_value_sender_t{"hello_multi"}, inline_scheduler{});
auto snd2 = ex::transfer_just(inline_scheduler{}, std::string{"hello"});
optional<std::tuple<std::variant<std::tuple<std::string>, std::tuple<int>>>> res =
optional<std::variant<std::tuple<std::string>, std::tuple<int>>> res =
sync_wait_with_variant(std::move(snd));
CHECK(res.has_value());
CHECK(std::get<0>(std::get<0>(res.value())) == std::make_tuple(std::string{"hallo_multi"}));
CHECK(std::get<0>(std::get<0>(res.value())) == std::string{"hallo_multi"});
}

TEST_CASE(
"sync_wait_with_variant can be customized without scheduler",
"[consumers][sync_wait_with_variant]") {
// The customization will return a different value
my_multi_value_sender_t snd{std::string{"hello_multi"}};
optional<std::tuple<std::variant<std::tuple<std::string>, std::tuple<int>>>> res =
optional<std::variant<std::tuple<std::string>, std::tuple<int>>> res =
sync_wait_with_variant(std::move(snd));
CHECK(res.has_value());
CHECK(std::get<0>(std::get<0>(res.value())) == std::make_tuple(std::string{"ciao_multi"}));
CHECK(std::get<0>(std::get<0>(res.value())) == std::string{"ciao_multi"});
}

template <class... Ts>
Expand Down

0 comments on commit e8e27de

Please sign in to comment.