16#include "pw_async2/dispatcher.h"
17#include "pw_async2/future.h"
23template <
typename... Futures>
26 using value_type = std::tuple<FutureValue<Futures>...>;
31 [[nodiscard]]
bool is_pendable()
const {
return state_.
is_pendable(); }
33 [[nodiscard]]
bool is_complete()
const {
return state_.
is_complete(); }
38 PW_ASSERT(is_pendable());
39 if (!PendElements(cx, kTupleIndexSequence)) {
44 return TakeOutputs(kTupleIndexSequence);
48 static_assert(
sizeof...(Futures) > 0u,
"Cannot join an empty set of futures");
50 static constexpr auto kTupleIndexSequence =
51 std::make_index_sequence<
sizeof...(Futures)>();
52 using TupleOfOutputValues = std::tuple<FutureValue<Futures>...>;
54 template <
typename... Fs>
55 friend constexpr auto Join(Fs&&...);
57 explicit constexpr JoinFuture(Futures&&... futures)
58 : futures_(std::move(futures)...),
59 outputs_(
Poll<typename Futures::value_type>(
Pending())...),
65 template <
size_t... Is>
66 bool PendElements(Context& cx, std::index_sequence<Is...>) {
67 (PendElement<Is>(cx), ...);
68 return (std::get<Is>(outputs_).IsReady() && ...);
73 template <
size_t kTupleIndex>
74 void PendElement(Context& cx) {
75 auto& output = std::get<kTupleIndex>(outputs_);
76 if (!output.IsReady()) {
77 output = std::get<kTupleIndex>(futures_).Pend(cx);
82 template <
size_t... Is>
83 Poll<TupleOfOutputValues> TakeOutputs(std::index_sequence<Is...>) {
84 return Poll<TupleOfOutputValues>(
85 std::tuple<FutureValue<Futures>...>(TakeOutput<Is>()...));
89 template <
size_t kTupleIndex>
91 typename std::tuple_element<kTupleIndex, std::tuple<Futures...>>::type>&&
93 return std::move(std::get<kTupleIndex>(outputs_).value());
96 static_assert((Future<Futures> && ...),
97 "All types in JoinFuture must be Future types");
98 std::tuple<Futures...> futures_;
99 std::tuple<Poll<typename Futures::value_type>...> outputs_;
103template <
typename... Futures>
104JoinFuture(Futures&&...) -> JoinFuture<Futures...>;
111template <
typename... Futures>
112constexpr auto Join(Futures&&... futures) {
114 "All arguments to Join must be Future types");
115 return JoinFuture(std::forward<Futures>(futures)...);
constexpr bool is_pendable() const
Definition: future.h:151
void MarkComplete()
Definition: future.h:185
constexpr bool is_complete() const
Definition: future.h:156
Poll< value_type > Pend(Context &cx)
Definition: join.h:37
constexpr auto Join(Futures &&... futures)
Definition: join.h:112
std::conditional_t< std::is_void_v< typename T::value_type >, ReadyType, typename T::value_type > FutureValue
Definition: future.h:109
constexpr PendingType Pending()
Returns a value indicating that an operation was not yet able to complete.
Definition: poll.h:353