@@ -852,6 +852,64 @@ macro_rules! iterator {
852852 fn last( mut self ) -> Option <$elem> {
853853 self . next_back( )
854854 }
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+ }
855913 }
856914
857915 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -872,6 +930,48 @@ macro_rules! iterator {
872930 }
873931 }
874932 }
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+ }
875975 }
876976}
877977
@@ -903,6 +1003,24 @@ macro_rules! make_mut_slice {
9031003 } }
9041004}
9051005
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+
9061024/// Immutable slice iterator
9071025///
9081026/// This struct is created by the [`iter`] method on [slices].
0 commit comments