@@ -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" ) ]
752766impl < 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" ) ]
876894impl < 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