@@ -715,13 +715,27 @@ impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> {
715
715
}
716
716
}
717
717
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
+
718
732
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
719
733
impl < I : Iterator , P > Iterator for Filter < I , P > where P : FnMut ( & I :: Item ) -> bool {
720
734
type Item = I :: Item ;
721
735
722
736
#[ inline]
723
737
fn next ( & mut self ) -> Option < I :: Item > {
724
- self . try_for_each ( Err ) . err ( )
738
+ self . iter . find ( & mut self . predicate )
725
739
}
726
740
727
741
#[ inline]
@@ -743,32 +757,26 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
743
757
// leaving more budget for LLVM optimizations.
744
758
#[ inline]
745
759
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 ( )
748
766
}
749
767
750
768
#[ 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
752
770
Self : Sized , Fold : FnMut ( Acc , Self :: Item ) -> R , R : Try < Ok =Acc >
753
771
{
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) )
760
773
}
761
774
762
775
#[ inline]
763
- fn fold < Acc , Fold > ( self , init : Acc , mut fold : Fold ) -> Acc
776
+ fn fold < Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
764
777
where Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
765
778
{
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) )
772
780
}
773
781
}
774
782
@@ -778,31 +786,21 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
778
786
{
779
787
#[ inline]
780
788
fn next_back ( & mut self ) -> Option < I :: Item > {
781
- self . try_rfold ( ( ) , |_ , x| Err ( x ) ) . err ( )
789
+ self . iter . rfind ( & mut self . predicate )
782
790
}
783
791
784
792
#[ 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
786
794
Self : Sized , Fold : FnMut ( Acc , Self :: Item ) -> R , R : Try < Ok =Acc >
787
795
{
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) )
794
797
}
795
798
796
799
#[ inline]
797
- fn rfold < Acc , Fold > ( self , init : Acc , mut fold : Fold ) -> Acc
800
+ fn rfold < Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
798
801
where Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
799
802
{
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) )
806
804
}
807
805
}
808
806
@@ -839,6 +837,26 @@ impl<I: fmt::Debug, F> fmt::Debug for FilterMap<I, F> {
839
837
}
840
838
}
841
839
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
+
842
860
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
843
861
impl < B , I : Iterator , F > Iterator for FilterMap < I , F >
844
862
where F : FnMut ( I :: Item ) -> Option < B > ,
@@ -847,7 +865,7 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
847
865
848
866
#[ inline]
849
867
fn next ( & mut self ) -> Option < B > {
850
- self . try_for_each ( Err ) . err ( )
868
+ self . iter . find_map ( & mut self . f )
851
869
}
852
870
853
871
#[ inline]
@@ -857,25 +875,17 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
857
875
}
858
876
859
877
#[ 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
861
879
Self : Sized , Fold : FnMut ( Acc , Self :: Item ) -> R , R : Try < Ok =Acc >
862
880
{
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) )
868
882
}
869
883
870
884
#[ inline]
871
- fn fold < Acc , Fold > ( self , init : Acc , mut fold : Fold ) -> Acc
885
+ fn fold < Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
872
886
where Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
873
887
{
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) )
879
889
}
880
890
}
881
891
@@ -885,29 +895,31 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
885
895
{
886
896
#[ inline]
887
897
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 ( )
889
909
}
890
910
891
911
#[ 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
893
913
Self : Sized , Fold : FnMut ( Acc , Self :: Item ) -> R , R : Try < Ok =Acc >
894
914
{
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) )
900
916
}
901
917
902
918
#[ inline]
903
- fn rfold < Acc , Fold > ( self , init : Acc , mut fold : Fold ) -> Acc
919
+ fn rfold < Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
904
920
where Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
905
921
{
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) )
911
923
}
912
924
}
913
925
0 commit comments