diff --git a/src/zip_eq_impl.rs b/src/zip_eq_impl.rs index 864930bc0..caf540282 100644 --- a/src/zip_eq_impl.rs +++ b/src/zip_eq_impl.rs @@ -1,3 +1,5 @@ +use std::iter::FusedIterator; + use super::size_hint; /// An iterator which iterates two other iterators simultaneously @@ -45,7 +47,7 @@ impl Iterator for ZipEq (None, None) => None, (Some(a), Some(b)) => Some((a, b)), (None, Some(_)) | (Some(_), None) => - panic!("itertools: .zip_eq() reached end of one iterator before the other") + panic!("itertools: .zip_eq() reached end of one iterator before the other") } } @@ -54,7 +56,27 @@ impl Iterator for ZipEq } } +impl DoubleEndedIterator for ZipEq + where I: DoubleEndedIterator, + J: DoubleEndedIterator { + fn next_back(&mut self) -> Option { + match (self.a.next_back(), self.b.next_back()) { + (None, None) => None, + (Some(a), Some(b)) => Some((a, b)), + (None, Some(_)) | (Some(_), None) => + panic!("itertools: .zip_eq() reached start of one iterator before the other") + } + } +} + impl ExactSizeIterator for ZipEq where I: ExactSizeIterator, J: ExactSizeIterator {} + +// technically we only need at least one of the iterators to implement FusedIterator, but for that we either need +// negative trait bounds or maybe specialization +impl FusedIterator for ZipEq + where I: FusedIterator, + J: FusedIterator +{} diff --git a/tests/zip.rs b/tests/zip.rs index 5801b4232..7ba7fc5cc 100644 --- a/tests/zip.rs +++ b/tests/zip.rs @@ -29,8 +29,8 @@ fn test_zip_longest_size_hint() { fn test_double_ended_zip_longest() { 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 a = xs.iter().copied(); + let b = ys.iter().copied(); let mut it = a.zip_longest(b); assert_eq!(it.next(), Some(Both(1, 1))); assert_eq!(it.next(), Some(Both(2, 2))); @@ -45,8 +45,8 @@ fn test_double_ended_zip_longest() { 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 a = xs.iter().copied(); + let b = ys.iter().copied(); let mut it = multizip((a, b)); assert_eq!(it.next_back(), Some((4, 7))); assert_eq!(it.next_back(), Some((3, 3))); @@ -75,3 +75,18 @@ fn zip_eq_panic2() zip_eq(&a, &b).count(); } + +#[test] +fn zip_eq_backwards() { + let mut it = zip_eq(0..3, 4..7); + assert_eq!(it.next_back(), Some((2, 6))); + assert_eq!(it.next_back(), Some((1, 5))); + assert_eq!(it.next_back(), Some((0, 4))); + assert_eq!(it.next_back(), None); +} + +#[should_panic] +#[test] +fn zip_eq_backwards_panic() { + zip_eq(&[1, 2], &[1, 2, 3]).rev().count(); +}