1 // Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 use ops::{self, Add, Sub};
15 use super::FusedIterator;
17 /// Objects that can be stepped over in both directions.
19 /// The `steps_between` function provides a way to efficiently compare
20 /// two `Step` objects.
21 #[unstable(feature = "step_trait",
22 reason = "likely to be replaced by finer-grained traits",
24 pub trait Step: PartialOrd + Sized {
25 /// Steps `self` if possible.
26 fn step(&self, by: &Self) -> Option<Self>;
28 /// Returns the number of steps between two step objects. The count is
29 /// inclusive of `start` and exclusive of `end`.
31 /// Returns `None` if it is not possible to calculate `steps_between`
33 fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>;
35 /// Same as `steps_between`, but with a `by` of 1
36 fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize>;
38 /// Tests whether this step is negative or not (going backwards)
39 fn is_negative(&self) -> bool;
41 /// Replaces this step with `1`, returning itself
42 fn replace_one(&mut self) -> Self;
44 /// Replaces this step with `0`, returning itself
45 fn replace_zero(&mut self) -> Self;
47 /// Adds one to this step, returning the result
48 fn add_one(&self) -> Self;
50 /// Subtracts one to this step, returning the result
51 fn sub_one(&self) -> Self;
54 macro_rules! step_impl_unsigned {
56 #[unstable(feature = "step_trait",
57 reason = "likely to be replaced by finer-grained traits",
61 fn step(&self, by: &$t) -> Option<$t> {
62 (*self).checked_add(*by)
65 #[allow(trivial_numeric_casts)]
66 fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
67 if *by == 0 { return None; }
69 // Note: We assume $t <= usize here
70 let diff = (*end - *start) as usize;
71 let by = *by as usize;
83 fn is_negative(&self) -> bool {
88 fn replace_one(&mut self) -> Self {
93 fn replace_zero(&mut self) -> Self {
98 fn add_one(&self) -> Self {
103 fn sub_one(&self) -> Self {
108 fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
109 Self::steps_between(start, end, &1)
114 macro_rules! step_impl_signed {
116 #[unstable(feature = "step_trait",
117 reason = "likely to be replaced by finer-grained traits",
121 fn step(&self, by: &$t) -> Option<$t> {
122 (*self).checked_add(*by)
125 #[allow(trivial_numeric_casts)]
126 fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
127 if *by == 0 { return None; }
134 // Note: We assume $t <= isize here
135 // Use .wrapping_sub and cast to usize to compute the
136 // difference that may not fit inside the range of isize.
137 diff = (*end as isize).wrapping_sub(*start as isize) as usize;
143 diff = (*start as isize).wrapping_sub(*end as isize) as usize;
144 by_u = (*by as isize).wrapping_mul(-1) as usize;
147 Some(diff / by_u + 1)
154 fn is_negative(&self) -> bool {
159 fn replace_one(&mut self) -> Self {
160 mem::replace(self, 0)
164 fn replace_zero(&mut self) -> Self {
165 mem::replace(self, 1)
169 fn add_one(&self) -> Self {
174 fn sub_one(&self) -> Self {
179 fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
180 Self::steps_between(start, end, &1)
186 macro_rules! step_impl_no_between {
188 #[unstable(feature = "step_trait",
189 reason = "likely to be replaced by finer-grained traits",
193 fn step(&self, by: &$t) -> Option<$t> {
194 (*self).checked_add(*by)
197 fn steps_between(_a: &$t, _b: &$t, _by: &$t) -> Option<usize> {
202 #[allow(unused_comparisons)]
203 fn is_negative(&self) -> bool {
208 fn replace_one(&mut self) -> Self {
209 mem::replace(self, 0)
213 fn replace_zero(&mut self) -> Self {
214 mem::replace(self, 1)
218 fn add_one(&self) -> Self {
223 fn sub_one(&self) -> Self {
228 fn steps_between_by_one(start: &Self, end: &Self) -> Option<usize> {
229 Self::steps_between(start, end, &1)
235 step_impl_unsigned!(usize u8 u16 u32);
236 step_impl_signed!(isize i8 i16 i32);
237 #[cfg(target_pointer_width = "64")]
238 step_impl_unsigned!(u64);
239 #[cfg(target_pointer_width = "64")]
240 step_impl_signed!(i64);
241 // If the target pointer width is not 64-bits, we
242 // assume here that it is less than 64-bits.
243 #[cfg(not(target_pointer_width = "64"))]
244 step_impl_no_between!(u64 i64);
246 /// An adapter for stepping range iterators by a custom amount.
248 /// The resulting iterator handles overflow by stopping. The `A`
249 /// parameter is the type being iterated over, while `R` is the range
250 /// type (usually one of `std::ops::{Range, RangeFrom, RangeInclusive}`.
251 #[derive(Clone, Debug)]
252 #[unstable(feature = "step_by", reason = "recent addition",
254 pub struct StepBy<A, R> {
259 impl<A: Step> ops::RangeFrom<A> {
260 /// Creates an iterator starting at the same point, but stepping by
261 /// the given amount at each iteration.
266 /// #![feature(step_by)]
268 /// let result: Vec<_> = (0..).step_by(2).take(5).collect();
269 /// assert_eq!(result, vec![0, 2, 4, 6, 8]);
272 #[unstable(feature = "step_by", reason = "recent addition",
274 pub fn step_by(self, by: A) -> StepBy<A, Self> {
282 impl<A: Step> ops::Range<A> {
283 /// Creates an iterator with the same range, but stepping by the
284 /// given amount at each iteration.
286 /// The resulting iterator handles overflow by stopping.
291 /// #![feature(step_by)]
293 /// let result: Vec<_> = (0..10).step_by(2).collect();
294 /// assert_eq!(result, vec![0, 2, 4, 6, 8]);
297 #[unstable(feature = "step_by", reason = "recent addition",
299 pub fn step_by(self, by: A) -> StepBy<A, Self> {
307 impl<A: Step> ops::RangeInclusive<A> {
308 /// Creates an iterator with the same range, but stepping by the
309 /// given amount at each iteration.
311 /// The resulting iterator handles overflow by stopping.
316 /// #![feature(step_by, inclusive_range_syntax)]
318 /// let result: Vec<_> = (0...10).step_by(2).collect();
319 /// assert_eq!(result, vec![0, 2, 4, 6, 8, 10]);
321 #[unstable(feature = "step_by", reason = "recent addition",
323 pub fn step_by(self, by: A) -> StepBy<A, Self> {
331 #[stable(feature = "rust1", since = "1.0.0")]
332 impl<A> Iterator for StepBy<A, ops::RangeFrom<A>> where
334 for<'a> &'a A: Add<&'a A, Output = A>
339 fn next(&mut self) -> Option<A> {
340 let mut n = &self.range.start + &self.step_by;
341 mem::swap(&mut n, &mut self.range.start);
346 fn size_hint(&self) -> (usize, Option<usize>) {
347 (usize::MAX, None) // Too bad we can't specify an infinite lower bound
351 #[unstable(feature = "fused", issue = "35602")]
352 impl<A> FusedIterator for StepBy<A, ops::RangeFrom<A>>
353 where A: Clone, for<'a> &'a A: Add<&'a A, Output = A> {}
355 #[stable(feature = "rust1", since = "1.0.0")]
356 impl<A: Step + Clone> Iterator for StepBy<A, ops::Range<A>> {
360 fn next(&mut self) -> Option<A> {
361 let rev = self.step_by.is_negative();
362 if (rev && self.range.start > self.range.end) ||
363 (!rev && self.range.start < self.range.end)
365 match self.range.start.step(&self.step_by) {
367 mem::swap(&mut self.range.start, &mut n);
371 let mut n = self.range.end.clone();
372 mem::swap(&mut self.range.start, &mut n);
382 fn size_hint(&self) -> (usize, Option<usize>) {
383 match Step::steps_between(&self.range.start,
386 Some(hint) => (hint, Some(hint)),
392 #[unstable(feature = "fused", issue = "35602")]
393 impl<A: Step + Clone> FusedIterator for StepBy<A, ops::Range<A>> {}
395 #[unstable(feature = "inclusive_range",
396 reason = "recently added, follows RFC",
398 impl<A: Step + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
402 fn next(&mut self) -> Option<A> {
403 use ops::RangeInclusive::*;
405 // this function has a sort of odd structure due to borrowck issues
406 // we may need to replace self.range, so borrows of start and end need to end early
408 let (finishing, n) = match self.range {
409 Empty { .. } => return None, // empty iterators yield no values
411 NonEmpty { ref mut start, ref mut end } => {
412 let rev = self.step_by.is_negative();
414 // march start towards (maybe past!) end and yield the old value
415 if (rev && start >= end) ||
416 (!rev && start <= end)
418 match start.step(&self.step_by) {
420 mem::swap(start, &mut n);
421 (None, Some(n)) // yield old value, remain non-empty
424 let mut n = end.clone();
425 mem::swap(start, &mut n);
426 (None, Some(n)) // yield old value, remain non-empty
430 // found range in inconsistent state (start at or past end), so become empty
431 (Some(end.replace_zero()), None)
436 // turn into an empty iterator if we've reached the end
437 if let Some(end) = finishing {
438 self.range = Empty { at: end };
445 fn size_hint(&self) -> (usize, Option<usize>) {
446 use ops::RangeInclusive::*;
449 Empty { .. } => (0, Some(0)),
451 NonEmpty { ref start, ref end } =>
452 match Step::steps_between(start,
455 Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
462 #[unstable(feature = "fused", issue = "35602")]
463 impl<A: Step + Clone> FusedIterator for StepBy<A, ops::RangeInclusive<A>> {}
465 macro_rules! range_exact_iter_impl {
467 #[stable(feature = "rust1", since = "1.0.0")]
468 impl ExactSizeIterator for ops::Range<$t> { }
470 #[unstable(feature = "inclusive_range",
471 reason = "recently added, follows RFC",
473 impl ExactSizeIterator for ops::RangeInclusive<$t> { }
477 #[stable(feature = "rust1", since = "1.0.0")]
478 impl<A: Step> Iterator for ops::Range<A> where
479 for<'a> &'a A: Add<&'a A, Output = A>
484 fn next(&mut self) -> Option<A> {
485 if self.start < self.end {
486 let mut n = self.start.add_one();
487 mem::swap(&mut n, &mut self.start);
495 fn size_hint(&self) -> (usize, Option<usize>) {
496 match Step::steps_between_by_one(&self.start, &self.end) {
497 Some(hint) => (hint, Some(hint)),
503 // Ranges of u64 and i64 are excluded because they cannot guarantee having
504 // a length <= usize::MAX, which is required by ExactSizeIterator.
505 range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
507 #[stable(feature = "rust1", since = "1.0.0")]
508 impl<A: Step + Clone> DoubleEndedIterator for ops::Range<A> where
509 for<'a> &'a A: Add<&'a A, Output = A>,
510 for<'a> &'a A: Sub<&'a A, Output = A>
513 fn next_back(&mut self) -> Option<A> {
514 if self.start < self.end {
515 self.end = self.end.sub_one();
516 Some(self.end.clone())
523 #[unstable(feature = "fused", issue = "35602")]
524 impl<A> FusedIterator for ops::Range<A>
525 where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}
527 #[stable(feature = "rust1", since = "1.0.0")]
528 impl<A: Step> Iterator for ops::RangeFrom<A> where
529 for<'a> &'a A: Add<&'a A, Output = A>
534 fn next(&mut self) -> Option<A> {
535 let mut n = self.start.add_one();
536 mem::swap(&mut n, &mut self.start);
541 #[unstable(feature = "fused", issue = "35602")]
542 impl<A> FusedIterator for ops::RangeFrom<A>
543 where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}
545 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
546 impl<A: Step> Iterator for ops::RangeInclusive<A> where
547 for<'a> &'a A: Add<&'a A, Output = A>
552 fn next(&mut self) -> Option<A> {
553 use ops::RangeInclusive::*;
555 // this function has a sort of odd structure due to borrowck issues
556 // we may need to replace self, so borrows of self.start and self.end need to end early
558 let (finishing, n) = match *self {
559 Empty { .. } => (None, None), // empty iterators yield no values
561 NonEmpty { ref mut start, ref mut end } => {
563 (Some(end.replace_one()), Some(start.replace_one()))
564 } else if start < end {
565 let mut n = start.add_one();
566 mem::swap(&mut n, start);
568 // if the iterator is done iterating, it will change from
569 // NonEmpty to Empty to avoid unnecessary drops or clones,
570 // we'll reuse either start or end (they are equal now, so
571 // it doesn't matter which) to pull out end, we need to swap
574 (if n == *end { Some(end.replace_one()) } else { None },
575 // ^ are we done yet?
576 Some(n)) // < the value to output
578 (Some(start.replace_one()), None)
583 // turn into an empty iterator if this is the last value
584 if let Some(end) = finishing {
585 *self = Empty { at: end };
592 fn size_hint(&self) -> (usize, Option<usize>) {
593 use ops::RangeInclusive::*;
596 Empty { .. } => (0, Some(0)),
598 NonEmpty { ref start, ref end } =>
599 match Step::steps_between_by_one(start, end) {
600 Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
607 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
608 impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> where
609 for<'a> &'a A: Add<&'a A, Output = A>,
610 for<'a> &'a A: Sub<&'a A, Output = A>
613 fn next_back(&mut self) -> Option<A> {
614 use ops::RangeInclusive::*;
616 // see Iterator::next for comments
618 let (finishing, n) = match *self {
619 Empty { .. } => return None,
621 NonEmpty { ref mut start, ref mut end } => {
623 (Some(start.replace_one()), Some(end.replace_one()))
624 } else if start < end {
625 let mut n = end.sub_one();
626 mem::swap(&mut n, end);
628 (if n == *start { Some(start.replace_one()) } else { None },
631 (Some(end.replace_one()), None)
636 if let Some(start) = finishing {
637 *self = Empty { at: start };
644 #[unstable(feature = "fused", issue = "35602")]
645 impl<A> FusedIterator for ops::RangeInclusive<A>
646 where A: Step, for<'a> &'a A: Add<&'a A, Output = A> {}