@@ -161,21 +161,35 @@ macro_rules! slice_offset {
161161 ( $ptr: expr, $by: expr) => { {
162162 let ptr = $ptr;
163163 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 _
165165 } else {
166166 ptr. offset( $by)
167167 }
168168 } } ;
169169}
170170
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 {
172186 ( $ptr: expr) => { {
173187 let ptr = $ptr;
174188 if size_from_ptr( ptr) == 0 {
175189 // Use a non-null pointer value
176190 & mut * ( 1 as * mut _)
177191 } else {
178- mem :: transmute ( ptr)
192+ & mut * ptr
179193 }
180194 } } ;
181195}
@@ -796,7 +810,7 @@ fn size_from_ptr<T>(_: *const T) -> usize {
796810
797811// The shared definition of the `Iter` and `IterMut` iterators
798812macro_rules! iterator {
799- ( struct $name: ident -> $ptr: ty, $elem: ty) => {
813+ ( struct $name: ident -> $ptr: ty, $elem: ty, $mkref : ident ) => {
800814 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
801815 impl <' a, T > Iterator for $name<' a, T > {
802816 type Item = $elem;
@@ -812,9 +826,7 @@ macro_rules! iterator {
812826 if self . ptr == self . end {
813827 None
814828 } 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( ) ) )
818830 }
819831 }
820832 }
@@ -857,8 +869,7 @@ macro_rules! iterator {
857869 if self . end == self . ptr {
858870 None
859871 } else {
860- self . end = slice_offset!( self . end, -1 ) ;
861- Some ( slice_ref!( self . end) )
872+ Some ( $mkref!( self . end. pre_dec( ) ) )
862873 }
863874 }
864875 }
@@ -980,7 +991,7 @@ impl<'a, T> Iter<'a, T> {
980991 }
981992}
982993
983- iterator ! { struct Iter -> * const T , & ' a T }
994+ iterator ! { struct Iter -> * const T , & ' a T , make_ref }
984995
985996#[ stable( feature = "rust1" , since = "1.0.0" ) ]
986997impl < ' a , T > ExactSizeIterator for Iter < ' a , T > { }
@@ -1104,7 +1115,7 @@ impl<'a, T> IterMut<'a, T> {
11041115 }
11051116}
11061117
1107- iterator ! { struct IterMut -> * mut T , & ' a mut T }
1118+ iterator ! { struct IterMut -> * mut T , & ' a mut T , make_ref_mut }
11081119
11091120#[ stable( feature = "rust1" , since = "1.0.0" ) ]
11101121impl < ' a , T > ExactSizeIterator for IterMut < ' a , T > { }
@@ -1115,6 +1126,41 @@ impl<'a, T> FusedIterator for IterMut<'a, T> {}
11151126#[ unstable( feature = "trusted_len" , issue = "37572" ) ]
11161127unsafe impl < ' a , T > TrustedLen for IterMut < ' a , T > { }
11171128
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+
11181164/// An internal abstraction over the splitting iterators, so that
11191165/// splitn, splitn_mut etc can be implemented once.
11201166#[ doc( hidden) ]
0 commit comments