@@ -21,7 +21,7 @@ use cmp;
21
21
use num:: { Zero , One , Integer , CheckedAdd , CheckedSub , Saturating } ;
22
22
use option:: { Option , Some , None } ;
23
23
use ops:: { Add , Mul , Sub } ;
24
- use cmp:: Ord ;
24
+ use cmp:: { Eq , Ord } ;
25
25
use clone:: Clone ;
26
26
use uint;
27
27
use util;
@@ -1838,6 +1838,81 @@ impl<A: Sub<A, A> + Integer + Ord + Clone> DoubleEndedIterator<A> for RangeInclu
1838
1838
}
1839
1839
}
1840
1840
1841
+ /// An iterator over the range [start, stop) by `step`. It handles overflow by stopping.
1842
+ #[ deriving( Clone , DeepClone ) ]
1843
+ pub struct RangeStep < A > {
1844
+ priv state : A ,
1845
+ priv stop : A ,
1846
+ priv step : A ,
1847
+ priv rev: bool
1848
+ }
1849
+
1850
+ /// Return an iterator over the range [start, stop) by `step`. It handles overflow by stopping.
1851
+ #[ inline]
1852
+ pub fn range_step < A : CheckedAdd + Ord + Clone + Zero > ( start : A , stop : A , step : A ) -> RangeStep < A > {
1853
+ let rev = step < Zero :: zero ( ) ;
1854
+ RangeStep { state : start, stop : stop, step : step, rev : rev}
1855
+ }
1856
+
1857
+ impl < A : CheckedAdd + Ord + Clone > Iterator < A > for RangeStep < A > {
1858
+ #[ inline]
1859
+ fn next ( & mut self ) -> Option < A > {
1860
+ if ( self . rev && self . state > self . stop ) || self . state < self . stop {
1861
+ let result = self . state . clone ( ) ;
1862
+ match self . state . checked_add ( & self . step ) {
1863
+ Some ( x) => self . state = x,
1864
+ None => self . state = self . stop . clone ( )
1865
+ }
1866
+ Some ( result)
1867
+ } else {
1868
+ None
1869
+ }
1870
+ }
1871
+ }
1872
+
1873
+ /// An iterator over the range [start, stop] by `step`. It handles overflow by stopping.
1874
+ #[ deriving( Clone , DeepClone ) ]
1875
+ pub struct RangeStepInclusive < A > {
1876
+ priv state : A ,
1877
+ priv stop : A ,
1878
+ priv step : A ,
1879
+ priv rev: bool ,
1880
+ priv done : bool
1881
+ }
1882
+
1883
+ /// Return an iterator over the range [start, stop] by `step`. It handles overflow by stopping.
1884
+ #[ inline]
1885
+ pub fn range_step_inclusive < A : CheckedAdd + Ord + Clone + Zero > ( start : A , stop : A ,
1886
+ step : A ) -> RangeStepInclusive < A > {
1887
+ let rev = step < Zero :: zero ( ) ;
1888
+ RangeStepInclusive { state : start, stop : stop, step : step, rev : rev, done : false }
1889
+ }
1890
+
1891
+ impl < A : CheckedAdd + Ord + Clone + Eq > Iterator < A > for RangeStepInclusive < A > {
1892
+ #[ inline]
1893
+ fn next ( & mut self ) -> Option < A > {
1894
+ if !self . done {
1895
+ if ( self . rev && self . state > self . stop ) || self . state < self . stop {
1896
+ let result = self . state . clone ( ) ;
1897
+ match self . state . checked_add ( & self . step ) {
1898
+ Some ( x) => self . state = x,
1899
+ None => self . done = true
1900
+ }
1901
+ Some ( result)
1902
+ } else {
1903
+ if self . state == self . stop {
1904
+ self . done = true ;
1905
+ Some ( self . state . clone ( ) )
1906
+ } else {
1907
+ None
1908
+ }
1909
+ }
1910
+ } else {
1911
+ None
1912
+ }
1913
+ }
1914
+ }
1915
+
1841
1916
/// An iterator that repeats an element endlessly
1842
1917
#[ deriving( Clone , DeepClone ) ]
1843
1918
pub struct Repeat < A > {
@@ -2647,6 +2722,20 @@ mod tests {
2647
2722
assert_eq ! ( range_inclusive( 0 i, 5 ) . invert( ) . collect:: <~[ int] >( ) , ~[ 5 i, 4 , 3 , 2 , 1 , 0 ] ) ;
2648
2723
}
2649
2724
2725
+ #[ test]
2726
+ fn test_range_step ( ) {
2727
+ assert_eq ! ( range_step( 0 i, 20 , 5 ) . collect:: <~[ int] >( ) , ~[ 0 , 5 , 10 , 15 ] ) ;
2728
+ assert_eq ! ( range_step( 20 i, 0 , -5 ) . collect:: <~[ int] >( ) , ~[ 20 , 15 , 10 , 5 ] ) ;
2729
+ assert_eq ! ( range_step( 200u8 , 255 , 50 ) . collect:: <~[ u8 ] >( ) , ~[ 200u8 , 250 ] ) ;
2730
+ }
2731
+
2732
+ #[ test]
2733
+ fn test_range_step_inclusive ( ) {
2734
+ assert_eq ! ( range_step_inclusive( 0 i, 20 , 5 ) . collect:: <~[ int] >( ) , ~[ 0 , 5 , 10 , 15 , 20 ] ) ;
2735
+ assert_eq ! ( range_step_inclusive( 20 i, 0 , -5 ) . collect:: <~[ int] >( ) , ~[ 20 , 15 , 10 , 5 , 0 ] ) ;
2736
+ assert_eq ! ( range_step_inclusive( 200u8 , 255 , 50 ) . collect:: <~[ u8 ] >( ) , ~[ 200u8 , 250 ] ) ;
2737
+ }
2738
+
2650
2739
#[ test]
2651
2740
fn test_reverse ( ) {
2652
2741
let mut ys = [ 1 , 2 , 3 , 4 , 5 ] ;
0 commit comments