Skip to content

Commit

Permalink
Merge pull request #1200 from msimberg/fix-when_all_vector
Browse files Browse the repository at this point in the history
Fix issue when using `any_sender` (or any copyable sender) with `when_all_vector`
  • Loading branch information
msimberg authored Jul 10, 2024
2 parents c9c18b9 + 7a8fa75 commit f294998
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,14 @@ namespace pika::when_all_vector_detail {
operation_states_storage_type op_states = nullptr;

template <typename Receiver_>
operation_state(Receiver_&& receiver, std::vector<Sender>&& senders)
operation_state(Receiver_&& receiver, std::vector<Sender> senders)
: num_predecessors(senders.size())
, receiver(PIKA_FORWARD(Receiver_, receiver))
{
op_states =
std::make_unique<std::optional<operation_state_type>[]>(num_predecessors);
std::size_t i = 0;
for (auto&& sender : senders)
for (auto& sender : senders)
{
op_states[i].emplace(pika::detail::with_result_of([&]() {
return pika::execution::experimental::connect(
Expand Down Expand Up @@ -383,7 +383,7 @@ namespace pika::when_all_vector_detail {
friend auto tag_invoke(pika::execution::experimental::connect_t,
when_all_vector_sender_type const& s, Receiver&& receiver)
{
return operation_state<Receiver>(receiver, s.senders);
return operation_state<Receiver>(PIKA_FORWARD(Receiver, receiver), s.senders);
}
};
} // namespace pika::when_all_vector_detail
Expand Down
30 changes: 30 additions & 0 deletions libs/pika/execution/tests/unit/algorithm_when_all_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <pika/config.hpp>
#include <pika/modules/execution.hpp>
#include <pika/modules/execution_base.hpp>
#include <pika/testing.hpp>

#include <pika/execution_base/tests/algorithm_test_utils.hpp>
Expand Down Expand Up @@ -263,6 +264,35 @@ int main()
PIKA_TEST(set_value_called);
}

// Test a combination with any_sender as predecessors and successor
{
std::atomic<bool> set_value_called{false};
std::vector<ex::any_sender<>> senders;
senders.emplace_back(ex::just());
senders.emplace_back(ex::just());
senders.emplace_back(ex::just());
ex::any_sender<> s = ex::when_all_vector(std::move(senders));
auto f = []() {};
auto r = callback_receiver<decltype(f)>{f, set_value_called};
auto os = ex::connect(s, std::move(r));
ex::start(os);
PIKA_TEST(set_value_called);
}

{
std::atomic<bool> set_value_called{false};
std::vector<ex::any_sender<>> senders;
senders.emplace_back(ex::just());
senders.emplace_back(ex::just());
senders.emplace_back(ex::just());
ex::any_sender<> s = ex::when_all_vector(std::move(senders));
auto f = []() {};
auto r = callback_receiver<decltype(f)>{f, set_value_called};
auto os = ex::connect(std::move(s), std::move(r));
ex::start(os);
PIKA_TEST(set_value_called);
}

// Failure path
{
std::atomic<bool> set_error_called{false};
Expand Down

0 comments on commit f294998

Please sign in to comment.