@@ -21,7 +21,7 @@ use cmp;
2121use num:: { Zero , One , Integer , CheckedAdd , CheckedSub , Saturating } ;
2222use option:: { Option , Some , None } ;
2323use ops:: { Add , Mul , Sub } ;
24- use cmp:: Ord ;
24+ use cmp:: { Eq , Ord } ;
2525use clone:: Clone ;
2626use uint;
2727use util;
@@ -1838,6 +1838,81 @@ impl<A: Sub<A, A> + Integer + Ord + Clone> DoubleEndedIterator<A> for RangeInclu
18381838 }
18391839}
18401840
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+
18411916/// An iterator that repeats an element endlessly
18421917#[ deriving( Clone , DeepClone ) ]
18431918pub struct Repeat < A > {
@@ -2647,6 +2722,20 @@ mod tests {
26472722 assert_eq ! ( range_inclusive( 0 i, 5 ) . invert( ) . collect:: <~[ int] >( ) , ~[ 5 i, 4 , 3 , 2 , 1 , 0 ] ) ;
26482723 }
26492724
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+
26502739 #[ test]
26512740 fn test_reverse ( ) {
26522741 let mut ys = [ 1 , 2 , 3 , 4 , 5 ] ;
0 commit comments