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