From 38bb0b173e370fccc35c7bc02e29525c9d82c767 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Wed, 20 Jul 2022 16:33:57 +0200 Subject: [PATCH] Move `rfold` logic into `iter_rfold` --- library/core/src/iter/adapters/flatten.rs | 54 +++++++++++++++-------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index ba9767e5c4a..307016c2690 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -393,6 +393,35 @@ impl FlattenCompat where I: DoubleEndedIterator>, { + /// Folds the inner iterators into an accumulator by applying an operation, starting form the + /// back. + /// + /// Folds over the inner iterators, not over their elements. Is used by the `rfold` method. + #[inline] + fn iter_rfold(self, mut acc: Acc, mut fold: Fold) -> Acc + where + Fold: FnMut(Acc, U) -> Acc, + { + #[inline] + fn flatten( + fold: &mut impl FnMut(Acc, T::IntoIter) -> Acc, + ) -> impl FnMut(Acc, T) -> Acc + '_ { + move |acc, iter| fold(acc, iter.into_iter()) + } + + if let Some(iter) = self.backiter { + acc = fold(acc, iter); + } + + acc = self.iter.rfold(acc, flatten(&mut fold)); + + if let Some(iter) = self.frontiter { + acc = fold(acc, iter); + } + + acc + } + /// Folds over the inner iterators in reverse order as long as the given function returns /// successfully, always storing the most recent inner iterator in `self.backiter`. /// @@ -579,31 +608,18 @@ where } #[inline] - fn rfold(self, mut init: Acc, mut fold: Fold) -> Acc + fn rfold(self, init: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { #[inline] - fn flatten( - fold: &mut impl FnMut(Acc, T::Item) -> Acc, - ) -> impl FnMut(Acc, T) -> Acc + '_ - where - T::IntoIter: DoubleEndedIterator, - { - move |acc, x| x.into_iter().rfold(acc, &mut *fold) + fn flatten( + mut fold: impl FnMut(Acc, U::Item) -> Acc, + ) -> impl FnMut(Acc, U) -> Acc { + move |acc, iter| iter.rfold(acc, &mut fold) } - if let Some(back) = self.backiter { - init = back.rfold(init, &mut fold); - } - - init = self.iter.rfold(init, flatten(&mut fold)); - - if let Some(front) = self.frontiter { - init = front.rfold(init, &mut fold); - } - - init + self.iter_rfold(init, flatten(fold)) } #[inline]