]> git.proxmox.com Git - rustc.git/blob - src/vendor/itertools/src/ziptuple.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / vendor / itertools / src / ziptuple.rs
1 use super::size_hint;
2
3 /// See [`multizip`](../fn.multizip.html) for more information.
4 #[derive(Clone)]
5 pub struct Zip<T> {
6 t: T,
7 }
8
9 impl<T> Zip<T> {
10 /// Deprecated: renamed to multizip
11 #[deprecated(note = "Renamed to multizip")]
12 pub fn new<U>(t: U) -> Zip<T>
13 where Zip<T>: From<U>,
14 Zip<T>: Iterator,
15 {
16 multizip(t)
17 }
18 }
19
20 /// An iterator that generalizes *.zip()* and allows running multiple iterators in lockstep.
21 ///
22 /// The iterator `Zip<(I, J, ..., M)>` is formed from a tuple of iterators (or values that
23 /// implement `IntoIterator`) and yields elements
24 /// until any of the subiterators yields `None`.
25 ///
26 /// The iterator element type is a tuple like like `(A, B, ..., E)` where `A` to `E` are the
27 /// element types of the subiterator.
28 ///
29 /// ```
30 /// use itertools::multizip;
31 ///
32 /// // Iterate over three sequences side-by-side
33 /// let mut xs = [0, 0, 0];
34 /// let ys = [69, 107, 101];
35 ///
36 /// for (i, a, b) in multizip((0..100, &mut xs, &ys)) {
37 /// *a = i ^ *b;
38 /// }
39 ///
40 /// assert_eq!(xs, [69, 106, 103]);
41 /// ```
42 pub fn multizip<T, U>(t: U) -> Zip<T>
43 where Zip<T>: From<U>,
44 Zip<T>: Iterator,
45 {
46 Zip::from(t)
47 }
48
49 macro_rules! impl_zip_iter {
50 ($($B:ident),*) => (
51 #[allow(non_snake_case)]
52 impl<$($B: IntoIterator),*> From<($($B,)*)> for Zip<($($B::IntoIter,)*)> {
53 fn from(t: ($($B,)*)) -> Self {
54 let ($($B,)*) = t;
55 Zip { t: ($($B.into_iter(),)*) }
56 }
57 }
58
59 #[allow(non_snake_case)]
60 #[allow(unused_assignments)]
61 impl<$($B),*> Iterator for Zip<($($B,)*)>
62 where
63 $(
64 $B: Iterator,
65 )*
66 {
67 type Item = ($($B::Item,)*);
68
69 fn next(&mut self) -> Option<Self::Item>
70 {
71 let ($(ref mut $B,)*) = self.t;
72
73 // NOTE: Just like iter::Zip, we check the iterators
74 // for None in order. We may finish unevenly (some
75 // iterators gave n + 1 elements, some only n).
76 $(
77 let $B = match $B.next() {
78 None => return None,
79 Some(elt) => elt
80 };
81 )*
82 Some(($($B,)*))
83 }
84
85 fn size_hint(&self) -> (usize, Option<usize>)
86 {
87 let sh = (::std::usize::MAX, None);
88 let ($(ref $B,)*) = self.t;
89 $(
90 let sh = size_hint::min($B.size_hint(), sh);
91 )*
92 sh
93 }
94 }
95
96 #[allow(non_snake_case)]
97 impl<$($B),*> ExactSizeIterator for Zip<($($B,)*)> where
98 $(
99 $B: ExactSizeIterator,
100 )*
101 { }
102 );
103 }
104
105 impl_zip_iter!(A);
106 impl_zip_iter!(A, B);
107 impl_zip_iter!(A, B, C);
108 impl_zip_iter!(A, B, C, D);
109 impl_zip_iter!(A, B, C, D, E);
110 impl_zip_iter!(A, B, C, D, E, F);
111 impl_zip_iter!(A, B, C, D, E, F, G);
112 impl_zip_iter!(A, B, C, D, E, F, G, H);