@@ -172,21 +172,35 @@ macro_rules! slice_offset {
172172 ( $ptr: expr, $by: expr) => { {
173173 let ptr = $ptr;
174174 if size_from_ptr( ptr) == 0 {
175- :: intrinsics :: arith_offset ( ptr as * mut i8 , $by) as * mut _
175+ ( ptr as * mut i8 ) . wrapping_offset ( $by) as _
176176 } else {
177177 ptr. offset( $by)
178178 }
179179 } } ;
180180}
181181
182- macro_rules! slice_ref {
182+ // make a &T from a *const T
183+ macro_rules! make_ref {
184+ ( $ptr: expr) => { {
185+ let ptr = $ptr;
186+ if size_from_ptr( ptr) == 0 {
187+ // Use a non-null pointer value
188+ & * ( 1 as * mut _)
189+ } else {
190+ & * ptr
191+ }
192+ } } ;
193+ }
194+
195+ // make a &mut T from a *mut T
196+ macro_rules! make_ref_mut {
183197 ( $ptr: expr) => { {
184198 let ptr = $ptr;
185199 if size_from_ptr( ptr) == 0 {
186200 // Use a non-null pointer value
187201 & mut * ( 1 as * mut _)
188202 } else {
189- mem :: transmute ( ptr)
203+ & mut * ptr
190204 }
191205 } } ;
192206}
@@ -963,7 +977,7 @@ fn size_from_ptr<T>(_: *const T) -> usize {
963977
964978// The shared definition of the `Iter` and `IterMut` iterators
965979macro_rules! iterator {
966- ( struct $name: ident -> $ptr: ty, $elem: ty) => {
980+ ( struct $name: ident -> $ptr: ty, $elem: ty, $mkref : ident ) => {
967981 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
968982 impl <' a, T > Iterator for $name<' a, T > {
969983 type Item = $elem;
@@ -979,18 +993,14 @@ macro_rules! iterator {
979993 if self . ptr == self . end {
980994 None
981995 } else {
982- let old = self . ptr;
983- self . ptr = slice_offset!( self . ptr, 1 ) ;
984- Some ( slice_ref!( old) )
996+ Some ( $mkref!( self . ptr. post_inc( ) ) )
985997 }
986998 }
987999 }
9881000
9891001 #[ inline]
9901002 fn size_hint( & self ) -> ( usize , Option <usize >) {
991- let diff = ( self . end as usize ) . wrapping_sub( self . ptr as usize ) ;
992- let size = mem:: size_of:: <T >( ) ;
993- let exact = diff / ( if size == 0 { 1 } else { size} ) ;
1003+ let exact = ptrdistance( self . ptr, self . end) ;
9941004 ( exact, Some ( exact) )
9951005 }
9961006
@@ -1009,6 +1019,64 @@ macro_rules! iterator {
10091019 fn last( mut self ) -> Option <$elem> {
10101020 self . next_back( )
10111021 }
1022+
1023+ fn all<F >( & mut self , mut predicate: F ) -> bool
1024+ where F : FnMut ( Self :: Item ) -> bool ,
1025+ {
1026+ self . search_while( true , move |elt| {
1027+ if predicate( elt) {
1028+ SearchWhile :: Continue
1029+ } else {
1030+ SearchWhile :: Done ( false )
1031+ }
1032+ } )
1033+ }
1034+
1035+ fn any<F >( & mut self , mut predicate: F ) -> bool
1036+ where F : FnMut ( Self :: Item ) -> bool ,
1037+ {
1038+ !self . all( move |elt| !predicate( elt) )
1039+ }
1040+
1041+ fn find<F >( & mut self , mut predicate: F ) -> Option <Self :: Item >
1042+ where F : FnMut ( & Self :: Item ) -> bool ,
1043+ {
1044+ self . search_while( None , move |elt| {
1045+ if predicate( & elt) {
1046+ SearchWhile :: Done ( Some ( elt) )
1047+ } else {
1048+ SearchWhile :: Continue
1049+ }
1050+ } )
1051+ }
1052+
1053+ fn position<F >( & mut self , mut predicate: F ) -> Option <usize >
1054+ where F : FnMut ( Self :: Item ) -> bool ,
1055+ {
1056+ let mut index = 0 ;
1057+ self . search_while( None , move |elt| {
1058+ if predicate( elt) {
1059+ SearchWhile :: Done ( Some ( index) )
1060+ } else {
1061+ index += 1 ;
1062+ SearchWhile :: Continue
1063+ }
1064+ } )
1065+ }
1066+
1067+ fn rposition<F >( & mut self , mut predicate: F ) -> Option <usize >
1068+ where F : FnMut ( Self :: Item ) -> bool ,
1069+ {
1070+ let mut index = self . len( ) ;
1071+ self . rsearch_while( None , move |elt| {
1072+ index -= 1 ;
1073+ if predicate( elt) {
1074+ SearchWhile :: Done ( Some ( index) )
1075+ } else {
1076+ SearchWhile :: Continue
1077+ }
1078+ } )
1079+ }
10121080 }
10131081
10141082 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1024,10 +1092,51 @@ macro_rules! iterator {
10241092 if self . end == self . ptr {
10251093 None
10261094 } else {
1027- self . end = slice_offset!( self . end, -1 ) ;
1028- Some ( slice_ref!( self . end) )
1095+ Some ( $mkref!( self . end. pre_dec( ) ) )
1096+ }
1097+ }
1098+ }
1099+ }
1100+
1101+ // search_while is a generalization of the internal iteration methods.
1102+ impl <' a, T > $name<' a, T > {
1103+ // search through the iterator's element using the closure `g`.
1104+ // if no element was found, return `default`.
1105+ fn search_while<Acc , G >( & mut self , default : Acc , mut g: G ) -> Acc
1106+ where Self : Sized ,
1107+ G : FnMut ( $elem) -> SearchWhile <Acc >
1108+ {
1109+ // manual unrolling is needed when there are conditional exits from the loop
1110+ unsafe {
1111+ while ptrdistance( self . ptr, self . end) >= 4 {
1112+ search_while!( g( $mkref!( self . ptr. post_inc( ) ) ) ) ;
1113+ search_while!( g( $mkref!( self . ptr. post_inc( ) ) ) ) ;
1114+ search_while!( g( $mkref!( self . ptr. post_inc( ) ) ) ) ;
1115+ search_while!( g( $mkref!( self . ptr. post_inc( ) ) ) ) ;
1116+ }
1117+ while self . ptr != self . end {
1118+ search_while!( g( $mkref!( self . ptr. post_inc( ) ) ) ) ;
1119+ }
1120+ }
1121+ default
1122+ }
1123+
1124+ fn rsearch_while<Acc , G >( & mut self , default : Acc , mut g: G ) -> Acc
1125+ where Self : Sized ,
1126+ G : FnMut ( $elem) -> SearchWhile <Acc >
1127+ {
1128+ unsafe {
1129+ while ptrdistance( self . ptr, self . end) >= 4 {
1130+ search_while!( g( $mkref!( self . end. pre_dec( ) ) ) ) ;
1131+ search_while!( g( $mkref!( self . end. pre_dec( ) ) ) ) ;
1132+ search_while!( g( $mkref!( self . end. pre_dec( ) ) ) ) ;
1133+ search_while!( g( $mkref!( self . end. pre_dec( ) ) ) ) ;
1134+ }
1135+ while self . ptr != self . end {
1136+ search_while!( g( $mkref!( self . end. pre_dec( ) ) ) ) ;
10291137 }
10301138 }
1139+ default
10311140 }
10321141 }
10331142 }
@@ -1061,6 +1170,24 @@ macro_rules! make_mut_slice {
10611170 } }
10621171}
10631172
1173+ // An enum used for controlling the execution of `.search_while()`.
1174+ enum SearchWhile < T > {
1175+ // Continue searching
1176+ Continue ,
1177+ // Fold is complete and will return this value
1178+ Done ( T ) ,
1179+ }
1180+
1181+ // helper macro for search while's control flow
1182+ macro_rules! search_while {
1183+ ( $e: expr) => {
1184+ match $e {
1185+ SearchWhile :: Continue => { }
1186+ SearchWhile :: Done ( done) => return done,
1187+ }
1188+ }
1189+ }
1190+
10641191/// Immutable slice iterator
10651192///
10661193/// This struct is created by the [`iter`] method on [slices].
@@ -1147,7 +1274,7 @@ impl<'a, T> Iter<'a, T> {
11471274 }
11481275}
11491276
1150- iterator ! { struct Iter -> * const T , & ' a T }
1277+ iterator ! { struct Iter -> * const T , & ' a T , make_ref }
11511278
11521279#[ stable( feature = "rust1" , since = "1.0.0" ) ]
11531280impl < ' a , T > ExactSizeIterator for Iter < ' a , T > {
@@ -1275,7 +1402,7 @@ impl<'a, T> IterMut<'a, T> {
12751402 }
12761403}
12771404
1278- iterator ! { struct IterMut -> * mut T , & ' a mut T }
1405+ iterator ! { struct IterMut -> * mut T , & ' a mut T , make_ref_mut }
12791406
12801407#[ stable( feature = "rust1" , since = "1.0.0" ) ]
12811408impl < ' a , T > ExactSizeIterator for IterMut < ' a , T > {
@@ -1290,6 +1417,50 @@ impl<'a, T> FusedIterator for IterMut<'a, T> {}
12901417#[ unstable( feature = "trusted_len" , issue = "37572" ) ]
12911418unsafe impl < ' a , T > TrustedLen for IterMut < ' a , T > { }
12921419
1420+
1421+ // Return the number of elements of `T` from `start` to `end`.
1422+ // Return the arithmetic difference if `T` is zero size.
1423+ #[ inline( always) ]
1424+ fn ptrdistance < T > ( start : * const T , end : * const T ) -> usize {
1425+ let diff = ( end as usize ) . wrapping_sub ( start as usize ) ;
1426+ let size = mem:: size_of :: < T > ( ) ;
1427+ diff / ( if size == 0 { 1 } else { size } )
1428+ }
1429+
1430+ // Extension methods for raw pointers, used by the iterators
1431+ trait PointerExt : Copy {
1432+ unsafe fn slice_offset ( self , i : isize ) -> Self ;
1433+
1434+ /// Increment self by 1, but return the old value
1435+ #[ inline( always) ]
1436+ unsafe fn post_inc ( & mut self ) -> Self {
1437+ let current = * self ;
1438+ * self = self . slice_offset ( 1 ) ;
1439+ current
1440+ }
1441+
1442+ /// Decrement self by 1, and return the new value
1443+ #[ inline( always) ]
1444+ unsafe fn pre_dec ( & mut self ) -> Self {
1445+ * self = self . slice_offset ( -1 ) ;
1446+ * self
1447+ }
1448+ }
1449+
1450+ impl < T > PointerExt for * const T {
1451+ #[ inline( always) ]
1452+ unsafe fn slice_offset ( self , i : isize ) -> Self {
1453+ slice_offset ! ( self , i)
1454+ }
1455+ }
1456+
1457+ impl < T > PointerExt for * mut T {
1458+ #[ inline( always) ]
1459+ unsafe fn slice_offset ( self , i : isize ) -> Self {
1460+ slice_offset ! ( self , i)
1461+ }
1462+ }
1463+
12931464/// An internal abstraction over the splitting iterators, so that
12941465/// splitn, splitn_mut etc can be implemented once.
12951466#[ doc( hidden) ]
0 commit comments