diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs index d98f6fe7c..a7b759bf9 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -806,9 +806,30 @@ macro_rules! impl_tuple_combination { ) } -impl_tuple_combination!(Tuple2Combination Tuple1Combination ; A, A, A ; a); -impl_tuple_combination!(Tuple3Combination Tuple2Combination ; A, A, A, A ; a b); -impl_tuple_combination!(Tuple4Combination Tuple3Combination ; A, A, A, A, A; a b c); +// This snippet generates the twelve `impl_tuple_collect!` invocations: +// use core::iter; +// use itertools::Itertools; +// +// for i in 2..=12 { +// println!("impl_tuple_combination!(Tuple{arity}Combination Tuple{prev}Combination; {tys}; {idents});", +// arity = i, +// prev = i - 1, +// tys = iter::repeat("A").take(i + 1).join(", "), +// idents = ('a'..'z').take(i - 1).join(" "), +// ); +// } +// It could probably be replaced by a bit more macro cleverness. +impl_tuple_combination!(Tuple2Combination Tuple1Combination; A, A, A; a); +impl_tuple_combination!(Tuple3Combination Tuple2Combination; A, A, A, A; a b); +impl_tuple_combination!(Tuple4Combination Tuple3Combination; A, A, A, A, A; a b c); +impl_tuple_combination!(Tuple5Combination Tuple4Combination; A, A, A, A, A, A; a b c d); +impl_tuple_combination!(Tuple6Combination Tuple5Combination; A, A, A, A, A, A, A; a b c d e); +impl_tuple_combination!(Tuple7Combination Tuple6Combination; A, A, A, A, A, A, A, A; a b c d e f); +impl_tuple_combination!(Tuple8Combination Tuple7Combination; A, A, A, A, A, A, A, A, A; a b c d e f g); +impl_tuple_combination!(Tuple9Combination Tuple8Combination; A, A, A, A, A, A, A, A, A, A; a b c d e f g h); +impl_tuple_combination!(Tuple10Combination Tuple9Combination; A, A, A, A, A, A, A, A, A, A, A; a b c d e f g h i); +impl_tuple_combination!(Tuple11Combination Tuple10Combination; A, A, A, A, A, A, A, A, A, A, A, A; a b c d e f g h i j); +impl_tuple_combination!(Tuple12Combination Tuple11Combination; A, A, A, A, A, A, A, A, A, A, A, A, A; a b c d e f g h i j k); /// An iterator adapter to filter values within a nested `Result::Ok`. /// diff --git a/src/cons_tuples_impl.rs b/src/cons_tuples_impl.rs index 3cdfe0d18..5a1343891 100644 --- a/src/cons_tuples_impl.rs +++ b/src/cons_tuples_impl.rs @@ -35,7 +35,7 @@ macro_rules! impl_cons_iter( ); ); -impl_cons_iter!(A, B, C, D, E, F, G, H,); +impl_cons_iter!(A, B, C, D, E, F, G, H, I, J, K, L,); /// An iterator that maps an iterator of tuples like /// `((A, B), C)` to an iterator of `(A, B, C)`. diff --git a/src/lib.rs b/src/lib.rs index 1412930b1..e790889b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1250,7 +1250,7 @@ pub trait Itertools : Iterator { /// elements from an iterator. /// /// Iterator element can be any homogeneous tuple of type `Self::Item` with - /// size up to 4. + /// size up to 12. /// /// ``` /// use itertools::Itertools; @@ -1485,7 +1485,7 @@ pub trait Itertools : Iterator { // non-adaptor methods /// Advances the iterator and returns the next items grouped in a tuple of - /// a specific size (up to 4). + /// a specific size (up to 12). /// /// If there are enough elements to be grouped in a tuple, then the tuple is /// returned inside `Some`, otherwise `None` is returned. @@ -1505,7 +1505,7 @@ pub trait Itertools : Iterator { } /// Collects all items from the iterator into a tuple of a specific size - /// (up to 4). + /// (up to 12). /// /// If the number of elements inside the iterator is **exactly** equal to /// the tuple size, then the tuple is returned inside `Some`, otherwise diff --git a/src/tuple_impl.rs b/src/tuple_impl.rs index 4388e71e3..2af27953a 100644 --- a/src/tuple_impl.rs +++ b/src/tuple_impl.rs @@ -280,23 +280,14 @@ macro_rules! impl_tuple_collect { return None; } - #[allow(unused_assignments)] fn collect_from_iter_no_buf(iter: I) -> Option where I: IntoIterator { let mut iter = iter.into_iter(); - loop { - $( - let $Y = if let Some($Y) = iter.next() { - $Y - } else { - break; - }; - )* - return Some(($($Y),*,)) - } - return None; + Some(($( + { let $Y = iter.next()?; $Y }, + )*)) } fn num_items() -> usize { @@ -307,17 +298,37 @@ macro_rules! impl_tuple_collect { use std::mem::replace; let &mut ($(ref mut $Y),*,) = self; - let tmp = item; $( - let tmp = replace($Y_rev, tmp); + let item = replace($Y_rev, item); )* - drop(tmp); + drop(item); } } ) } +// This snippet generates the twelve `impl_tuple_collect!` invocations: +// use core::iter; +// use itertools::Itertools; +// +// for i in 1..=12 { +// println!("impl_tuple_collect!({arity}; A; {ty}; {idents}; {rev_idents});", +// arity=i, +// ty=iter::repeat("A").take(i).join(", "), +// idents=('a'..='z').take(i).join(", "), +// rev_idents=('a'..='z').take(i).collect_vec().into_iter().rev().join(", ") +// ); +// } +// It could probably be replaced by a bit more macro cleverness. impl_tuple_collect!(1; A; A; a; a); impl_tuple_collect!(2; A; A, A; a, b; b, a); impl_tuple_collect!(3; A; A, A, A; a, b, c; c, b, a); impl_tuple_collect!(4; A; A, A, A, A; a, b, c, d; d, c, b, a); +impl_tuple_collect!(5; A; A, A, A, A, A; a, b, c, d, e; e, d, c, b, a); +impl_tuple_collect!(6; A; A, A, A, A, A, A; a, b, c, d, e, f; f, e, d, c, b, a); +impl_tuple_collect!(7; A; A, A, A, A, A, A, A; a, b, c, d, e, f, g; g, f, e, d, c, b, a); +impl_tuple_collect!(8; A; A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h; h, g, f, e, d, c, b, a); +impl_tuple_collect!(9; A; A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i; i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(10; A; A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j; j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(11; A; A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k; k, j, i, h, g, f, e, d, c, b, a); +impl_tuple_collect!(12; A; A, A, A, A, A, A, A, A, A, A, A, A; a, b, c, d, e, f, g, h, i, j, k, l; l, k, j, i, h, g, f, e, d, c, b, a); diff --git a/src/ziptuple.rs b/src/ziptuple.rs index 2dc3ea5e0..7a3000668 100644 --- a/src/ziptuple.rs +++ b/src/ziptuple.rs @@ -109,3 +109,7 @@ impl_zip_iter!(A, B, C, D, E); impl_zip_iter!(A, B, C, D, E, F); impl_zip_iter!(A, B, C, D, E, F, G); impl_zip_iter!(A, B, C, D, E, F, G, H); +impl_zip_iter!(A, B, C, D, E, F, G, H, I); +impl_zip_iter!(A, B, C, D, E, F, G, H, I, J); +impl_zip_iter!(A, B, C, D, E, F, G, H, I, J, K); +impl_zip_iter!(A, B, C, D, E, F, G, H, I, J, K, L);