use default::Default;
use marker;
use mem;
-use num::{Int, Zero, One};
+use num::{Zero, One};
use ops::{self, Add, Sub, FnMut, Mul, RangeFrom};
use option::Option::{self, Some, None};
use marker::Sized;
/// Creates an iterator that iterates over both this and the specified
/// iterators simultaneously, yielding the two elements as pairs. When
- /// either iterator returns `None`, all further invocations of next() will
- /// return `None`.
+ /// either iterator returns `None`, all further invocations of `next()`
+ /// will return `None`.
///
/// # Examples
///
impl<I> ExactSizeIterator for Fuse<I> where I: ExactSizeIterator {}
impl<I> Fuse<I> {
- /// Resets the fuse such that the next call to .next() or .next_back() will
- /// call the underlying iterator again even if it previously returned None.
+ /// Resets the `Fuse` such that the next call to `.next()` or
+ /// `.next_back()` will call the underlying iterator again even if it
+ /// previously returned `None`.
#[inline]
#[unstable(feature = "core", reason = "seems marginal")]
pub fn reset_fuse(&mut self) {
/// An iterator that yields sequential Fibonacci numbers, and stops on overflow.
///
/// ```
-/// # #![feature(core)]
+/// #![feature(core)]
/// use std::iter::Unfold;
-/// use std::num::Int; // For `.checked_add()`
///
/// // This iterator will yield up to the last Fibonacci number before the max
/// // value of `u32`. You can simply change `u32` to `u64` in this line if
/// `start` should always be less than `end`, so the result should never
/// be negative.
///
+ /// `by` must be > 0.
+ ///
/// Returns `None` if it is not possible to calculate steps_between
/// without overflow.
fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>;
}
-macro_rules! step_impl {
+macro_rules! step_impl_unsigned {
+ ($($t:ty)*) => ($(
+ impl Step for $t {
+ #[inline]
+ fn step(&self, by: &$t) -> Option<$t> {
+ (*self).checked_add(*by)
+ }
+ #[inline]
+ #[allow(trivial_numeric_casts)]
+ fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
+ if *start <= *end {
+ // Note: We assume $t <= usize here
+ Some((*end - *start) as usize / (*by as usize))
+ } else {
+ Some(0)
+ }
+ }
+ }
+ )*)
+}
+macro_rules! step_impl_signed {
($($t:ty)*) => ($(
impl Step for $t {
#[inline]
#[allow(trivial_numeric_casts)]
fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
if *start <= *end {
- Some(((*end - *start) / *by) as usize)
+ // Note: We assume $t <= isize here
+ // Use .wrapping_sub and cast to usize to compute the
+ // difference that may not fit inside the range of isize.
+ Some(
+ ((*end as isize).wrapping_sub(*start as isize) as usize
+ / (*by as usize))
+ )
} else {
Some(0)
}
)*)
}
-step_impl!(usize u8 u16 u32 isize i8 i16 i32);
+step_impl_unsigned!(usize u8 u16 u32);
+step_impl_signed!(isize i8 i16 i32);
+#[cfg(target_pointer_width = "64")]
+step_impl_unsigned!(u64);
#[cfg(target_pointer_width = "64")]
-step_impl!(u64 i64);
+step_impl_signed!(i64);
#[cfg(target_pointer_width = "32")]
step_impl_no_between!(u64 i64);
}
}
-/// An iterator over the range [start, stop] by `step`. It handles overflow by stopping.
-#[derive(Clone)]
-#[unstable(feature = "core",
- reason = "likely to be replaced by range notation and adapters")]
-pub struct RangeStepInclusive<A> {
- state: A,
- stop: A,
- step: A,
- rev: bool,
- done: bool,
-}
-
-/// Returns an iterator over the range [start, stop] by `step`.
-///
-/// It handles overflow by stopping.
-///
-/// # Examples
-///
-/// ```
-/// # #![feature(core)]
-/// use std::iter::range_step_inclusive;
-///
-/// for i in range_step_inclusive(0, 10, 2) {
-/// println!("{}", i);
-/// }
-/// ```
-///
-/// This prints:
-///
-/// ```text
-/// 0
-/// 2
-/// 4
-/// 6
-/// 8
-/// 10
-/// ```
-#[inline]
-#[unstable(feature = "core",
- reason = "likely to be replaced by range notation and adapters")]
-#[allow(deprecated)]
-pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepInclusive<A> {
- let rev = step < Int::zero();
- RangeStepInclusive {
- state: start,
- stop: stop,
- step: step,
- rev: rev,
- done: false,
- }
-}
-
-#[unstable(feature = "core",
- reason = "likely to be replaced by range notation and adapters")]
-#[allow(deprecated)]
-impl<A: Int> Iterator for RangeStepInclusive<A> {
- type Item = A;
-
- #[inline]
- fn next(&mut self) -> Option<A> {
- if !self.done && ((self.rev && self.state >= self.stop) ||
- (!self.rev && self.state <= self.stop)) {
- let result = self.state;
- match self.state.checked_add(self.step) {
- Some(x) => self.state = x,
- None => self.done = true
- }
- Some(result)
- } else {
- None
- }
- }
-}
-
macro_rules! range_exact_iter_impl {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]