1use core::pin::Pin;
2use core::{
3 future::Future,
4 task::{Context, Poll},
5};
6
7extern crate alloc;
8use alloc::vec::Vec;
9
10use crate::BoxFuture;
11
12pub struct JoinedFuture<'a, T> {
14 futures: Vec<(Option<T>, BoxFuture<'a, T>)>,
15}
16
17impl<'a, T> JoinedFuture<'a, T> {
18 #[inline]
19 fn new(futures: Vec<BoxFuture<'a, T>>) -> Self {
20 Self {
21 futures: futures.into_iter().map(|x| (None, x)).collect(),
22 }
23 }
24}
25
26impl<'a, T> Future for JoinedFuture<'a, T> {
27 type Output = Vec<T>;
28
29 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
30 let mut done = true;
31 let me = unsafe {
32 self.get_unchecked_mut()
35 };
36 for future in me.futures.iter_mut() {
37 if future.0.is_some() {
38 continue;
39 }
40 done = false;
41 if let Poll::Ready(content) = future.1.as_mut().poll(cx) {
42 future.0 = Some(content);
43 }
44 }
45 if done {
46 Poll::Ready(me.futures.iter_mut().map(|x| x.0.take().unwrap()).collect())
47 } else {
48 Poll::Pending
49 }
50 }
51}
52
53#[inline]
56pub fn join<T>(futures: Vec<BoxFuture<T>>) -> JoinedFuture<T> {
57 JoinedFuture::new(futures)
58}
59
60#[macro_export]
61macro_rules! join {
62 ($($a:expr),* $(,)?) => {
63 join(vec![$(
64 $crate::prep($a),
65 )*])
66 };
67}
68
69#[macro_export]
70macro_rules! join_boxed {
71 ($($a:expr),* $(,)?) => {
72 join(vec![$(
73 $a,
74 )*])
75 };
76}