@@ -172,21 +172,35 @@ macro_rules! slice_offset {
172
172
( $ptr: expr, $by: expr) => { {
173
173
let ptr = $ptr;
174
174
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 _
176
176
} else {
177
177
ptr. offset( $by)
178
178
}
179
179
} } ;
180
180
}
181
181
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 {
183
197
( $ptr: expr) => { {
184
198
let ptr = $ptr;
185
199
if size_from_ptr( ptr) == 0 {
186
200
// Use a non-null pointer value
187
201
& mut * ( 1 as * mut _)
188
202
} else {
189
- mem :: transmute ( ptr)
203
+ & mut * ptr
190
204
}
191
205
} } ;
192
206
}
@@ -963,7 +977,7 @@ fn size_from_ptr<T>(_: *const T) -> usize {
963
977
964
978
// The shared definition of the `Iter` and `IterMut` iterators
965
979
macro_rules! iterator {
966
- ( struct $name: ident -> $ptr: ty, $elem: ty) => {
980
+ ( struct $name: ident -> $ptr: ty, $elem: ty, $mkref : ident ) => {
967
981
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
968
982
impl <' a, T > Iterator for $name<' a, T > {
969
983
type Item = $elem;
@@ -979,18 +993,14 @@ macro_rules! iterator {
979
993
if self . ptr == self . end {
980
994
None
981
995
} 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( ) ) )
985
997
}
986
998
}
987
999
}
988
1000
989
1001
#[ inline]
990
1002
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) ;
994
1004
( exact, Some ( exact) )
995
1005
}
996
1006
@@ -1009,6 +1019,64 @@ macro_rules! iterator {
1009
1019
fn last( mut self ) -> Option <$elem> {
1010
1020
self . next_back( )
1011
1021
}
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
+ }
1012
1080
}
1013
1081
1014
1082
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1024,10 +1092,51 @@ macro_rules! iterator {
1024
1092
if self . end == self . ptr {
1025
1093
None
1026
1094
} 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( ) ) ) ) ;
1029
1137
}
1030
1138
}
1139
+ default
1031
1140
}
1032
1141
}
1033
1142
}
@@ -1061,6 +1170,24 @@ macro_rules! make_mut_slice {
1061
1170
} }
1062
1171
}
1063
1172
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
+
1064
1191
/// Immutable slice iterator
1065
1192
///
1066
1193
/// This struct is created by the [`iter`] method on [slices].
@@ -1147,7 +1274,7 @@ impl<'a, T> Iter<'a, T> {
1147
1274
}
1148
1275
}
1149
1276
1150
- iterator ! { struct Iter -> * const T , & ' a T }
1277
+ iterator ! { struct Iter -> * const T , & ' a T , make_ref }
1151
1278
1152
1279
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1153
1280
impl < ' a , T > ExactSizeIterator for Iter < ' a , T > {
@@ -1275,7 +1402,7 @@ impl<'a, T> IterMut<'a, T> {
1275
1402
}
1276
1403
}
1277
1404
1278
- iterator ! { struct IterMut -> * mut T , & ' a mut T }
1405
+ iterator ! { struct IterMut -> * mut T , & ' a mut T , make_ref_mut }
1279
1406
1280
1407
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1281
1408
impl < ' a , T > ExactSizeIterator for IterMut < ' a , T > {
@@ -1290,6 +1417,50 @@ impl<'a, T> FusedIterator for IterMut<'a, T> {}
1290
1417
#[ unstable( feature = "trusted_len" , issue = "37572" ) ]
1291
1418
unsafe impl < ' a , T > TrustedLen for IterMut < ' a , T > { }
1292
1419
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
+
1293
1464
/// An internal abstraction over the splitting iterators, so that
1294
1465
/// splitn, splitn_mut etc can be implemented once.
1295
1466
#[ doc( hidden) ]
0 commit comments