@@ -161,21 +161,35 @@ macro_rules! slice_offset {
161
161
( $ptr: expr, $by: expr) => { {
162
162
let ptr = $ptr;
163
163
if size_from_ptr( ptr) == 0 {
164
- :: intrinsics :: arith_offset ( ptr as * mut i8 , $by) as * mut _
164
+ ( ptr as * mut i8 ) . wrapping_offset ( $by) as _
165
165
} else {
166
166
ptr. offset( $by)
167
167
}
168
168
} } ;
169
169
}
170
170
171
- macro_rules! slice_ref {
171
+ // make a &T from a *const T
172
+ macro_rules! make_ref {
173
+ ( $ptr: expr) => { {
174
+ let ptr = $ptr;
175
+ if size_from_ptr( ptr) == 0 {
176
+ // Use a non-null pointer value
177
+ & * ( 1 as * mut _)
178
+ } else {
179
+ & * ptr
180
+ }
181
+ } } ;
182
+ }
183
+
184
+ // make a &mut T from a *mut T
185
+ macro_rules! make_ref_mut {
172
186
( $ptr: expr) => { {
173
187
let ptr = $ptr;
174
188
if size_from_ptr( ptr) == 0 {
175
189
// Use a non-null pointer value
176
190
& mut * ( 1 as * mut _)
177
191
} else {
178
- mem :: transmute ( ptr)
192
+ & mut * ptr
179
193
}
180
194
} } ;
181
195
}
@@ -796,7 +810,7 @@ fn size_from_ptr<T>(_: *const T) -> usize {
796
810
797
811
// The shared definition of the `Iter` and `IterMut` iterators
798
812
macro_rules! iterator {
799
- ( struct $name: ident -> $ptr: ty, $elem: ty) => {
813
+ ( struct $name: ident -> $ptr: ty, $elem: ty, $mkref : ident ) => {
800
814
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
801
815
impl <' a, T > Iterator for $name<' a, T > {
802
816
type Item = $elem;
@@ -812,9 +826,7 @@ macro_rules! iterator {
812
826
if self . ptr == self . end {
813
827
None
814
828
} else {
815
- let old = self . ptr;
816
- self . ptr = slice_offset!( self . ptr, 1 ) ;
817
- Some ( slice_ref!( old) )
829
+ Some ( $mkref!( self . ptr. post_inc( ) ) )
818
830
}
819
831
}
820
832
}
@@ -857,8 +869,7 @@ macro_rules! iterator {
857
869
if self . end == self . ptr {
858
870
None
859
871
} else {
860
- self . end = slice_offset!( self . end, -1 ) ;
861
- Some ( slice_ref!( self . end) )
872
+ Some ( $mkref!( self . end. pre_dec( ) ) )
862
873
}
863
874
}
864
875
}
@@ -980,7 +991,7 @@ impl<'a, T> Iter<'a, T> {
980
991
}
981
992
}
982
993
983
- iterator ! { struct Iter -> * const T , & ' a T }
994
+ iterator ! { struct Iter -> * const T , & ' a T , make_ref }
984
995
985
996
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
986
997
impl < ' a , T > ExactSizeIterator for Iter < ' a , T > { }
@@ -1104,7 +1115,7 @@ impl<'a, T> IterMut<'a, T> {
1104
1115
}
1105
1116
}
1106
1117
1107
- iterator ! { struct IterMut -> * mut T , & ' a mut T }
1118
+ iterator ! { struct IterMut -> * mut T , & ' a mut T , make_ref_mut }
1108
1119
1109
1120
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1110
1121
impl < ' a , T > ExactSizeIterator for IterMut < ' a , T > { }
@@ -1115,6 +1126,41 @@ impl<'a, T> FusedIterator for IterMut<'a, T> {}
1115
1126
#[ unstable( feature = "trusted_len" , issue = "37572" ) ]
1116
1127
unsafe impl < ' a , T > TrustedLen for IterMut < ' a , T > { }
1117
1128
1129
+
1130
+ // Extension methods for raw pointers, used by the iterators
1131
+ trait PointerExt : Copy {
1132
+ unsafe fn slice_offset ( self , i : isize ) -> Self ;
1133
+
1134
+ /// Increment self by 1, but return the old value
1135
+ #[ inline( always) ]
1136
+ unsafe fn post_inc ( & mut self ) -> Self {
1137
+ let current = * self ;
1138
+ * self = self . slice_offset ( 1 ) ;
1139
+ current
1140
+ }
1141
+
1142
+ /// Decrement self by 1, and return the new value
1143
+ #[ inline( always) ]
1144
+ unsafe fn pre_dec ( & mut self ) -> Self {
1145
+ * self = self . slice_offset ( -1 ) ;
1146
+ * self
1147
+ }
1148
+ }
1149
+
1150
+ impl < T > PointerExt for * const T {
1151
+ #[ inline( always) ]
1152
+ unsafe fn slice_offset ( self , i : isize ) -> Self {
1153
+ slice_offset ! ( self , i)
1154
+ }
1155
+ }
1156
+
1157
+ impl < T > PointerExt for * mut T {
1158
+ #[ inline( always) ]
1159
+ unsafe fn slice_offset ( self , i : isize ) -> Self {
1160
+ slice_offset ! ( self , i)
1161
+ }
1162
+ }
1163
+
1118
1164
/// An internal abstraction over the splitting iterators, so that
1119
1165
/// splitn, splitn_mut etc can be implemented once.
1120
1166
#[ doc( hidden) ]
0 commit comments