16#include "pw_async2/dispatcher.h"
17#include "pw_async2/future.h"
23template <
typename... Futures>
26 using value_type = std::tuple<FutureValue<Futures>&&...>;
30 [[nodiscard]]
bool is_pendable()
const {
return state_.
is_pendable(); }
32 [[nodiscard]]
bool is_complete()
const {
return state_.
is_complete(); }
37 PW_ASSERT(is_pendable());
38 if (!PendElements(cx, kTupleIndexSequence)) {
43 return TakeOutputs(kTupleIndexSequence);
47 static_assert(
sizeof...(Futures) > 0u,
"Cannot join an empty set of futures");
49 static constexpr auto kTupleIndexSequence =
50 std::make_index_sequence<
sizeof...(Futures)>();
51 using TupleOfOutputRvalues = std::tuple<FutureValue<Futures>&&...>;
53 template <
typename... Fs>
54 friend constexpr auto Join(Fs&&...);
56 explicit constexpr JoinFuture(Futures&&... futures)
57 : futures_(std::move(futures)...),
58 outputs_(
Poll<typename Futures::value_type>(
Pending())...),
64 template <
size_t... Is>
65 bool PendElements(Context& cx, std::index_sequence<Is...>) {
66 (PendElement<Is>(cx), ...);
67 return (std::get<Is>(outputs_).IsReady() && ...);
72 template <
size_t kTupleIndex>
73 void PendElement(Context& cx) {
74 auto& output = std::get<kTupleIndex>(outputs_);
75 if (!output.IsReady()) {
76 output = std::get<kTupleIndex>(futures_).Pend(cx);
81 template <
size_t... Is>
82 Poll<TupleOfOutputRvalues> TakeOutputs(std::index_sequence<Is...>) {
83 return Poll<TupleOfOutputRvalues>(
84 std::forward_as_tuple<FutureValue<Futures>...>(TakeOutput<Is>()...));
88 template <
size_t kTupleIndex>
90 typename std::tuple_element<kTupleIndex, std::tuple<Futures...>>::type>&&
92 return std::move(std::get<kTupleIndex>(outputs_).value());
95 static_assert((Future<Futures> && ...),
96 "All types in JoinFuture must be Future types");
97 std::tuple<Futures...> futures_;
98 std::tuple<Poll<typename Futures::value_type>...> outputs_;
102template <
typename... Futures>
103JoinFuture(Futures&&...) -> JoinFuture<Futures...>;
110template <
typename... Futures>
111constexpr auto Join(Futures&&... futures) {
113 "All arguments to Join must be Future types");
114 return JoinFuture(std::forward<Futures>(futures)...);
constexpr bool is_pendable() const
Definition: future.h:149
void MarkComplete()
Definition: future.h:183
constexpr bool is_complete() const
Definition: future.h:154
Poll< value_type > Pend(Context &cx)
Definition: join.h:36
constexpr auto Join(Futures &&... futures)
Definition: join.h:111
std::conditional_t< std::is_void_v< typename T::value_type >, ReadyType, typename T::value_type > FutureValue
Definition: future.h:107
constexpr PendingType Pending()
Returns a value indicating that an operation was not yet able to complete.
Definition: poll.h:353