@@ -64,8 +64,8 @@ use cmp::Ord;
6464use default:: Default ;
6565use marker;
6666use mem;
67- use num:: { ToPrimitive , Int } ;
68- use ops:: { Add , FnMut , RangeFrom } ;
67+ use num:: { Int , Zero , One , ToPrimitive } ;
68+ use ops:: { Add , Sub , FnMut , RangeFrom } ;
6969use option:: Option ;
7070use option:: Option :: { Some , None } ;
7171use marker:: Sized ;
@@ -843,9 +843,8 @@ pub trait Iterator {
843843 ///
844844 /// ```
845845 /// # #![feature(core)]
846- /// use std::num::SignedInt;
847846 ///
848- /// let a = [-3 , 0, 1, 5, -10];
847+ /// let a = [-3_i32 , 0, 1, 5, -10];
849848 /// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10);
850849 /// ```
851850 #[ inline]
@@ -875,9 +874,8 @@ pub trait Iterator {
875874 ///
876875 /// ```
877876 /// # #![feature(core)]
878- /// use std::num::SignedInt;
879877 ///
880- /// let a = [-3 , 0, 1, 5, -10];
878+ /// let a = [-3_i32 , 0, 1, 5, -10];
881879 /// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0);
882880 /// ```
883881 #[ inline]
@@ -2417,6 +2415,67 @@ impl<A, St, F> Iterator for Unfold<St, F> where F: FnMut(&mut St) -> Option<A> {
24172415 }
24182416}
24192417
2418+ /// Objects that can be stepped over in both directions.
2419+ ///
2420+ /// The `steps_between` function provides a way to efficiently compare
2421+ /// two `Step` objects.
2422+ #[ unstable( feature = "step_trait" ,
2423+ reason = "likely to be replaced by finer-grained traits" ) ]
2424+ pub trait Step : Ord {
2425+ /// Steps `self` if possible.
2426+ fn step ( & self , by : & Self ) -> Option < Self > ;
2427+
2428+ /// The number of steps between two step objects.
2429+ ///
2430+ /// `start` should always be less than `end`, so the result should never
2431+ /// be negative.
2432+ ///
2433+ /// Return `None` if it is not possible to calculate steps_between
2434+ /// without overflow.
2435+ fn steps_between ( start : & Self , end : & Self , by : & Self ) -> Option < usize > ;
2436+ }
2437+
2438+ macro_rules! step_impl {
2439+ ( $( $t: ty) * ) => ( $(
2440+ impl Step for $t {
2441+ #[ inline]
2442+ fn step( & self , by: & $t) -> Option <$t> {
2443+ ( * self ) . checked_add( * by)
2444+ }
2445+ #[ inline]
2446+ #[ allow( trivial_numeric_casts) ]
2447+ fn steps_between( start: & $t, end: & $t, by: & $t) -> Option <usize > {
2448+ if * start <= * end {
2449+ Some ( ( ( * end - * start) / * by) as usize )
2450+ } else {
2451+ Some ( 0 )
2452+ }
2453+ }
2454+ }
2455+ ) * )
2456+ }
2457+
2458+ macro_rules! step_impl_no_between {
2459+ ( $( $t: ty) * ) => ( $(
2460+ impl Step for $t {
2461+ #[ inline]
2462+ fn step( & self , by: & $t) -> Option <$t> {
2463+ ( * self ) . checked_add( * by)
2464+ }
2465+ #[ inline]
2466+ fn steps_between( _a: & $t, _b: & $t, _by: & $t) -> Option <usize > {
2467+ None
2468+ }
2469+ }
2470+ ) * )
2471+ }
2472+
2473+ step_impl ! ( usize u8 u16 u32 isize i8 i16 i32 ) ;
2474+ #[ cfg( target_pointer_width = "64" ) ]
2475+ step_impl ! ( u64 i64 ) ;
2476+ #[ cfg( target_pointer_width = "32" ) ]
2477+ step_impl_no_between ! ( u64 i64 ) ;
2478+
24202479/// An adapter for stepping range iterators by a custom amount.
24212480///
24222481/// The resulting iterator handles overflow by stopping. The `A`
@@ -2429,7 +2488,7 @@ pub struct StepBy<A, R> {
24292488 range : R ,
24302489}
24312490
2432- impl < A : Add > RangeFrom < A > {
2491+ impl < A : Step > RangeFrom < A > {
24332492 /// Creates an iterator starting at the same point, but stepping by
24342493 /// the given amount at each iteration.
24352494 ///
@@ -2451,7 +2510,8 @@ impl<A: Add> RangeFrom<A> {
24512510 }
24522511}
24532512
2454- impl < A : Int > :: ops:: Range < A > {
2513+ #[ allow( deprecated) ]
2514+ impl < A : Step > :: ops:: Range < A > {
24552515 /// Creates an iterator with the same range, but stepping by the
24562516 /// given amount at each iteration.
24572517 ///
@@ -2505,14 +2565,17 @@ pub fn count<A>(start: A, step: A) -> Counter<A> {
25052565}
25062566
25072567#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2508- impl < A : Add < Output =A > + Clone > Iterator for StepBy < A , RangeFrom < A > > {
2568+ impl < A > Iterator for StepBy < A , RangeFrom < A > > where
2569+ A : Clone ,
2570+ for < ' a > & ' a A : Add < & ' a A , Output = A >
2571+ {
25092572 type Item = A ;
25102573
25112574 #[ inline]
25122575 fn next ( & mut self ) -> Option < A > {
2513- let result = self . range . start . clone ( ) ;
2514- self . range . start = result . clone ( ) + self . step_by . clone ( ) ;
2515- Some ( result )
2576+ let mut n = & self . range . start + & self . step_by ;
2577+ mem :: swap ( & mut n , & mut self . range . start ) ;
2578+ Some ( n )
25162579 }
25172580
25182581 #[ inline]
@@ -2715,19 +2778,27 @@ pub fn range_step<A: Int>(start: A, stop: A, step: A) -> RangeStep<A> {
27152778}
27162779
27172780#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2718- impl < A : Int > Iterator for StepBy < A , :: ops:: Range < A > > {
2781+ #[ allow( deprecated) ]
2782+ impl < A : Step + Zero + Clone > Iterator for StepBy < A , :: ops:: Range < A > > {
27192783 type Item = A ;
27202784
27212785 #[ inline]
27222786 fn next ( & mut self ) -> Option < A > {
2723- let rev = self . step_by < Int :: zero ( ) ;
2724- let start = self . range . start ;
2725- if ( rev && start > self . range . end ) || ( !rev && start < self . range . end ) {
2726- match start. checked_add ( self . step_by ) {
2727- Some ( x) => self . range . start = x,
2728- None => self . range . start = self . range . end . clone ( )
2787+ let rev = self . step_by < A :: zero ( ) ;
2788+ if ( rev && self . range . start > self . range . end ) ||
2789+ ( !rev && self . range . start < self . range . end )
2790+ {
2791+ match self . range . start . step ( & self . step_by ) {
2792+ Some ( mut n) => {
2793+ mem:: swap ( & mut self . range . start , & mut n) ;
2794+ Some ( n)
2795+ } ,
2796+ None => {
2797+ let mut n = self . range . end . clone ( ) ;
2798+ mem:: swap ( & mut self . range . start , & mut n) ;
2799+ Some ( n)
2800+ }
27292801 }
2730- Some ( start)
27312802 } else {
27322803 None
27332804 }
@@ -2774,6 +2845,7 @@ pub struct RangeStepInclusive<A> {
27742845#[ inline]
27752846#[ unstable( feature = "core" ,
27762847 reason = "likely to be replaced by range notation and adapters" ) ]
2848+ #[ allow( deprecated) ]
27772849pub fn range_step_inclusive < A : Int > ( start : A , stop : A , step : A ) -> RangeStepInclusive < A > {
27782850 let rev = step < Int :: zero ( ) ;
27792851 RangeStepInclusive {
@@ -2787,6 +2859,7 @@ pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepIncl
27872859
27882860#[ unstable( feature = "core" ,
27892861 reason = "likely to be replaced by range notation and adapters" ) ]
2862+ #[ allow( deprecated) ]
27902863impl < A : Int > Iterator for RangeStepInclusive < A > {
27912864 type Item = A ;
27922865
@@ -2814,27 +2887,36 @@ macro_rules! range_exact_iter_impl {
28142887}
28152888
28162889#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2817- impl < A : Int > Iterator for :: ops:: Range < A > {
2890+ #[ allow( deprecated) ]
2891+ impl < A : Step + One + Clone > Iterator for :: ops:: Range < A > {
28182892 type Item = A ;
28192893
28202894 #[ inline]
28212895 fn next ( & mut self ) -> Option < A > {
28222896 if self . start < self . end {
2823- let result = self . start ;
2824- self . start = self . start + Int :: one ( ) ;
2825- Some ( result)
2897+ match self . start . step ( & A :: one ( ) ) {
2898+ Some ( mut n) => {
2899+ mem:: swap ( & mut n, & mut self . start ) ;
2900+ Some ( n)
2901+ } ,
2902+ None => {
2903+ let mut n = self . end . clone ( ) ;
2904+ mem:: swap ( & mut n, & mut self . start ) ;
2905+ Some ( n)
2906+
2907+ }
2908+ }
28262909 } else {
28272910 None
28282911 }
28292912 }
28302913
28312914 #[ inline]
28322915 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
2833- if self . start >= self . end {
2834- ( 0 , Some ( 0 ) )
2916+ if let Some ( hint ) = Step :: steps_between ( & self . start , & self . end , & A :: one ( ) ) {
2917+ ( hint , Some ( hint ) )
28352918 } else {
2836- let length = ( self . end - self . start ) . to_usize ( ) ;
2837- ( length. unwrap_or ( 0 ) , length)
2919+ ( 0 , None )
28382920 }
28392921 }
28402922}
@@ -2844,28 +2926,32 @@ impl<A: Int> Iterator for ::ops::Range<A> {
28442926range_exact_iter_impl ! ( usize u8 u16 u32 isize i8 i16 i32 ) ;
28452927
28462928#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2847- impl < A : Int > DoubleEndedIterator for :: ops:: Range < A > {
2929+ #[ allow( deprecated) ]
2930+ impl < A : Step + One + Clone > DoubleEndedIterator for :: ops:: Range < A > where
2931+ for < ' a > & ' a A : Sub < & ' a A , Output = A >
2932+ {
28482933 #[ inline]
28492934 fn next_back ( & mut self ) -> Option < A > {
28502935 if self . start < self . end {
2851- self . end = self . end - Int :: one ( ) ;
2852- Some ( self . end )
2936+ self . end = & self . end - & A :: one ( ) ;
2937+ Some ( self . end . clone ( ) )
28532938 } else {
28542939 None
28552940 }
28562941 }
28572942}
28582943
28592944#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2860- impl < A : Int > Iterator for :: ops:: RangeFrom < A > {
2945+ #[ allow( deprecated) ]
2946+ impl < A : Step + One > Iterator for :: ops:: RangeFrom < A > {
28612947 type Item = A ;
28622948
28632949 #[ inline]
28642950 fn next ( & mut self ) -> Option < A > {
2865- let result = self . start ;
2866- self . start = self . start + Int :: one ( ) ;
2867- debug_assert ! ( result < self . start ) ;
2868- Some ( result )
2951+ self . start . step ( & A :: one ( ) ) . map ( | mut n| {
2952+ mem :: swap ( & mut n , & mut self . start ) ;
2953+ n
2954+ } )
28692955 }
28702956}
28712957
0 commit comments