// can't split that into multiple files.
use crate::cmp::{self, Ordering};
-use crate::ops::{Add, Try};
+use crate::ops::{Add, ControlFlow, Try};
-use super::super::LoopState;
use super::super::TrustedRandomAccess;
use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
use super::super::{FlatMap, Flatten};
/// generally, please see the [module-level documentation]. In particular, you
/// may want to know how to [implement `Iterator`][impl].
///
-/// [module-level documentation]: index.html
-/// [impl]: index.html#implementing-iterator
+/// [module-level documentation]: crate::iter
+/// [impl]: crate::iter#implementing-iterator
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
on(
/// assert_eq!(None, iter.next());
/// assert_eq!(None, iter.next());
/// ```
- #[cfg_attr(not(bootstrap), lang = "next")]
+ #[lang = "next"]
#[stable(feature = "rust1", since = "1.0.0")]
fn next(&mut self) -> Option<Self::Item>;
/// returning the number of times it saw [`Some`]. Note that [`next`] has to be
/// called at least once even if the iterator does not have any elements.
///
- /// [`next`]: #tymethod.next
+ /// [`next`]: Iterator::next
///
/// # Overflow Behavior
///
self.fold(None, some)
}
+ /// Advances the iterator by `n` elements.
+ ///
+ /// This method will eagerly skip `n` elements by calling [`next`] up to `n`
+ /// times until [`None`] is encountered.
+ ///
+ /// `advance_by(n)` will return [`Ok(())`] if the iterator successfully advances by
+ /// `n` elements, or [`Err(k)`] if [`None`] is encountered, where `k` is the number
+ /// of elements the iterator is advanced by before running out of elements (i.e. the
+ /// length of the iterator). Note that `k` is always less than `n`.
+ ///
+ /// Calling `advance_by(0)` does not consume any elements and always returns [`Ok(())`].
+ ///
+ /// [`next`]: Iterator::next
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(iter_advance_by)]
+ ///
+ /// let a = [1, 2, 3, 4];
+ /// let mut iter = a.iter();
+ ///
+ /// assert_eq!(iter.advance_by(2), Ok(()));
+ /// assert_eq!(iter.next(), Some(&3));
+ /// assert_eq!(iter.advance_by(0), Ok(()));
+ /// assert_eq!(iter.advance_by(100), Err(1)); // only `&4` was skipped
+ /// ```
+ #[inline]
+ #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")]
+ fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+ for i in 0..n {
+ self.next().ok_or(i)?;
+ }
+ Ok(())
+ }
+
/// Returns the `n`th element of the iterator.
///
/// Like most indexing operations, the count starts from zero, so `nth(0)`
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
- while let Some(x) = self.next() {
- if n == 0 {
- return Some(x);
- }
- n -= 1;
- }
- None
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ self.advance_by(n).ok()?;
+ self.next()
}
/// Creates an iterator starting at the same point, but stepping by
/// }
/// ```
///
- /// [`once`]: fn.once.html
- /// [`Iterator`]: trait.Iterator.html
- /// [`IntoIterator`]: trait.IntoIterator.html
+ /// [`once`]: crate::iter::once
/// [`OsStr`]: ../../std/ffi/struct.OsStr.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
/// [`Iterator`] itself. For example, slices (`&[T]`) implement
/// [`IntoIterator`], and so can be passed to `zip()` directly:
///
- /// [`IntoIterator`]: trait.IntoIterator.html
- /// [`Iterator`]: trait.Iterator.html
- ///
/// ```
/// let s1 = &[1, 2, 3];
/// let s2 = &[4, 5, 6];
/// assert_eq!((2, 'o'), zipper[2]);
/// ```
///
- /// [`enumerate`]: #method.enumerate
- /// [`next`]: #tymethod.next
+ /// [`enumerate`]: Iterator::enumerate
+ /// [`next`]: Iterator::next
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
/// Creates an iterator which uses a closure to determine if an element
/// should be yielded.
///
- /// The closure must return `true` or `false`. `filter()` creates an
- /// iterator which calls this closure on each element. If the closure
- /// returns `true`, then the element is returned. If the closure returns
- /// `false`, it will try again, and call the closure on the next element,
- /// seeing if it passes the test.
+ /// Given an element the closure must return `true` or `false`. The returned
+ /// iterator will yield only the elements for which the closure returns
+ /// true.
///
/// # Examples
///
/// Creates an iterator that both filters and maps.
///
- /// The closure must return an [`Option<T>`]. `filter_map` creates an
- /// iterator which calls this closure on each element. If the closure
- /// returns [`Some(element)`][`Some`], then that element is returned. If the
- /// closure returns [`None`], it will try again, and call the closure on the
- /// next element, seeing if it will return [`Some`].
+ /// The returned iterator yields only the `value`s for which the supplied
+ /// closure returns `Some(value)`.
///
- /// Why `filter_map` and not just [`filter`] and [`map`]? The key is in this
- /// part:
+ /// `filter_map` can be used to make chains of [`filter`] and [`map`] more
+ /// concise. The example below shows how a `map().filter().map()` can be
+ /// shortened to a single call to `filter_map`.
///
- /// [`filter`]: #method.filter
- /// [`map`]: #method.map
- ///
- /// > If the closure returns [`Some(element)`][`Some`], then that element is returned.
- ///
- /// In other words, it removes the [`Option<T>`] layer automatically. If your
- /// mapping is already returning an [`Option<T>`] and you want to skip over
- /// [`None`]s, then `filter_map` is much, much nicer to use.
+ /// [`filter`]: Iterator::filter
+ /// [`map`]: Iterator::map
///
/// # Examples
///
///
/// [`usize`]: type@usize
/// [`usize::MAX`]: crate::usize::MAX
- /// [`zip`]: #method.zip
+ /// [`zip`]: Iterator::zip
///
/// # Examples
///
Enumerate::new(self)
}
- /// Creates an iterator which can use `peek` to look at the next element of
+ /// Creates an iterator which can use [`peek`] to look at the next element of
/// the iterator without consuming it.
///
/// Adds a [`peek`] method to an iterator. See its documentation for
/// anything other than fetching the next value) of the [`next`] method
/// will occur.
///
- /// [`peek`]: crate::iter::Peekable::peek
- /// [`next`]: #tymethod.next
+ /// [`peek`]: Peekable::peek
+ /// [`next`]: Iterator::next
///
/// # Examples
///
/// Creates an iterator that [`skip`]s elements based on a predicate.
///
- /// [`skip`]: #method.skip
+ /// [`skip`]: Iterator::skip
///
/// `skip_while()` takes a closure as an argument. It will call this
/// closure on each element of the iterator, and ignore elements
///
/// Here's the same example, but with [`take_while`] and [`map`]:
///
- /// [`take_while`]: #method.take_while
- /// [`map`]: #method.map
+ /// [`take_while`]: Iterator::take_while
+ /// [`map`]: Iterator::map
///
/// ```
/// let a = [-1i32, 4, 0, 1];
/// It is also not specified what this iterator returns after the first` None` is returned.
/// If you need fused iterator, use [`fuse`].
///
- /// [`fuse`]: #method.fuse
+ /// [`fuse`]: Iterator::fuse
#[inline]
#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
/// An iterator adaptor similar to [`fold`] that holds internal state and
/// produces a new iterator.
///
- /// [`fold`]: #method.fold
+ /// [`fold`]: Iterator::fold
///
/// `scan()` takes two arguments: an initial value which seeds the internal
/// state, and a closure with two arguments, the first being a mutable
/// one item for each element, and `flat_map()`'s closure returns an
/// iterator for each element.
///
- /// [`map`]: #method.map
- /// [`flatten`]: #method.flatten
+ /// [`map`]: Iterator::map
+ /// [`flatten`]: Iterator::flatten
///
/// # Examples
///
/// two-dimensional and not one-dimensional. To get a one-dimensional
/// structure, you have to `flatten()` again.
///
- /// [`flat_map()`]: #method.flat_map
+ /// [`flat_map()`]: Iterator::flat_map
#[inline]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
fn flatten(self) -> Flatten<Self>
/// assert_eq!(Ok(vec![1, 3]), result);
/// ```
///
- /// [`iter`]: #tymethod.next
+ /// [`iter`]: Iterator::next
/// [`String`]: ../../std/string/struct.String.html
/// [`char`]: type@char
#[inline]
///
/// See also [`is_partitioned()`] and [`partition_in_place()`].
///
- /// [`is_partitioned()`]: #method.is_partitioned
- /// [`partition_in_place()`]: #method.partition_in_place
+ /// [`is_partitioned()`]: Iterator::is_partitioned
+ /// [`partition_in_place()`]: Iterator::partition_in_place
///
/// # Examples
///
///
/// See also [`is_partitioned()`] and [`partition()`].
///
- /// [`is_partitioned()`]: #method.is_partitioned
- /// [`partition()`]: #method.partition
+ /// [`is_partitioned()`]: Iterator::is_partitioned
+ /// [`partition()`]: Iterator::partition
///
/// # Examples
///
///
/// See also [`partition()`] and [`partition_in_place()`].
///
- /// [`partition()`]: #method.partition
- /// [`partition_in_place()`]: #method.partition_in_place
+ /// [`partition()`]: Iterator::partition
+ /// [`partition_in_place()`]: Iterator::partition_in_place
///
/// # Examples
///
/// This can also be thought of as the fallible form of [`for_each()`]
/// or as the stateless version of [`try_fold()`].
///
- /// [`for_each()`]: #method.for_each
- /// [`try_fold()`]: #method.try_fold
+ /// [`for_each()`]: Iterator::for_each
+ /// [`try_fold()`]: Iterator::try_fold
///
/// # Examples
///
/// // they're the same
/// assert_eq!(result, result2);
/// ```
+ #[doc(alias = "reduce")]
+ #[doc(alias = "inject")]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn fold<B, F>(mut self, init: B, mut f: F) -> B
accum
}
- /// The same as [`fold()`](#method.fold), but uses the first element in the
+ /// The same as [`fold()`], but uses the first element in the
/// iterator as the initial value, folding every subsequent element into it.
- /// If the iterator is empty, return `None`; otherwise, return the result
+ /// If the iterator is empty, return [`None`]; otherwise, return the result
/// of the fold.
///
+ /// [`fold()`]: Iterator::fold
+ ///
/// # Example
///
/// Find the maximum value:
F: FnMut(Self::Item) -> bool,
{
#[inline]
- fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> LoopState<(), ()> {
+ fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
move |(), x| {
- if f(x) { LoopState::Continue(()) } else { LoopState::Break(()) }
+ if f(x) { ControlFlow::CONTINUE } else { ControlFlow::BREAK }
}
}
- self.try_fold((), check(f)) == LoopState::Continue(())
+ self.try_fold((), check(f)) == ControlFlow::CONTINUE
}
/// Tests if any element of the iterator matches a predicate.
F: FnMut(Self::Item) -> bool,
{
#[inline]
- fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> LoopState<(), ()> {
+ fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
move |(), x| {
- if f(x) { LoopState::Break(()) } else { LoopState::Continue(()) }
+ if f(x) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
}
}
- self.try_fold((), check(f)) == LoopState::Break(())
+ self.try_fold((), check(f)) == ControlFlow::BREAK
}
/// Searches for an element of an iterator that satisfies a predicate.
#[inline]
fn check<T>(
mut predicate: impl FnMut(&T) -> bool,
- ) -> impl FnMut((), T) -> LoopState<(), T> {
+ ) -> impl FnMut((), T) -> ControlFlow<(), T> {
move |(), x| {
- if predicate(&x) { LoopState::Break(x) } else { LoopState::Continue(()) }
+ if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
}
}
///
/// `iter.find_map(f)` is equivalent to `iter.filter_map(f).next()`.
///
- ///
/// # Examples
///
/// ```
F: FnMut(Self::Item) -> Option<B>,
{
#[inline]
- fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> LoopState<(), B> {
+ fn check<T, B>(
+ mut f: impl FnMut(T) -> Option<B>,
+ ) -> impl FnMut((), T) -> ControlFlow<(), B> {
move |(), x| match f(x) {
- Some(x) => LoopState::Break(x),
- None => LoopState::Continue(()),
+ Some(x) => ControlFlow::Break(x),
+ None => ControlFlow::CONTINUE,
}
}
R: Try<Ok = bool>,
{
#[inline]
- fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> LoopState<(), Result<T, R::Error>>
+ fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<(), Result<T, R::Error>>
where
F: FnMut(&T) -> R,
R: Try<Ok = bool>,
{
move |(), x| match f(&x).into_result() {
- Ok(false) => LoopState::Continue(()),
- Ok(true) => LoopState::Break(Ok(x)),
- Err(x) => LoopState::Break(Err(x)),
+ Ok(false) => ControlFlow::CONTINUE,
+ Ok(true) => ControlFlow::Break(Ok(x)),
+ Err(x) => ControlFlow::Break(Err(x)),
}
}
#[inline]
fn check<T>(
mut predicate: impl FnMut(T) -> bool,
- ) -> impl FnMut(usize, T) -> LoopState<usize, usize> {
+ ) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> {
// The addition might panic on overflow
move |i, x| {
- if predicate(x) { LoopState::Break(i) } else { LoopState::Continue(Add::add(i, 1)) }
+ if predicate(x) {
+ ControlFlow::Break(i)
+ } else {
+ ControlFlow::Continue(Add::add(i, 1))
+ }
}
}
#[inline]
fn check<T>(
mut predicate: impl FnMut(T) -> bool,
- ) -> impl FnMut(usize, T) -> LoopState<usize, usize> {
+ ) -> impl FnMut(usize, T) -> ControlFlow<usize, usize> {
move |i, x| {
let i = i - 1;
- if predicate(x) { LoopState::Break(i) } else { LoopState::Continue(i) }
+ if predicate(x) { ControlFlow::Break(i) } else { ControlFlow::Continue(i) }
}
}
/// This is only possible if the iterator has an end, so `rev()` only
/// works on [`DoubleEndedIterator`]s.
///
- /// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html
- ///
/// # Examples
///
/// ```
///
/// This function is, in some sense, the opposite of [`zip`].
///
- /// [`zip`]: #method.zip
+ /// [`zip`]: Iterator::zip
///
/// # Examples
///
/// This is useful when you have an iterator over `&T`, but you need an
/// iterator over `T`.
///
- /// [`clone`]: crate::clone::Clone::clone
+ /// [`clone`]: Clone::clone
///
/// # Examples
///
Product::product(self)
}
- /// Lexicographically compares the elements of this `Iterator` with those
+ /// Lexicographically compares the elements of this [`Iterator`] with those
/// of another.
///
/// # Examples
self.cmp_by(other, |x, y| x.cmp(&y))
}
- /// Lexicographically compares the elements of this `Iterator` with those
+ /// Lexicographically compares the elements of this [`Iterator`] with those
/// of another with respect to the specified comparison function.
///
/// # Examples
}
}
- /// Lexicographically compares the elements of this `Iterator` with those
+ /// Lexicographically compares the elements of this [`Iterator`] with those
/// of another.
///
/// # Examples
self.partial_cmp_by(other, |x, y| x.partial_cmp(&y))
}
- /// Lexicographically compares the elements of this `Iterator` with those
+ /// Lexicographically compares the elements of this [`Iterator`] with those
/// of another with respect to the specified comparison function.
///
/// # Examples
}
}
- /// Determines if the elements of this `Iterator` are equal to those of
+ /// Determines if the elements of this [`Iterator`] are equal to those of
/// another.
///
/// # Examples
self.eq_by(other, |x, y| x == y)
}
- /// Determines if the elements of this `Iterator` are equal to those of
+ /// Determines if the elements of this [`Iterator`] are equal to those of
/// another with respect to the specified equality function.
///
/// # Examples
}
}
- /// Determines if the elements of this `Iterator` are unequal to those of
+ /// Determines if the elements of this [`Iterator`] are unequal to those of
/// another.
///
/// # Examples
!self.eq(other)
}
- /// Determines if the elements of this `Iterator` are lexicographically
+ /// Determines if the elements of this [`Iterator`] are lexicographically
/// less than those of another.
///
/// # Examples
/// assert_eq!([1].iter().lt([1].iter()), false);
/// assert_eq!([1].iter().lt([1, 2].iter()), true);
/// assert_eq!([1, 2].iter().lt([1].iter()), false);
+ /// assert_eq!([1, 2].iter().lt([1, 2].iter()), false);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
fn lt<I>(self, other: I) -> bool
self.partial_cmp(other) == Some(Ordering::Less)
}
- /// Determines if the elements of this `Iterator` are lexicographically
+ /// Determines if the elements of this [`Iterator`] are lexicographically
/// less or equal to those of another.
///
/// # Examples
/// assert_eq!([1].iter().le([1].iter()), true);
/// assert_eq!([1].iter().le([1, 2].iter()), true);
/// assert_eq!([1, 2].iter().le([1].iter()), false);
+ /// assert_eq!([1, 2].iter().le([1, 2].iter()), true);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
fn le<I>(self, other: I) -> bool
matches!(self.partial_cmp(other), Some(Ordering::Less | Ordering::Equal))
}
- /// Determines if the elements of this `Iterator` are lexicographically
+ /// Determines if the elements of this [`Iterator`] are lexicographically
/// greater than those of another.
///
/// # Examples
/// assert_eq!([1].iter().gt([1].iter()), false);
/// assert_eq!([1].iter().gt([1, 2].iter()), false);
/// assert_eq!([1, 2].iter().gt([1].iter()), true);
+ /// assert_eq!([1, 2].iter().gt([1, 2].iter()), false);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
fn gt<I>(self, other: I) -> bool
self.partial_cmp(other) == Some(Ordering::Greater)
}
- /// Determines if the elements of this `Iterator` are lexicographically
+ /// Determines if the elements of this [`Iterator`] are lexicographically
/// greater than or equal to those of another.
///
/// # Examples
/// assert_eq!([1].iter().ge([1].iter()), true);
/// assert_eq!([1].iter().ge([1, 2].iter()), false);
/// assert_eq!([1, 2].iter().ge([1].iter()), true);
+ /// assert_eq!([1, 2].iter().ge([1, 2].iter()), true);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
fn ge<I>(self, other: I) -> bool
/// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// ```
///
- /// [`is_sorted`]: #method.is_sorted
+ /// [`is_sorted`]: Iterator::is_sorted
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
fn is_sorted_by<F>(mut self, mut compare: F) -> bool
where
/// the elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see
/// its documentation for more information.
///
- /// [`is_sorted`]: #method.is_sorted
+ /// [`is_sorted`]: Iterator::is_sorted
///
/// # Examples
///
}
/// See [TrustedRandomAccess]
+ // The unusual name is to avoid name collisions in method resolution
+ // see #76479.
#[inline]
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
+ fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+ (**self).advance_by(n)
+ }
fn nth(&mut self, n: usize) -> Option<Self::Item> {
(**self).nth(n)
}