]> git.proxmox.com Git - rustc.git/blame - src/vendor/itertools/src/ziptuple.rs
New upstream version 1.24.1+dfsg1
[rustc.git] / src / vendor / itertools / src / ziptuple.rs
CommitLineData
abe05a73
XL
1use super::size_hint;
2
3/// See [`multizip`](../fn.multizip.html) for more information.
4#[derive(Clone)]
5pub struct Zip<T> {
6 t: T,
7}
8
9impl<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/// ```
42pub 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
49macro_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
105impl_zip_iter!(A);
106impl_zip_iter!(A, B);
107impl_zip_iter!(A, B, C);
108impl_zip_iter!(A, B, C, D);
109impl_zip_iter!(A, B, C, D, E);
110impl_zip_iter!(A, B, C, D, E, F);
111impl_zip_iter!(A, B, C, D, E, F, G);
112impl_zip_iter!(A, B, C, D, E, F, G, H);