#[derive(Clone, Debug)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub struct Zip { t: T, } pub fn multizip(t: U) -> Zip where Zip: From, Zip: Iterator, { Zip::from(t) } macro_rules! impl_zip_iter { ($($B:ident),*) => ( #[allow(non_snake_case)] impl<$($B: IntoIterator),*> From<($($B,)*)> for Zip<($($B::IntoIter,)*)> { fn from(t: ($($B,)*)) -> Self { let ($($B,)*) = t; Zip { t: ($($B.into_iter(),)*) } } } #[allow(non_snake_case)] #[allow(unused_assignments)] impl<$($B),*> Iterator for Zip<($($B,)*)> where $($B: Iterator,)* { type Item = ($($B::Item,)*); fn next(&mut self) -> Option { let ($(ref mut $B,)*) = self.t; $( let $B = match $B.next() { None => return None, Some(elt) => elt }; )* Some(($($B,)*)) } } #[allow(non_snake_case)] impl<$($B),*> ExactSizeIterator for Zip<($($B,)*)> where $($B: ExactSizeIterator,)* { } #[allow(non_snake_case)] impl<$($B),*> DoubleEndedIterator for Zip<($($B,)*)> where $($B: DoubleEndedIterator + ExactSizeIterator,)* { #[inline] fn next_back(&mut self) -> Option { let ($(ref mut $B,)*) = self.t; let size = *[$( $B.len(), )*].iter().min().unwrap(); $( if $B.len() != size { for _ in 0..$B.len() - size { $B.next_back(); } } )* match ($($B.next_back(),)*) { ($(Some($B),)*) => Some(($($B,)*)), _ => None, } } } ); } impl_zip_iter!(A); impl_zip_iter!(A, B); impl_zip_iter!(A, B, C); impl_zip_iter!(A, B, C, D); impl_zip_iter!(A, B, C, D, E); impl_zip_iter!(A, B, C, D, E, F); impl_zip_iter!(A, B, C, D, E, F, G); impl_zip_iter!(A, B, C, D, E, F, G, H); impl_zip_iter!(A, B, C, D, E, F, G, H, I); impl_zip_iter!(A, B, C, D, E, F, G, H, I, J); impl_zip_iter!(A, B, C, D, E, F, G, H, I, J, K); impl_zip_iter!(A, B, C, D, E, F, G, H, I, J, K, L); #[cfg(test)] mod tests { use crate::alpha::multizip_test::multizip; #[test] fn test_multi_zip() { // iterate over three sequences side-by-side let mut results = [0, 0, 0, 0]; let inputs = [3, 7, 9, 6]; for (r, index, input) in multizip((&mut results, 0..10, &inputs)) { *r = index * 10 + input; } assert_eq!(results, [0 + 3, 10 + 7, 29, 36]); } }