diff --git a/src/ziptuple.rs b/src/ziptuple.rs index 2dc3ea5e0..c5054e0db 100644 --- a/src/ziptuple.rs +++ b/src/ziptuple.rs @@ -98,6 +98,30 @@ macro_rules! impl_zip_iter { $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(), )*].into_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, + } + } + } ); } diff --git a/tests/quick.rs b/tests/quick.rs index 8208a887c..ff05a478c 100644 --- a/tests/quick.rs +++ b/tests/quick.rs @@ -1209,3 +1209,31 @@ quickcheck! { TestResult::passed() } } + +quickcheck! { + fn test_double_ended_zip_2(a: Vec, b: Vec) -> TestResult { + let mut x = + multizip((a.clone().into_iter(), b.clone().into_iter())) + .collect_vec(); + x.reverse(); + + let y = + multizip((a.into_iter(), b.into_iter())) + .rfold(Vec::new(), |mut vec, e| { vec.push(e); vec }); + + TestResult::from_bool(itertools::equal(x, y)) + } + + fn test_double_ended_zip_3(a: Vec, b: Vec, c: Vec) -> TestResult { + let mut x = + multizip((a.clone().into_iter(), b.clone().into_iter(), c.clone().into_iter())) + .collect_vec(); + x.reverse(); + + let y = + multizip((a.into_iter(), b.into_iter(), c.into_iter())) + .rfold(Vec::new(), |mut vec, e| { vec.push(e); vec }); + + TestResult::from_bool(itertools::equal(x, y)) + } +} diff --git a/tests/zip.rs b/tests/zip.rs index b1af52c9c..5801b4232 100644 --- a/tests/zip.rs +++ b/tests/zip.rs @@ -1,6 +1,7 @@ use itertools::Itertools; use itertools::EitherOrBoth::{Both, Left, Right}; use itertools::free::zip_eq; +use itertools::multizip; #[test] fn zip_longest_fused() { @@ -40,6 +41,20 @@ fn test_double_ended_zip_longest() { assert_eq!(it.next(), None); } +#[test] +fn test_double_ended_zip() { + let xs = [1, 2, 3, 4, 5, 6]; + let ys = [1, 2, 3, 7]; + let a = xs.iter().map(|&x| x); + let b = ys.iter().map(|&x| x); + let mut it = multizip((a, b)); + assert_eq!(it.next_back(), Some((4, 7))); + assert_eq!(it.next_back(), Some((3, 3))); + assert_eq!(it.next_back(), Some((2, 2))); + assert_eq!(it.next_back(), Some((1, 1))); + assert_eq!(it.next_back(), None); +} + #[should_panic] #[test] @@ -60,4 +75,3 @@ fn zip_eq_panic2() zip_eq(&a, &b).count(); } -