]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | use super::size_hint; |
2 | ||
3 | /// An iterator which iterates two other iterators simultaneously | |
4 | /// | |
5 | /// See [`.zip_eq()`](../trait.Itertools.html#method.zip_eq) for more information. | |
6 | #[derive(Clone, Debug)] | |
7 | #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] | |
8 | pub struct ZipEq<I, J> { | |
9 | a: I, | |
10 | b: J, | |
11 | } | |
12 | ||
13 | /// Iterate `i` and `j` in lock step. | |
14 | /// | |
15 | /// **Panics** if the iterators are not of the same length. | |
16 | /// | |
17 | /// `IntoIterator` enabled version of `i.zip_eq(j)`. | |
18 | /// | |
19 | /// ``` | |
20 | /// use itertools::zip_eq; | |
21 | /// | |
22 | /// let data = [1, 2, 3, 4, 5]; | |
23 | /// for (a, b) in zip_eq(&data[..data.len() - 1], &data[1..]) { | |
24 | /// /* loop body */ | |
25 | /// } | |
26 | /// ``` | |
27 | pub fn zip_eq<I, J>(i: I, j: J) -> ZipEq<I::IntoIter, J::IntoIter> | |
28 | where I: IntoIterator, | |
29 | J: IntoIterator | |
30 | { | |
31 | ZipEq { | |
32 | a: i.into_iter(), | |
33 | b: j.into_iter(), | |
34 | } | |
35 | } | |
36 | ||
37 | impl<I, J> Iterator for ZipEq<I, J> | |
38 | where I: Iterator, | |
39 | J: Iterator | |
40 | { | |
41 | type Item = (I::Item, J::Item); | |
42 | ||
43 | fn next(&mut self) -> Option<Self::Item> { | |
44 | match (self.a.next(), self.b.next()) { | |
45 | (None, None) => None, | |
46 | (Some(a), Some(b)) => Some((a, b)), | |
47 | (None, Some(_)) | (Some(_), None) => | |
48 | panic!("itertools: .zip_eq() reached end of one iterator before the other") | |
49 | } | |
50 | } | |
51 | ||
52 | fn size_hint(&self) -> (usize, Option<usize>) { | |
53 | size_hint::min(self.a.size_hint(), self.b.size_hint()) | |
54 | } | |
55 | } | |
56 | ||
57 | impl<I, J> ExactSizeIterator for ZipEq<I, J> | |
58 | where I: ExactSizeIterator, | |
59 | J: ExactSizeIterator | |
60 | {} |