euphony_units/
zip.rs

1pub trait Zip {
2    type Iter;
3
4    fn zip(self) -> Self::Iter;
5}
6
7#[derive(Clone, Copy)]
8pub struct ZipIter<T>(T);
9
10macro_rules! zip {
11    () => {};
12    ($H:ident $(,$T:ident)* $(,)?) => {
13        impl<$H: IntoIterator, $($T: IntoIterator,)*> Zip for ($H, $($T,)*) {
14            type Iter = ZipIter<($H::IntoIter, $($T::IntoIter,)*)>;
15
16            #[inline]
17            #[allow(non_snake_case)]
18            fn zip(self) -> Self::Iter {
19                let (
20                    $H,
21                    $(
22                        $T,
23                    )*
24                ) = self;
25                ZipIter((
26                    $H.into_iter(),
27                    $(
28                        $T.into_iter(),
29                    )*
30                ))
31            }
32        }
33
34        impl<$H: Iterator, $($T: Iterator,)*> Iterator for ZipIter<($H, $($T,)*)> {
35            type Item = ($H::Item, $($T::Item,)*);
36
37            #[inline]
38            #[allow(non_snake_case)]
39            fn next(&mut self) -> Option<Self::Item> {
40                let (
41                    $H,
42                    $(
43                        $T,
44                    )*
45                ) = &mut self.0;
46                Some((
47                    $H.next()?,
48                    $(
49                        $T.next()?,
50                    )*
51                ))
52            }
53        }
54
55        zip!($($T),*);
56    };
57}
58
59zip!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z);