@@ -625,6 +625,36 @@ impl<'a, T> IntoIterator for &'a mut [T] {
625625 }
626626}
627627
628+ #[ inline( always) ]
629+ fn size_from_ptr < T > ( _: * const T ) -> usize {
630+ mem:: size_of :: < T > ( )
631+ }
632+
633+
634+ // Use macro to be generic over const/mut
635+ macro_rules! slice_offset {
636+ ( $ptr: expr, $by: expr) => { {
637+ let ptr = $ptr;
638+ if size_from_ptr( ptr) == 0 {
639+ transmute( ptr as usize + $by)
640+ } else {
641+ ptr. offset( $by)
642+ }
643+ } } ;
644+ }
645+
646+ macro_rules! slice_ref {
647+ ( $ptr: expr) => { {
648+ let ptr = $ptr;
649+ if size_from_ptr( ptr) == 0 {
650+ // Use a non-null pointer value
651+ & mut * ( 1 as * mut _)
652+ } else {
653+ transmute( ptr)
654+ }
655+ } } ;
656+ }
657+
628658// The shared definition of the `Iter` and `IterMut` iterators
629659macro_rules! iterator {
630660 ( struct $name: ident -> $ptr: ty, $elem: ty) => {
@@ -641,20 +671,9 @@ macro_rules! iterator {
641671 if self . ptr == self . end {
642672 None
643673 } else {
644- if mem:: size_of:: <T >( ) == 0 {
645- // purposefully don't use 'ptr.offset' because for
646- // vectors with 0-size elements this would return the
647- // same pointer.
648- self . ptr = transmute( self . ptr as usize + 1 ) ;
649-
650- // Use a non-null pointer value
651- Some ( & mut * ( 1 as * mut _) )
652- } else {
653- let old = self . ptr;
654- self . ptr = self . ptr. offset( 1 ) ;
655-
656- Some ( transmute( old) )
657- }
674+ let old = self . ptr;
675+ self . ptr = slice_offset!( self . ptr, 1 ) ;
676+ Some ( slice_ref!( old) )
658677 }
659678 }
660679 }
@@ -695,17 +714,8 @@ macro_rules! iterator {
695714 if self . end == self . ptr {
696715 None
697716 } else {
698- if mem:: size_of:: <T >( ) == 0 {
699- // See above for why 'ptr.offset' isn't used
700- self . end = transmute( self . end as usize - 1 ) ;
701-
702- // Use a non-null pointer value
703- Some ( & mut * ( 1 as * mut _) )
704- } else {
705- self . end = self . end. offset( -1 ) ;
706-
707- Some ( transmute( self . end) )
708- }
717+ self . end = slice_offset!( self . end, -1 ) ;
718+ Some ( slice_ref!( self . end) )
709719 }
710720 }
711721 }
@@ -805,16 +815,9 @@ impl<'a, T> Iter<'a, T> {
805815 // Helper function for Iter::nth
806816 fn iter_nth ( & mut self , n : usize ) -> Option < & ' a T > {
807817 match self . as_slice ( ) . get ( n) {
808- Some ( elem_ref) => if mem:: size_of :: < T > ( ) == 0 {
809- unsafe {
810- self . ptr = transmute ( ( elem_ref as * const _ ) as usize + 1 ) ;
811- Some ( & * ( 1 as * const _ ) )
812- }
813- } else {
814- unsafe {
815- self . ptr = ( elem_ref as * const _ ) . offset ( 1 ) ;
816- Some ( elem_ref)
817- }
818+ Some ( elem_ref) => unsafe {
819+ self . ptr = slice_offset ! ( elem_ref as * const _, 1 ) ;
820+ Some ( slice_ref ! ( elem_ref) )
818821 } ,
819822 None => {
820823 self . ptr = self . end ;
@@ -955,16 +958,9 @@ impl<'a, T> IterMut<'a, T> {
955958 // Helper function for IterMut::nth
956959 fn iter_nth ( & mut self , n : usize ) -> Option < & ' a mut T > {
957960 match make_mut_slice ! ( T => & ' a mut [ T ] : self . ptr, self . end) . get_mut ( n) {
958- Some ( elem_ref) => if mem:: size_of :: < T > ( ) == 0 {
959- unsafe {
960- self . ptr = transmute ( ( elem_ref as * mut _ ) as usize + 1 ) ;
961- Some ( & mut * ( 1 as * mut _ ) )
962- }
963- } else {
964- unsafe {
965- self . ptr = ( elem_ref as * mut _ ) . offset ( 1 ) ;
966- Some ( elem_ref)
967- }
961+ Some ( elem_ref) => unsafe {
962+ self . ptr = slice_offset ! ( elem_ref as * mut _, 1 ) ;
963+ Some ( slice_ref ! ( elem_ref) )
968964 } ,
969965 None => {
970966 self . ptr = self . end ;
0 commit comments