@@ -674,51 +674,13 @@ macro_rules! iterator {
674674
675675 #[ inline]
676676 fn nth( & mut self , n: usize ) -> Option <$elem> {
677- // could be implemented with slices, but this avoids bounds checks
678- unsafe {
679- :: intrinsics:: assume( !self . ptr. is_null( ) ) ;
680- :: intrinsics:: assume( !self . end. is_null( ) ) ;
681- // There should be some way to use offset and optimize this to LEA but I don't
682- // know how to do that AND detect overflow...
683- let size = mem:: size_of:: <T >( ) ;
684- if size == 0 {
685- if let Some ( new_ptr) = ( self . ptr as usize ) . checked_add( n) {
686- if new_ptr < ( self . end as usize ) {
687- self . ptr = transmute( new_ptr + 1 ) ;
688- return Some ( & mut * ( 1 as * mut _) )
689- }
690- }
691- } else {
692- if let Some ( new_ptr) = n. checked_mul( size) . and_then( |offset| {
693- ( self . ptr as usize ) . checked_add( offset)
694- } ) {
695- if new_ptr < ( self . end as usize ) {
696- self . ptr = transmute( new_ptr + size) ;
697- return Some ( transmute( new_ptr) )
698- }
699- }
700- }
701- None
702- }
677+ // Call helper method. Can't put the definition here because mut versus const.
678+ self . iter_nth( n)
703679 }
704680
705681 #[ inline]
706- fn last( self ) -> Option <$elem> {
707- // We could just call next_back but this avoids the memory write.
708- unsafe {
709- :: intrinsics:: assume( !self . ptr. is_null( ) ) ;
710- :: intrinsics:: assume( !self . end. is_null( ) ) ;
711- if self . end == self . ptr {
712- None
713- } else {
714- if mem:: size_of:: <T >( ) == 0 {
715- // Use a non-null pointer value
716- Some ( & mut * ( 1 as * mut _) )
717- } else {
718- Some ( transmute( self . end. offset( -1 ) ) )
719- }
720- }
721- }
682+ fn last( mut self ) -> Option <$elem> {
683+ self . next_back( )
722684 }
723685 }
724686
@@ -839,6 +801,27 @@ impl<'a, T> Iter<'a, T> {
839801 pub fn as_slice ( & self ) -> & ' a [ T ] {
840802 make_slice ! ( T => & ' a [ T ] : self . ptr, self . end)
841803 }
804+
805+ // Helper function for Iter::nth
806+ fn iter_nth ( & mut self , n : usize ) -> Option < & ' a T > {
807+ 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+ } ,
819+ None => {
820+ self . ptr = self . end ;
821+ None
822+ }
823+ }
824+ }
842825}
843826
844827iterator ! { struct Iter -> * const T , & ' a T }
@@ -968,6 +951,27 @@ impl<'a, T> IterMut<'a, T> {
968951 pub fn into_slice ( self ) -> & ' a mut [ T ] {
969952 make_mut_slice ! ( T => & ' a mut [ T ] : self . ptr, self . end)
970953 }
954+
955+ // Helper function for IterMut::nth
956+ fn iter_nth ( & mut self , n : usize ) -> Option < & ' a mut T > {
957+ 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+ }
968+ } ,
969+ None => {
970+ self . ptr = self . end ;
971+ None
972+ }
973+ }
974+ }
971975}
972976
973977iterator ! { struct IterMut -> * mut T , & ' a mut T }
0 commit comments