@@ -306,7 +306,7 @@ use default::Default;
306
306
use marker;
307
307
use mem;
308
308
use num:: { Zero , One } ;
309
- use ops:: { self , Add , Sub , FnMut , Mul , RangeFrom } ;
309
+ use ops:: { self , Add , Sub , FnMut , Mul } ;
310
310
use option:: Option :: { self , Some , None } ;
311
311
use marker:: Sized ;
312
312
use usize;
@@ -4286,7 +4286,7 @@ step_impl_no_between!(u64 i64);
4286
4286
///
4287
4287
/// The resulting iterator handles overflow by stopping. The `A`
4288
4288
/// parameter is the type being iterated over, while `R` is the range
4289
- /// type (usually one of `std::ops::{Range, RangeFrom}`.
4289
+ /// type (usually one of `std::ops::{Range, RangeFrom, RangeInclusive }`.
4290
4290
#[ derive( Clone ) ]
4291
4291
#[ unstable( feature = "step_by" , reason = "recent addition" ,
4292
4292
issue = "27741" ) ]
@@ -4295,7 +4295,7 @@ pub struct StepBy<A, R> {
4295
4295
range : R ,
4296
4296
}
4297
4297
4298
- impl < A : Step > RangeFrom < A > {
4298
+ impl < A : Step > ops :: RangeFrom < A > {
4299
4299
/// Creates an iterator starting at the same point, but stepping by
4300
4300
/// the given amount at each iteration.
4301
4301
///
@@ -4355,8 +4355,44 @@ impl<A: Step> ops::Range<A> {
4355
4355
}
4356
4356
}
4357
4357
4358
+ impl < A : Step > ops:: RangeInclusive < A > {
4359
+ /// Creates an iterator with the same range, but stepping by the
4360
+ /// given amount at each iteration.
4361
+ ///
4362
+ /// The resulting iterator handles overflow by stopping.
4363
+ ///
4364
+ /// # Examples
4365
+ ///
4366
+ /// ```
4367
+ /// #![feature(step_by, inclusive_range_syntax)]
4368
+ ///
4369
+ /// for i in (0...10).step_by(2) {
4370
+ /// println!("{}", i);
4371
+ /// }
4372
+ /// ```
4373
+ ///
4374
+ /// This prints:
4375
+ ///
4376
+ /// ```text
4377
+ /// 0
4378
+ /// 2
4379
+ /// 4
4380
+ /// 6
4381
+ /// 8
4382
+ /// 10
4383
+ /// ```
4384
+ #[ unstable( feature = "step_by" , reason = "recent addition" ,
4385
+ issue = "27741" ) ]
4386
+ pub fn step_by ( self , by : A ) -> StepBy < A , Self > {
4387
+ StepBy {
4388
+ step_by : by,
4389
+ range : self
4390
+ }
4391
+ }
4392
+ }
4393
+
4358
4394
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
4359
- impl < A > Iterator for StepBy < A , RangeFrom < A > > where
4395
+ impl < A > Iterator for StepBy < A , ops :: RangeFrom < A > > where
4360
4396
A : Clone ,
4361
4397
for < ' a > & ' a A : Add < & ' a A , Output = A >
4362
4398
{
@@ -4412,6 +4448,74 @@ impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::Range<A>> {
4412
4448
}
4413
4449
}
4414
4450
4451
+ #[ unstable( feature = "inclusive_range" ,
4452
+ reason = "recently added, follows RFC" ,
4453
+ issue = "28237" ) ]
4454
+ impl < A : Step + Zero + Clone > Iterator for StepBy < A , ops:: RangeInclusive < A > > {
4455
+ type Item = A ;
4456
+
4457
+ #[ inline]
4458
+ fn next ( & mut self ) -> Option < A > {
4459
+ use ops:: RangeInclusive :: * ;
4460
+
4461
+ // this function has a sort of odd structure due to borrowck issues
4462
+ // we may need to replace self.range, so borrows of start and end need to end early
4463
+
4464
+ let ( finishing, n) = match self . range {
4465
+ Empty { .. } => return None , // empty iterators yield no values
4466
+
4467
+ NonEmpty { ref mut start, ref mut end } => {
4468
+ let zero = A :: zero ( ) ;
4469
+ let rev = self . step_by < zero;
4470
+
4471
+ // march start towards (maybe past!) end and yield the old value
4472
+ if ( rev && start >= end) ||
4473
+ ( !rev && start <= end)
4474
+ {
4475
+ match start. step ( & self . step_by ) {
4476
+ Some ( mut n) => {
4477
+ mem:: swap ( start, & mut n) ;
4478
+ ( None , Some ( n) ) // yield old value, remain non-empty
4479
+ } ,
4480
+ None => {
4481
+ let mut n = end. clone ( ) ;
4482
+ mem:: swap ( start, & mut n) ;
4483
+ ( None , Some ( n) ) // yield old value, remain non-empty
4484
+ }
4485
+ }
4486
+ } else {
4487
+ // found range in inconsistent state (start at or past end), so become empty
4488
+ ( Some ( mem:: replace ( end, zero) ) , None )
4489
+ }
4490
+ }
4491
+ } ;
4492
+
4493
+ // turn into an empty iterator if we've reached the end
4494
+ if let Some ( end) = finishing {
4495
+ self . range = Empty { at : end } ;
4496
+ }
4497
+
4498
+ n
4499
+ }
4500
+
4501
+ #[ inline]
4502
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
4503
+ use ops:: RangeInclusive :: * ;
4504
+
4505
+ match self . range {
4506
+ Empty { .. } => ( 0 , Some ( 0 ) ) ,
4507
+
4508
+ NonEmpty { ref start, ref end } =>
4509
+ match Step :: steps_between ( start,
4510
+ end,
4511
+ & self . step_by ) {
4512
+ Some ( hint) => ( hint. saturating_add ( 1 ) , hint. checked_add ( 1 ) ) ,
4513
+ None => ( 0 , None )
4514
+ }
4515
+ }
4516
+ }
4517
+ }
4518
+
4415
4519
macro_rules! range_exact_iter_impl {
4416
4520
( $( $t: ty) * ) => ( $(
4417
4521
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments