avenger_wgpu/
util.rs

1#[macro_export]
2macro_rules! par_izip {
3    // Define the closure for flattening the tuple in a map call for parallel processing.
4    ( @closure $p:pat => $tup:expr ) => {
5        |$p| $tup
6    };
7
8    ( @closure $p:pat => ( $($tup:tt)* ) , $_iter:expr $( , $tail:expr )* ) => {
9        par_izip!(@closure ($p, b) => ( $($tup)*, b ) $( , $tail )*)
10    };
11
12    // Unary case: Convert a single iterable into a parallel iterator.
13    ($first:expr $(,)*) => {
14        rayon::prelude::IntoParallelRefIterator::par_iter(&$first)
15    };
16
17    // Binary case: Zip two parallel iterators.
18    ($first:expr, $second:expr $(,)*) => {
19        par_izip!($first)
20            .zip($second)
21    };
22
23    // N-ary case: Zip multiple parallel iterators and flatten the tuple.
24    ( $first:expr $( , $rest:expr )* $(,)* ) => {
25        par_izip!($first)
26            $(
27                .zip($rest)
28            )*
29            .map(
30                par_izip!(@closure a => (a) $( , $rest )*)
31            )
32    };
33}
34
35#[cfg(test)]
36mod tests {
37    use rayon::prelude::*;
38
39    #[test]
40    fn try_it() {
41        let v = par_izip!(vec![1, 2, 3], vec![1, 2, 3], vec![1, 2, 3])
42            .map(|(a, b, c)| {
43                println!("{a}, {b}, {c}");
44                a + b + c
45            })
46            .collect::<Vec<_>>();
47        println!("{v:?}");
48    }
49}