@@ -748,13 +748,27 @@ impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> {
748
748
}
749
749
}
750
750
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
+
751
765
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
752
766
impl < I : Iterator , P > Iterator for Filter < I , P > where P : FnMut ( & I :: Item ) -> bool {
753
767
type Item = I :: Item ;
754
768
755
769
#[ inline]
756
770
fn next ( & mut self ) -> Option < I :: Item > {
757
- self . try_for_each ( Err ) . err ( )
771
+ self . iter . find ( & mut self . predicate )
758
772
}
759
773
760
774
#[ inline]
@@ -776,32 +790,26 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
776
790
// leaving more budget for LLVM optimizations.
777
791
#[ inline]
778
792
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 ( )
781
799
}
782
800
783
801
#[ 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
785
803
Self : Sized , Fold : FnMut ( Acc , Self :: Item ) -> R , R : Try < Ok =Acc >
786
804
{
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) )
793
806
}
794
807
795
808
#[ inline]
796
- fn fold < Acc , Fold > ( self , init : Acc , mut fold : Fold ) -> Acc
809
+ fn fold < Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
797
810
where Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
798
811
{
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) )
805
813
}
806
814
}
807
815
@@ -811,31 +819,21 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
811
819
{
812
820
#[ inline]
813
821
fn next_back ( & mut self ) -> Option < I :: Item > {
814
- self . try_rfold ( ( ) , |_ , x| Err ( x ) ) . err ( )
822
+ self . iter . rfind ( & mut self . predicate )
815
823
}
816
824
817
825
#[ 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
819
827
Self : Sized , Fold : FnMut ( Acc , Self :: Item ) -> R , R : Try < Ok =Acc >
820
828
{
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) )
827
830
}
828
831
829
832
#[ inline]
830
- fn rfold < Acc , Fold > ( self , init : Acc , mut fold : Fold ) -> Acc
833
+ fn rfold < Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
831
834
where Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
832
835
{
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) )
839
837
}
840
838
}
841
839
@@ -872,6 +870,26 @@ impl<I: fmt::Debug, F> fmt::Debug for FilterMap<I, F> {
872
870
}
873
871
}
874
872
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
+
875
893
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
876
894
impl < B , I : Iterator , F > Iterator for FilterMap < I , F >
877
895
where F : FnMut ( I :: Item ) -> Option < B > ,
@@ -880,7 +898,7 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
880
898
881
899
#[ inline]
882
900
fn next ( & mut self ) -> Option < B > {
883
- self . try_for_each ( Err ) . err ( )
901
+ self . iter . find_map ( & mut self . f )
884
902
}
885
903
886
904
#[ inline]
@@ -890,25 +908,17 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
890
908
}
891
909
892
910
#[ 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
894
912
Self : Sized , Fold : FnMut ( Acc , Self :: Item ) -> R , R : Try < Ok =Acc >
895
913
{
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) )
901
915
}
902
916
903
917
#[ inline]
904
- fn fold < Acc , Fold > ( self , init : Acc , mut fold : Fold ) -> Acc
918
+ fn fold < Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
905
919
where Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
906
920
{
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) )
912
922
}
913
923
}
914
924
@@ -918,29 +928,31 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
918
928
{
919
929
#[ inline]
920
930
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 ( )
922
942
}
923
943
924
944
#[ 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
926
946
Self : Sized , Fold : FnMut ( Acc , Self :: Item ) -> R , R : Try < Ok =Acc >
927
947
{
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) )
933
949
}
934
950
935
951
#[ inline]
936
- fn rfold < Acc , Fold > ( self , init : Acc , mut fold : Fold ) -> Acc
952
+ fn rfold < Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
937
953
where Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
938
954
{
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) )
944
956
}
945
957
}
946
958
0 commit comments