1 | macro_rules! impl_cons_iter( |
2 | ($_A:ident, $_B:ident, ) => (); // stop |
3 | |
4 | ($A:ident, $($B:ident,)*) => ( |
5 | impl_cons_iter!($($B,)*); |
6 | #[allow(non_snake_case)] |
7 | impl<X, Iter, $($B),*> Iterator for ConsTuples<Iter, (($($B,)*), X)> |
8 | where Iter: Iterator<Item = (($($B,)*), X)>, |
9 | { |
10 | type Item = ($($B,)* X, ); |
11 | fn next(&mut self) -> Option<Self::Item> { |
12 | self.iter.next().map(|(($($B,)*), x)| ($($B,)* x, )) |
13 | } |
14 | |
15 | fn size_hint(&self) -> (usize, Option<usize>) { |
16 | self.iter.size_hint() |
17 | } |
18 | fn fold<Acc, Fold>(self, accum: Acc, mut f: Fold) -> Acc |
19 | where Fold: FnMut(Acc, Self::Item) -> Acc, |
20 | { |
21 | self.iter.fold(accum, move |acc, (($($B,)*), x)| f(acc, ($($B,)* x, ))) |
22 | } |
23 | } |
24 | |
25 | #[allow(non_snake_case)] |
26 | impl<X, Iter, $($B),*> DoubleEndedIterator for ConsTuples<Iter, (($($B,)*), X)> |
27 | where Iter: DoubleEndedIterator<Item = (($($B,)*), X)>, |
28 | { |
29 | fn next_back(&mut self) -> Option<Self::Item> { |
30 | self.iter.next().map(|(($($B,)*), x)| ($($B,)* x, )) |
31 | } |
32 | } |
33 | |
34 | ); |
35 | ); |
36 | |
37 | impl_cons_iter!(A, B, C, D, E, F, G, H, I, J, K, L,); |
38 | |
39 | /// An iterator that maps an iterator of tuples like |
40 | /// `((A, B), C)` to an iterator of `(A, B, C)`. |
41 | /// |
42 | /// Used by the `iproduct!()` macro. |
43 | #[must_use = "iterator adaptors are lazy and do nothing unless consumed" ] |
44 | #[derive (Debug)] |
45 | pub struct ConsTuples<I, J> |
46 | where |
47 | I: Iterator<Item = J>, |
48 | { |
49 | iter: I, |
50 | } |
51 | |
52 | impl<I, J> Clone for ConsTuples<I, J> |
53 | where |
54 | I: Clone + Iterator<Item = J>, |
55 | { |
56 | clone_fields!(iter); |
57 | } |
58 | |
59 | /// Create an iterator that maps for example iterators of |
60 | /// `((A, B), C)` to `(A, B, C)`. |
61 | pub fn cons_tuples<I, J>(iterable: I) -> ConsTuples<I::IntoIter, J> |
62 | where |
63 | I: IntoIterator<Item = J>, |
64 | { |
65 | ConsTuples { |
66 | iter: iterable.into_iter(), |
67 | } |
68 | } |
69 | |