From 220e902b2cf7ed6fa62ab0a779cd6d466804df45 Mon Sep 17 00:00:00 2001 From: Philippe-Cholet Date: Tue, 3 Oct 2023 11:39:53 +0200 Subject: [PATCH] `Tuple*Combinations::fold` (macro) `I::Item` and `A` are the same so the "where condition" is not really changed, but it is apparently needed here. We fold `c` then for each item of `iter`, we fold the cloned `iter`. The `while let` loop should probably be converted to `fold` somehow later (if possible) but the core logic is done and it is already really faster. --- src/adaptors/mod.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs index 6d9013f0c..802256542 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -731,7 +731,7 @@ macro_rules! impl_tuple_combination { impl Iterator for $C where I: Iterator + Clone, - I::Item: Clone + A: Clone, { type Item = (A, $(ignore_ident!($X, A)),*); @@ -761,6 +761,26 @@ macro_rules! impl_tuple_combination { let n = self.iter.count(); checked_binomial(n, K).unwrap() + self.c.count() } + + fn fold(self, mut init: B, mut f: F) -> B + where + F: FnMut(B, Self::Item) -> B, + { + let Self { c, item, mut iter } = self; + init = c + .map(|($($X),*,)| { + let z = item.clone().unwrap(); + (z, $($X),*) + }) + .fold(init, &mut f); + while let Some(z) = iter.next() { + let c: $P = iter.clone().into(); + init = c + .map(|($($X),*,)| (z.clone(), $($X),*)) + .fold(init, &mut f); + } + init + } } impl HasCombination for (A, $(ignore_ident!($X, A)),*)