Skip to content

Commit ac113f0

Browse files
committed
Reduce genericity in Filter and FilterMap
1 parent b1fd3d0 commit ac113f0

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
@@ -748,13 +748,27 @@ impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> {
748748
}
749749
}
750750

751+
fn filter_fold<T, Acc>(
752+
mut predicate: impl FnMut(&T) -> bool,
753+
mut fold: impl FnMut(Acc, T) -> Acc,
754+
) -> impl FnMut(Acc, T) -> Acc {
755+
move |acc, item| if predicate(&item) { fold(acc, item) } else { acc }
756+
}
757+
758+
fn filter_try_fold<'a, T, Acc, R: Try<Ok = Acc>>(
759+
predicate: &'a mut impl FnMut(&T) -> bool,
760+
mut fold: impl FnMut(Acc, T) -> R + 'a,
761+
) -> impl FnMut(Acc, T) -> R + 'a {
762+
move |acc, item| if predicate(&item) { fold(acc, item) } else { R::from_ok(acc) }
763+
}
764+
751765
#[stable(feature = "rust1", since = "1.0.0")]
752766
impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {
753767
type Item = I::Item;
754768

755769
#[inline]
756770
fn next(&mut self) -> Option<I::Item> {
757-
self.try_for_each(Err).err()
771+
self.iter.find(&mut self.predicate)
758772
}
759773

760774
#[inline]
@@ -776,32 +790,26 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
776790
// leaving more budget for LLVM optimizations.
777791
#[inline]
778792
fn count(self) -> usize {
779-
let mut predicate = self.predicate;
780-
self.iter.map(|x| predicate(&x) as usize).sum()
793+
#[inline]
794+
fn to_usize<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut(T) -> usize {
795+
move |x| predicate(&x) as usize
796+
}
797+
798+
self.iter.map(to_usize(self.predicate)).sum()
781799
}
782800

783801
#[inline]
784-
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
802+
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
785803
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
786804
{
787-
let predicate = &mut self.predicate;
788-
self.iter.try_fold(init, move |acc, item| if predicate(&item) {
789-
fold(acc, item)
790-
} else {
791-
Try::from_ok(acc)
792-
})
805+
self.iter.try_fold(init, filter_try_fold(&mut self.predicate, fold))
793806
}
794807

795808
#[inline]
796-
fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
809+
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
797810
where Fold: FnMut(Acc, Self::Item) -> Acc,
798811
{
799-
let mut predicate = self.predicate;
800-
self.iter.fold(init, move |acc, item| if predicate(&item) {
801-
fold(acc, item)
802-
} else {
803-
acc
804-
})
812+
self.iter.fold(init, filter_fold(self.predicate, fold))
805813
}
806814
}
807815

@@ -811,31 +819,21 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
811819
{
812820
#[inline]
813821
fn next_back(&mut self) -> Option<I::Item> {
814-
self.try_rfold((), |_, x| Err(x)).err()
822+
self.iter.rfind(&mut self.predicate)
815823
}
816824

817825
#[inline]
818-
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
826+
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
819827
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
820828
{
821-
let predicate = &mut self.predicate;
822-
self.iter.try_rfold(init, move |acc, item| if predicate(&item) {
823-
fold(acc, item)
824-
} else {
825-
Try::from_ok(acc)
826-
})
829+
self.iter.try_rfold(init, filter_try_fold(&mut self.predicate, fold))
827830
}
828831

829832
#[inline]
830-
fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
833+
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
831834
where Fold: FnMut(Acc, Self::Item) -> Acc,
832835
{
833-
let mut predicate = self.predicate;
834-
self.iter.rfold(init, move |acc, item| if predicate(&item) {
835-
fold(acc, item)
836-
} else {
837-
acc
838-
})
836+
self.iter.rfold(init, filter_fold(self.predicate, fold))
839837
}
840838
}
841839

@@ -872,6 +870,26 @@ impl<I: fmt::Debug, F> fmt::Debug for FilterMap<I, F> {
872870
}
873871
}
874872

873+
fn filter_map_fold<T, B, Acc>(
874+
mut f: impl FnMut(T) -> Option<B>,
875+
mut fold: impl FnMut(Acc, B) -> Acc,
876+
) -> impl FnMut(Acc, T) -> Acc {
877+
move |acc, item| match f(item) {
878+
Some(x) => fold(acc, x),
879+
None => acc,
880+
}
881+
}
882+
883+
fn filter_map_try_fold<'a, T, B, Acc, R: Try<Ok = Acc>>(
884+
f: &'a mut impl FnMut(T) -> Option<B>,
885+
mut fold: impl FnMut(Acc, B) -> R + 'a,
886+
) -> impl FnMut(Acc, T) -> R + 'a {
887+
move |acc, item| match f(item) {
888+
Some(x) => fold(acc, x),
889+
None => R::from_ok(acc),
890+
}
891+
}
892+
875893
#[stable(feature = "rust1", since = "1.0.0")]
876894
impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
877895
where F: FnMut(I::Item) -> Option<B>,
@@ -880,7 +898,7 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
880898

881899
#[inline]
882900
fn next(&mut self) -> Option<B> {
883-
self.try_for_each(Err).err()
901+
self.iter.find_map(&mut self.f)
884902
}
885903

886904
#[inline]
@@ -890,25 +908,17 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
890908
}
891909

892910
#[inline]
893-
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
911+
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
894912
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
895913
{
896-
let f = &mut self.f;
897-
self.iter.try_fold(init, move |acc, item| match f(item) {
898-
Some(x) => fold(acc, x),
899-
None => Try::from_ok(acc),
900-
})
914+
self.iter.try_fold(init, filter_map_try_fold(&mut self.f, fold))
901915
}
902916

903917
#[inline]
904-
fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
918+
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
905919
where Fold: FnMut(Acc, Self::Item) -> Acc,
906920
{
907-
let mut f = self.f;
908-
self.iter.fold(init, move |acc, item| match f(item) {
909-
Some(x) => fold(acc, x),
910-
None => acc,
911-
})
921+
self.iter.fold(init, filter_map_fold(self.f, fold))
912922
}
913923
}
914924

@@ -918,29 +928,31 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
918928
{
919929
#[inline]
920930
fn next_back(&mut self) -> Option<B> {
921-
self.try_rfold((), |_, x| Err(x)).err()
931+
#[inline]
932+
fn find<T, B>(
933+
f: &mut impl FnMut(T) -> Option<B>
934+
) -> impl FnMut((), T) -> LoopState<(), B> + '_ {
935+
move |(), x| match f(x) {
936+
Some(x) => LoopState::Break(x),
937+
None => LoopState::Continue(()),
938+
}
939+
}
940+
941+
self.iter.try_rfold((), find(&mut self.f)).break_value()
922942
}
923943

924944
#[inline]
925-
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
945+
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
926946
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
927947
{
928-
let f = &mut self.f;
929-
self.iter.try_rfold(init, move |acc, item| match f(item) {
930-
Some(x) => fold(acc, x),
931-
None => Try::from_ok(acc),
932-
})
948+
self.iter.try_rfold(init, filter_map_try_fold(&mut self.f, fold))
933949
}
934950

935951
#[inline]
936-
fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
952+
fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
937953
where Fold: FnMut(Acc, Self::Item) -> Acc,
938954
{
939-
let mut f = self.f;
940-
self.iter.rfold(init, move |acc, item| match f(item) {
941-
Some(x) => fold(acc, x),
942-
None => acc,
943-
})
955+
self.iter.rfold(init, filter_map_fold(self.f, fold))
944956
}
945957
}
946958

0 commit comments

Comments
 (0)