1#![allow(non_snake_case)]
7
8use std::future::Future;
9use std::pin::Pin;
10use std::task::Context;
11use std::task::Poll;
12
13use futures::future::maybe_done;
14use futures::future::MaybeDone;
15use pin_utils::unsafe_pinned;
16
17macro_rules! generate {
21 ($(
22 $(#[$doc:meta])*
23 ($Complete:ident, <$($Fut:ident),*>),
24 )*) => ($(
25 #[must_use = "Combinations of futures don't do anything unless run in an executor."]
26 pub(crate) struct $Complete<$($Fut: Future),*> {
27 $($Fut: MaybeDone<$Fut>,)*
28 }
29
30 impl<$($Fut),*> $Complete<$($Fut),*>
31 where $(
32 $Fut: Future,
33 )*
34 {
35 $(
40 unsafe_pinned!($Fut: MaybeDone<$Fut>);
41 )*
42
43 pub(crate) fn new($($Fut: $Fut),*) -> $Complete<$($Fut),*> {
44 $(
45 let $Fut = maybe_done($Fut);
46 )*
47 $Complete {
48 $($Fut),*
49 }
50 }
51 }
52
53 impl<$($Fut),*> Future for $Complete<$($Fut),*>
54 where $(
55 $Fut: Future,
56 )*
57 {
58 type Output = ($($Fut::Output),*);
59
60 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
61 let mut complete = true;
62 $(
63 complete &= self.as_mut().$Fut().poll(cx).is_ready();
64 )*
65
66 if complete {
67 $(
68 let $Fut = self.as_mut().$Fut().take_output().unwrap();
69 )*
70 Poll::Ready(($($Fut), *))
71 } else {
72 Poll::Pending
73 }
74 }
75 }
76 )*)
77}
78
79generate! {
80 (Complete2, <_Fut1, _Fut2>),
82
83 (Complete3, <_Fut1, _Fut2, _Fut3>),
85
86 (Complete4, <_Fut1, _Fut2, _Fut3, _Fut4>),
88
89 (Complete5, <_Fut1, _Fut2, _Fut3, _Fut4, _Fut5>),
91}