Skip to content

Commit 2e1d5ca

Browse files
committed
Reduce genericity in Filter and FilterMap
1 parent 0991a09 commit 2e1d5ca

File tree

1 file changed

+70
-58
lines changed
  • src/libcore/iter/adapters

1 file changed

+70
-58
lines changed

src/libcore/iter/adapters/mod.rs

Lines changed: 70 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -715,13 +715,27 @@ impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> {
715715
}
716716
}
717717

718+
fn filter_fold<T, Acc>(
719+
mut predicate: impl FnMut(&T) -> bool,
720+
mut fold: impl FnMut(Acc, T) -> Acc,
721+
) -> impl FnMut(Acc, T) -> Acc {
722+
move |acc, item| if predicate(&item) { fold(acc, item) } else { acc }
723+
}
724+
725+
fn filter_try_fold<'a, T, Acc, R: Try<Ok = Acc>>(
726+
predicate: &'a mut impl FnMut(&T) -> bool,
727+
mut fold: impl FnMut(Acc, T) -> R + 'a,
728+
) -> impl FnMut(Acc, T) -> R + 'a {
729+
move |acc, item| if predicate(&item) { fold(acc, item) } else { R::from_ok(acc) }
730+
}
731+
718732
#[stable(feature = "rust1", since = "1.0.0")]
719733
impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {
720734
type Item = I::Item;
721735

722736
#[inline]
723737
fn next(&mut self) -> Option<I::Item> {
724-
self.try_for_each(Err).err()
738+
self.iter.find(&mut self.predicate)
725739
}
726740

727741
#[inline]
@@ -743,32 +757,26 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
743757
// leaving more budget for LLVM optimizations.
744758
#[inline]
745759
fn count(self) -> usize {
746-
let mut predicate = self.predicate;
747-
self.iter.map(|x| predicate(&x) as usize).sum()
760+
#[inline]
761+
fn to_usize<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut(T) -> usize {
762+
move |x| predicate(&x) as usize
763+
}
764+
765+
self.iter.map(to_usize(self.predicate)).sum()
748766
}
749767

750768
#[inline]
751-
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
769+
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
752770
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
753771
{
754-
let predicate = &mut self.predicate;
755-
self.iter.try_fold(init, move |acc, item| if predicate(&item) {
756-
fold(acc, item)
757-
} else {
758-
Try::from_ok(acc)
759-
})
772+
self.iter.try_fold(init, filter_try_fold(&mut self.predicate, fold))
760773
}
761774

762775
#[inline]
763-
fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
776+
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
764777
where Fold: FnMut(Acc, Self::Item) -> Acc,
765778
{
766-
let mut predicate = self.predicate;
767-
self.iter.fold(init, move |acc, item| if predicate(&item) {
768-
fold(acc, item)
769-
} else {
770-
acc
771-
})
779+
self.iter.fold(init, filter_fold(self.predicate, fold))
772780
}
773781
}
774782

@@ -778,31 +786,21 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
778786
{
779787
#[inline]
780788
fn next_back(&mut self) -> Option<I::Item> {
781-
self.try_rfold((), |_, x| Err(x)).err()
789+
self.iter.rfind(&mut self.predicate)
782790
}
783791

784792
#[inline]
785-
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
793+
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
786794
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
787795
{
788-
let predicate = &mut self.predicate;
789-
self.iter.try_rfold(init, move |acc, item| if predicate(&item) {
790-
fold(acc, item)
791-
} else {
792-
Try::from_ok(acc)
793-
})
796+
self.iter.try_rfold(init, filter_try_fold(&mut self.predicate, fold))
794797
}
795798

796799
#[inline]
797-
fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
800+
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
798801
where Fold: FnMut(Acc, Self::Item) -> Acc,
799802
{
800-
let mut predicate = self.predicate;
801-
self.iter.rfold(init, move |acc, item| if predicate(&item) {
802-
fold(acc, item)
803-
} else {
804-
acc
805-
})
803+
self.iter.rfold(init, filter_fold(self.predicate, fold))
806804
}
807805
}
808806

@@ -839,6 +837,26 @@ impl<I: fmt::Debug, F> fmt::Debug for FilterMap<I, F> {
839837
}
840838
}
841839

840+
fn filter_map_fold<T, B, Acc>(
841+
mut f: impl FnMut(T) -> Option<B>,
842+
mut fold: impl FnMut(Acc, B) -> Acc,
843+
) -> impl FnMut(Acc, T) -> Acc {
844+
move |acc, item| match f(item) {
845+
Some(x) => fold(acc, x),
846+
None => acc,
847+
}
848+
}
849+
850+
fn filter_map_try_fold<'a, T, B, Acc, R: Try<Ok = Acc>>(
851+
f: &'a mut impl FnMut(T) -> Option<B>,
852+
mut fold: impl FnMut(Acc, B) -> R + 'a,
853+
) -> impl FnMut(Acc, T) -> R + 'a {
854+
move |acc, item| match f(item) {
855+
Some(x) => fold(acc, x),
856+
None => R::from_ok(acc),
857+
}
858+
}
859+
842860
#[stable(feature = "rust1", since = "1.0.0")]
843861
impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
844862
where F: FnMut(I::Item) -> Option<B>,
@@ -847,7 +865,7 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
847865

848866
#[inline]
849867
fn next(&mut self) -> Option<B> {
850-
self.try_for_each(Err).err()
868+
self.iter.find_map(&mut self.f)
851869
}
852870

853871
#[inline]
@@ -857,25 +875,17 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
857875
}
858876

859877
#[inline]
860-
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
878+
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
861879
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
862880
{
863-
let f = &mut self.f;
864-
self.iter.try_fold(init, move |acc, item| match f(item) {
865-
Some(x) => fold(acc, x),
866-
None => Try::from_ok(acc),
867-
})
881+
self.iter.try_fold(init, filter_map_try_fold(&mut self.f, fold))
868882
}
869883

870884
#[inline]
871-
fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
885+
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
872886
where Fold: FnMut(Acc, Self::Item) -> Acc,
873887
{
874-
let mut f = self.f;
875-
self.iter.fold(init, move |acc, item| match f(item) {
876-
Some(x) => fold(acc, x),
877-
None => acc,
878-
})
888+
self.iter.fold(init, filter_map_fold(self.f, fold))
879889
}
880890
}
881891

@@ -885,29 +895,31 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
885895
{
886896
#[inline]
887897
fn next_back(&mut self) -> Option<B> {
888-
self.try_rfold((), |_, x| Err(x)).err()
898+
#[inline]
899+
fn find<T, B>(
900+
f: &mut impl FnMut(T) -> Option<B>
901+
) -> impl FnMut((), T) -> LoopState<(), B> + '_ {
902+
move |(), x| match f(x) {
903+
Some(x) => LoopState::Break(x),
904+
None => LoopState::Continue(()),
905+
}
906+
}
907+
908+
self.iter.try_rfold((), find(&mut self.f)).break_value()
889909
}
890910

891911
#[inline]
892-
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
912+
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
893913
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
894914
{
895-
let f = &mut self.f;
896-
self.iter.try_rfold(init, move |acc, item| match f(item) {
897-
Some(x) => fold(acc, x),
898-
None => Try::from_ok(acc),
899-
})
915+
self.iter.try_rfold(init, filter_map_try_fold(&mut self.f, fold))
900916
}
901917

902918
#[inline]
903-
fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
919+
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
904920
where Fold: FnMut(Acc, Self::Item) -> Acc,
905921
{
906-
let mut f = self.f;
907-
self.iter.rfold(init, move |acc, item| match f(item) {
908-
Some(x) => fold(acc, x),
909-
None => acc,
910-
})
922+
self.iter.rfold(init, filter_map_fold(self.f, fold))
911923
}
912924
}
913925

0 commit comments

Comments
 (0)