macro_rules! zip {
($($iterator:expr),*) => {
$crate::commons::utils::zip!(@zip $($iterator),*)
};
(@zip $first:expr, $($iterator:expr),* ) => {
$first.zip($crate::commons::utils::zip!(@zip $($iterator),*))
};
(@zip $first:expr) => {
$first
};
}
pub(crate) use zip;
macro_rules! zip_args {
($($iterator:pat),*) => {
$crate::commons::utils::zip_args!(@zip $($iterator),*)
};
(@zip $first:pat, $second:pat) => {
($first, $second)
};
(@zip $first:pat, $($iterator:pat),*) => {
($first, $crate::commons::utils::zip_args!(@zip $($iterator),*))
};
}
pub(crate) use zip_args;
#[inline]
fn assert_same_len(a: (usize, Option<usize>), b: (usize, Option<usize>)) {
debug_assert_eq!(a.1, Some(a.0));
debug_assert_eq!(b.1, Some(b.0));
debug_assert_eq!(a.0, b.0);
}
pub trait ZipChecked: IntoIterator + Sized {
#[inline]
fn zip_checked<B: IntoIterator>(
self,
b: B,
) -> core::iter::Zip<<Self as IntoIterator>::IntoIter, <B as IntoIterator>::IntoIter> {
let a = self.into_iter();
let b = b.into_iter();
assert_same_len(a.size_hint(), b.size_hint());
core::iter::zip(a, b)
}
}
impl<A: IntoIterator> ZipChecked for A {}
#[allow(unused_macros)]
macro_rules! izip {
(@ __closure @ $p:pat => $tup:expr) => {
|$p| $tup
};
(@ __closure @ $p:pat => ( $($tup:tt)* ) , $_iter:expr $( , $tail:expr )*) => {
$crate::commons::utils::izip!(@ __closure @ ($p, b) => ( $($tup)*, b ) $( , $tail )*)
};
( $first:expr $(,)?) => {
{
#[allow(unused_imports)]
use $crate::commons::utils::ZipChecked;
::core::iter::IntoIterator::into_iter($first)
}
};
( $first:expr, $($rest:expr),+ $(,)?) => {
{
#[allow(unused_imports)]
use $crate::commons::utils::ZipChecked;
::core::iter::IntoIterator::into_iter($first)
$(.zip_checked($rest))*
.map($crate::commons::utils::izip!(@ __closure @ a => (a) $( , $rest )*))
}
};
}
#[allow(unused_imports)]
pub(crate) use izip;
#[cfg(test)]
mod test {
#![allow(clippy::many_single_char_names)]
#[test]
fn test_zip() {
let a = vec![1, 2, 3];
let b = vec![4, 5, 6];
let c = vec![7, 8, 9];
let d = vec![10, 11, 12];
let e = vec![13, 14, 15];
let f = vec![16, 17, 18];
let g = vec![19, 20, 21];
for zip_args!(a, b, c) in zip!(a.iter(), b.iter(), c.iter()) {
println!("{},{},{}", a, b, c);
}
let mut iterator = zip!(
a.into_iter(),
b.into_iter(),
c.into_iter(),
d.into_iter(),
e.into_iter(),
f.into_iter(),
g.into_iter()
);
assert_eq!(
iterator.next().unwrap(),
(1, (4, (7, (10, (13, (16, 19))))))
);
assert_eq!(
iterator.next().unwrap(),
(2, (5, (8, (11, (14, (17, 20))))))
);
assert_eq!(
iterator.next().unwrap(),
(3, (6, (9, (12, (15, (18, 21))))))
);
}
}