#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
macro_rules! join {
(@ {
// One `_` for each branch in the `join!` macro. This is not used once
// normalization is complete.
( $($count:tt)* )
( $($total:tt)* )
$( ( $($skip:tt)* ) $e:expr, )*
}) => {{
use $crate::macros::support::{maybe_done, poll_fn, Future, Pin};
use $crate::macros::support::Poll::{Ready, Pending};
let mut futures = ( $( maybe_done($e), )* );
let mut futures = &mut futures;
let mut skip_next_time: u32 = 0;
poll_fn(move |cx| {
const COUNT: u32 = $($total)*;
let mut is_pending = false;
let mut to_run = COUNT;
let mut skip = skip_next_time;
skip_next_time = if skip + 1 == COUNT { 0 } else { skip + 1 };
loop {
$(
if skip == 0 {
if to_run == 0 {
break;
}
to_run -= 1;
let ( $($skip,)* fut, .. ) = &mut *futures;
let mut fut = unsafe { Pin::new_unchecked(fut) };
if fut.poll(cx).is_pending() {
is_pending = true;
}
} else {
skip -= 1;
}
)*
}
if is_pending {
Pending
} else {
Ready(($({
let ( $($skip,)* fut, .. ) = &mut futures;
let mut fut = unsafe { Pin::new_unchecked(fut) };
fut.take_output().expect("expected completed future")
},)*))
}
}).await
}};
(@ { ( $($s:tt)* ) ( $($n:tt)* ) $($t:tt)* } $e:expr, $($r:tt)* ) => {
$crate::join!(@{ ($($s)* _) ($($n)* + 1) $($t)* ($($s)*) $e, } $($r)*)
};
( $($e:expr),* $(,)?) => {
$crate::join!(@{ () (0) } $($e,)*)
};
}