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  );
26  
27  impl_cons_iter!(A, B, C, D, E, F, G, H, I, J, K, L,);
28  
29  /// An iterator that maps an iterator of tuples like
30  /// `((A, B), C)` to an iterator of `(A, B, C)`.
31  ///
32  /// Used by the `iproduct!()` macro.
33  #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
34  #[derive(Debug)]
35  pub struct ConsTuples<I, J>
36  where
37      I: Iterator<Item = J>,
38  {
39      iter: I,
40  }
41  
42  impl<I, J> Clone for ConsTuples<I, J>
43  where
44      I: Clone + Iterator<Item = J>,
45  {
46      clone_fields!(iter);
47  }
48  
49  /// Create an iterator that maps for example iterators of
50  /// `((A, B), C)` to `(A, B, C)`.
cons_tuples<I, J>(iterable: I) -> ConsTuples<I::IntoIter, J> where I: IntoIterator<Item = J>,51  pub fn cons_tuples<I, J>(iterable: I) -> ConsTuples<I::IntoIter, J>
52  where
53      I: IntoIterator<Item = J>,
54  {
55      ConsTuples {
56          iter: iterable.into_iter(),
57      }
58  }
59