coro_utils.hpp
1 
6 #pragma once
7 #include <ranges>
8 #include <type_traits>
9 #include <utility>
10 #include <vector>
11 
12 #include <coro/coro.hpp>
13 
14 namespace rapidsmpf::streaming {
15 
47 template <std::ranges::range Range>
48 auto coro_results(Range&& task_results) {
49  using first_ref_t = std::ranges::range_value_t<Range>;
50  using raw_ret_t = decltype(std::declval<first_ref_t>().return_value());
51  using val_t = std::remove_cvref_t<raw_ret_t>;
52 
53  if constexpr (std::is_void_v<val_t>) {
54  // Just surface exceptions; return void.
55  for (auto&& r : task_results) {
56  r.return_value();
57  }
58  } else {
59  std::vector<val_t> ret;
60  if constexpr (std::ranges::sized_range<Range>) {
61  ret.reserve(task_results.size());
62  }
63  for (auto&& r : task_results) {
64  ret.emplace_back(r.return_value());
65  }
66  return ret;
67  }
68 }
69 
86 template <typename... Args>
87 auto coro_results(std::tuple<Args...>&& results) {
88  return std::apply(
89  [](auto&&... result) {
90  if constexpr ((std::is_void_v<std::remove_cvref_t<
91  decltype(std::declval<
92  std::remove_reference_t<decltype(result)>>()
93  .return_value())>>
94  && ...))
95  {
96  (result.return_value(), ...);
97  } else {
98  return std::make_tuple(
99  std::forward<decltype(result)>(result).return_value()...
100  );
101  }
102  },
103  std::move(results)
104  );
105 }
106 
107 } // namespace rapidsmpf::streaming
auto coro_results(Range &&task_results)
Collect the results of multiple finished coroutines.
Definition: coro_utils.hpp:48