@@ -852,6 +852,64 @@ macro_rules! iterator {
852
852
fn last( mut self ) -> Option <$elem> {
853
853
self . next_back( )
854
854
}
855
+
856
+ fn all<F >( & mut self , mut predicate: F ) -> bool
857
+ where F : FnMut ( Self :: Item ) -> bool ,
858
+ {
859
+ self . search_while( true , move |elt| {
860
+ if predicate( elt) {
861
+ SearchWhile :: Continue
862
+ } else {
863
+ SearchWhile :: Done ( false )
864
+ }
865
+ } )
866
+ }
867
+
868
+ fn any<F >( & mut self , mut predicate: F ) -> bool
869
+ where F : FnMut ( Self :: Item ) -> bool ,
870
+ {
871
+ !self . all( move |elt| !predicate( elt) )
872
+ }
873
+
874
+ fn find<F >( & mut self , mut predicate: F ) -> Option <Self :: Item >
875
+ where F : FnMut ( & Self :: Item ) -> bool ,
876
+ {
877
+ self . search_while( None , move |elt| {
878
+ if predicate( & elt) {
879
+ SearchWhile :: Done ( Some ( elt) )
880
+ } else {
881
+ SearchWhile :: Continue
882
+ }
883
+ } )
884
+ }
885
+
886
+ fn position<F >( & mut self , mut predicate: F ) -> Option <usize >
887
+ where F : FnMut ( Self :: Item ) -> bool ,
888
+ {
889
+ let mut index = 0 ;
890
+ self . search_while( None , move |elt| {
891
+ if predicate( elt) {
892
+ SearchWhile :: Done ( Some ( index) )
893
+ } else {
894
+ index += 1 ;
895
+ SearchWhile :: Continue
896
+ }
897
+ } )
898
+ }
899
+
900
+ fn rposition<F >( & mut self , mut predicate: F ) -> Option <usize >
901
+ where F : FnMut ( Self :: Item ) -> bool ,
902
+ {
903
+ let mut index = self . len( ) ;
904
+ self . rsearch_while( None , move |elt| {
905
+ index -= 1 ;
906
+ if predicate( elt) {
907
+ SearchWhile :: Done ( Some ( index) )
908
+ } else {
909
+ SearchWhile :: Continue
910
+ }
911
+ } )
912
+ }
855
913
}
856
914
857
915
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -872,6 +930,48 @@ macro_rules! iterator {
872
930
}
873
931
}
874
932
}
933
+
934
+ // search_while is a generalization of the internal iteration methods.
935
+ impl <' a, T > $name<' a, T > {
936
+ // search through the iterator's element using the closure `g`.
937
+ // if no element was found, return `default`.
938
+ fn search_while<Acc , G >( & mut self , default : Acc , mut g: G ) -> Acc
939
+ where Self : Sized ,
940
+ G : FnMut ( $elem) -> SearchWhile <Acc >
941
+ {
942
+ // manual unrolling is needed when there are conditional exits from the loop
943
+ unsafe {
944
+ while ptrdistance( self . ptr, self . end) >= 4 {
945
+ search_while!( g( $mkref!( self . ptr. post_inc( ) ) ) ) ;
946
+ search_while!( g( $mkref!( self . ptr. post_inc( ) ) ) ) ;
947
+ search_while!( g( $mkref!( self . ptr. post_inc( ) ) ) ) ;
948
+ search_while!( g( $mkref!( self . ptr. post_inc( ) ) ) ) ;
949
+ }
950
+ while self . ptr != self . end {
951
+ search_while!( g( $mkref!( self . ptr. post_inc( ) ) ) ) ;
952
+ }
953
+ }
954
+ default
955
+ }
956
+
957
+ fn rsearch_while<Acc , G >( & mut self , default : Acc , mut g: G ) -> Acc
958
+ where Self : Sized ,
959
+ G : FnMut ( $elem) -> SearchWhile <Acc >
960
+ {
961
+ unsafe {
962
+ while ptrdistance( self . ptr, self . end) >= 4 {
963
+ search_while!( g( $mkref!( self . end. pre_dec( ) ) ) ) ;
964
+ search_while!( g( $mkref!( self . end. pre_dec( ) ) ) ) ;
965
+ search_while!( g( $mkref!( self . end. pre_dec( ) ) ) ) ;
966
+ search_while!( g( $mkref!( self . end. pre_dec( ) ) ) ) ;
967
+ }
968
+ while self . ptr != self . end {
969
+ search_while!( g( $mkref!( self . end. pre_dec( ) ) ) ) ;
970
+ }
971
+ }
972
+ default
973
+ }
974
+ }
875
975
}
876
976
}
877
977
@@ -903,6 +1003,24 @@ macro_rules! make_mut_slice {
903
1003
} }
904
1004
}
905
1005
1006
+ // An enum used for controlling the execution of `.search_while()`.
1007
+ enum SearchWhile < T > {
1008
+ // Continue searching
1009
+ Continue ,
1010
+ // Fold is complete and will return this value
1011
+ Done ( T ) ,
1012
+ }
1013
+
1014
+ // helper macro for search while's control flow
1015
+ macro_rules! search_while {
1016
+ ( $e: expr) => {
1017
+ match $e {
1018
+ SearchWhile :: Continue => { }
1019
+ SearchWhile :: Done ( done) => return done,
1020
+ }
1021
+ }
1022
+ }
1023
+
906
1024
/// Immutable slice iterator
907
1025
///
908
1026
/// This struct is created by the [`iter`] method on [slices].
0 commit comments