// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms.
//! External iterators for generic mathematics //! //! ## Compatibility //! //! The `num-iter` crate is tested for rustc 1.31 and greater.
use core::ops::{Add, Bound, RangeBounds, Sub}; use core::usize; use num_integer::Integer; use num_traits::{CheckedAdd, One, ToPrimitive, Zero};
/// An iterator over the range [start, stop) #[derive(Clone)] pubstruct Range<A> {
state: A,
stop: A,
one: A,
}
/// Returns an iterator over the given range [start, stop) (that is, starting /// at start (inclusive), and ending at stop (exclusive)). /// /// # Example /// /// ```rust /// let array = [0, 1, 2, 3, 4]; /// /// for i in num_iter::range(0, 5) { /// println!("{}", i); /// assert_eq!(i, array[i]); /// } /// ``` #[inline] pubfn range<A>(start: A, stop: A) -> Range<A> where
A: Add<A, Output = A> + PartialOrd + Clone + One,
{
Range {
state: start,
stop,
one: One::one(),
}
}
// Try to cast both ends to the largest unsigned primitive. // Note that negative values will wrap to a large positive. iflet Some(a) = unsigned(&self.state) { iflet Some(b) = unsigned(&self.stop) { // We've lost signs, but we already know state < stop, so // a `wrapping_sub` will give the correct unsigned delta. returnmatch b.wrapping_sub(a).to_usize() {
Some(len) => (len, Some(len)),
None => (usize::MAX, None),
};
}
}
// Standard fallback for unbounded/unrepresentable bounds
(0, None)
}
}
/// `Integer` is required to ensure the range will be the same regardless of /// the direction it is consumed. impl<A> DoubleEndedIterator for Range<A> where
A: Integer + Clone + ToPrimitive,
{ #[inline] fn next_back(&mutself) -> Option<A> { ifself.stop > self.state { self.stop.dec();
Some(self.stop.clone())
} else {
None
}
}
}
/// An iterator over the range [start, stop] #[derive(Clone)] pubstruct RangeInclusive<A> {
range: Range<A>,
done: bool,
}
/// Return an iterator over the range [start, stop] #[inline] pubfn range_inclusive<A>(start: A, stop: A) -> RangeInclusive<A> where
A: Add<A, Output = A> + PartialOrd + Clone + One,
{
RangeInclusive {
range: range(start, stop),
done: false,
}
}
/// An iterator over the range [start, stop) by `step`. It handles overflow by stopping. #[derive(Clone)] pubstruct RangeStep<A> {
state: A,
stop: A,
step: A,
rev: bool,
}
/// Return an iterator over the range [start, stop) by `step`. It handles overflow by stopping. #[inline] pubfn range_step<A>(start: A, stop: A, step: A) -> RangeStep<A> where
A: CheckedAdd + PartialOrd + Clone + Zero,
{ let rev = step < Zero::zero();
RangeStep {
state: start,
stop,
step,
rev,
}
}
impl<A> Iterator for RangeStep<A> where
A: CheckedAdd + PartialOrd + Clone,
{ type Item = A;
/// An iterator over the range [start, stop] by `step`. It handles overflow by stopping. #[derive(Clone)] pubstruct RangeStepInclusive<A> {
state: A,
stop: A,
step: A,
rev: bool,
done: bool,
}
/// Return an iterator over the range [start, stop] by `step`. It handles overflow by stopping. #[inline] pubfn range_step_inclusive<A>(start: A, stop: A, step: A) -> RangeStepInclusive<A> where
A: CheckedAdd + PartialOrd + Clone + Zero,
{ let rev = step < Zero::zero();
RangeStepInclusive {
state: start,
stop,
step,
rev,
done: false,
}
}
impl<A> Iterator for RangeStepInclusive<A> where
A: CheckedAdd + PartialOrd + Clone + PartialEq,
{ type Item = A;
/// An iterator over the infinite range starting at `start` #[derive(Clone)] pubstruct RangeFrom<A> {
state: A,
one: A,
}
/// Return an iterator over the infinite range starting at `start` and continuing forever. /// /// *Note*: Currently, the `Iterator` implementation is not checked for overflow. /// If you use a finite-sized integer type and the integer overflows, /// it might panic in debug mode or wrap around in release mode. /// **This behavior is not guaranteed and may change at any time.** #[inline] pubfn range_from<A>(start: A) -> RangeFrom<A> where
A: Add<A, Output = A> + Clone + One,
{
RangeFrom {
state: start,
one: One::one(),
}
}
/// An iterator over the infinite range starting at `start` by `step` #[derive(Clone)] pubstruct RangeStepFrom<A> {
state: A,
step: A,
}
/// Return an iterator over the infinite range starting at `start` and continuing forever by `step`. /// /// *Note*: Currently, the `Iterator` implementation is not checked for overflow. /// If you use a finite-sized integer type and the integer overflows, /// it might panic in debug mode or wrap around in release mode. /// **This behavior is not guaranteed and may change at any time.** #[inline] pubfn range_step_from<A>(start: A, step: A) -> RangeStepFrom<A> where
A: Add<A, Output = A> + Clone,
{
RangeStepFrom { state: start, step }
}
impl<A> Iterator for RangeStepFrom<A> where
A: Add<A, Output = A> + Clone,
{ type Item = A;
#[inline] fn next(&mutself) -> Option<A> { let result = self.state.clone(); self.state = self.state.clone() + self.step.clone();
Some(result)
}
#[cfg(test)] mod tests { use core::cmp::Ordering; use core::iter; use core::ops::{Add, Mul}; use core::{isize, usize}; use num_traits::{One, ToPrimitive};
#[test] fn test_range() { /// A mock type to check Range when ToPrimitive returns None struct Foo;
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.11Bemerkung:
(vorverarbeitet am 2026-08-25)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.