@@ -64,8 +64,8 @@ use cmp::Ord;
64
64
use default:: Default ;
65
65
use marker;
66
66
use 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 } ;
69
69
use option:: Option ;
70
70
use option:: Option :: { Some , None } ;
71
71
use marker:: Sized ;
@@ -843,9 +843,8 @@ pub trait Iterator {
843
843
///
844
844
/// ```
845
845
/// # #![feature(core)]
846
- /// use std::num::SignedInt;
847
846
///
848
- /// let a = [-3 , 0, 1, 5, -10];
847
+ /// let a = [-3_i32 , 0, 1, 5, -10];
849
848
/// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10);
850
849
/// ```
851
850
#[ inline]
@@ -875,9 +874,8 @@ pub trait Iterator {
875
874
///
876
875
/// ```
877
876
/// # #![feature(core)]
878
- /// use std::num::SignedInt;
879
877
///
880
- /// let a = [-3 , 0, 1, 5, -10];
878
+ /// let a = [-3_i32 , 0, 1, 5, -10];
881
879
/// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0);
882
880
/// ```
883
881
#[ inline]
@@ -2417,6 +2415,67 @@ impl<A, St, F> Iterator for Unfold<St, F> where F: FnMut(&mut St) -> Option<A> {
2417
2415
}
2418
2416
}
2419
2417
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
+
2420
2479
/// An adapter for stepping range iterators by a custom amount.
2421
2480
///
2422
2481
/// The resulting iterator handles overflow by stopping. The `A`
@@ -2429,7 +2488,7 @@ pub struct StepBy<A, R> {
2429
2488
range : R ,
2430
2489
}
2431
2490
2432
- impl < A : Add > RangeFrom < A > {
2491
+ impl < A : Step > RangeFrom < A > {
2433
2492
/// Creates an iterator starting at the same point, but stepping by
2434
2493
/// the given amount at each iteration.
2435
2494
///
@@ -2451,7 +2510,8 @@ impl<A: Add> RangeFrom<A> {
2451
2510
}
2452
2511
}
2453
2512
2454
- impl < A : Int > :: ops:: Range < A > {
2513
+ #[ allow( deprecated) ]
2514
+ impl < A : Step > :: ops:: Range < A > {
2455
2515
/// Creates an iterator with the same range, but stepping by the
2456
2516
/// given amount at each iteration.
2457
2517
///
@@ -2505,14 +2565,17 @@ pub fn count<A>(start: A, step: A) -> Counter<A> {
2505
2565
}
2506
2566
2507
2567
#[ 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
+ {
2509
2572
type Item = A ;
2510
2573
2511
2574
#[ inline]
2512
2575
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 )
2516
2579
}
2517
2580
2518
2581
#[ inline]
@@ -2715,19 +2778,27 @@ pub fn range_step<A: Int>(start: A, stop: A, step: A) -> RangeStep<A> {
2715
2778
}
2716
2779
2717
2780
#[ 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 > > {
2719
2783
type Item = A ;
2720
2784
2721
2785
#[ inline]
2722
2786
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
+ }
2729
2801
}
2730
- Some ( start)
2731
2802
} else {
2732
2803
None
2733
2804
}
@@ -2774,6 +2845,7 @@ pub struct RangeStepInclusive<A> {
2774
2845
#[ inline]
2775
2846
#[ unstable( feature = "core" ,
2776
2847
reason = "likely to be replaced by range notation and adapters" ) ]
2848
+ #[ allow( deprecated) ]
2777
2849
pub fn range_step_inclusive < A : Int > ( start : A , stop : A , step : A ) -> RangeStepInclusive < A > {
2778
2850
let rev = step < Int :: zero ( ) ;
2779
2851
RangeStepInclusive {
@@ -2787,6 +2859,7 @@ pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepIncl
2787
2859
2788
2860
#[ unstable( feature = "core" ,
2789
2861
reason = "likely to be replaced by range notation and adapters" ) ]
2862
+ #[ allow( deprecated) ]
2790
2863
impl < A : Int > Iterator for RangeStepInclusive < A > {
2791
2864
type Item = A ;
2792
2865
@@ -2814,27 +2887,36 @@ macro_rules! range_exact_iter_impl {
2814
2887
}
2815
2888
2816
2889
#[ 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 > {
2818
2892
type Item = A ;
2819
2893
2820
2894
#[ inline]
2821
2895
fn next ( & mut self ) -> Option < A > {
2822
2896
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
+ }
2826
2909
} else {
2827
2910
None
2828
2911
}
2829
2912
}
2830
2913
2831
2914
#[ inline]
2832
2915
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 ) )
2835
2918
} else {
2836
- let length = ( self . end - self . start ) . to_usize ( ) ;
2837
- ( length. unwrap_or ( 0 ) , length)
2919
+ ( 0 , None )
2838
2920
}
2839
2921
}
2840
2922
}
@@ -2844,28 +2926,32 @@ impl<A: Int> Iterator for ::ops::Range<A> {
2844
2926
range_exact_iter_impl ! ( usize u8 u16 u32 isize i8 i16 i32 ) ;
2845
2927
2846
2928
#[ 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
+ {
2848
2933
#[ inline]
2849
2934
fn next_back ( & mut self ) -> Option < A > {
2850
2935
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 ( ) )
2853
2938
} else {
2854
2939
None
2855
2940
}
2856
2941
}
2857
2942
}
2858
2943
2859
2944
#[ 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 > {
2861
2947
type Item = A ;
2862
2948
2863
2949
#[ inline]
2864
2950
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
+ } )
2869
2955
}
2870
2956
}
2871
2957
0 commit comments