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