successors.rs - source
Description: Source of the Rust file `library/core/src/iter/sources/successors.rs`.

#
core/iter/sources/
successors.rs

    1use crate::fmt;
    2use crate::iter::FusedIterator;
    3
    4/// Creates an iterator which, starting from an initial item,
    5/// computes each successive item from the preceding one.
    6///
    7/// This iterator stores an optional item (`Option<T>`) and a successor closure (`impl FnMut(&T) -> Option<T>`).
    8/// Its `next` method returns the stored optional item and
    9/// if it is `Some(val)` calls the stored closure on `&val` to compute and store its successor.
    10/// The iterator will apply the closure successively to the stored option's value until the option is `None`.
    11/// This also means that once the stored option is `None` it will remain `None`,
    12/// as the closure will not be called again, so the created iterator is a [`FusedIterator`].
    13/// The iterator's items will be the initial item and all of its successors as calculated by the successor closure.
    14///
    15/// ```
    16/// use std::iter::successors;
    17///
    18/// let powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
    19/// assert_eq!(powers_of_10.collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
    20/// ```
    21#[stable(feature = "iter_successors", since = "1.34.0")]
    22pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F>
    23where
    24    F: FnMut(&T) -> Option<T>,
    25{
    26    // If this function returned `impl Iterator<Item=T>`
    27    // it could be based on `from_fn` and not need a dedicated type.
    28    // However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
    29    Successors { next: first, succ }
    30}
    31
    32/// An iterator which, starting from an initial item,
    33/// computes each successive item from the preceding one.
    34///
    35/// This `struct` is created by the [`iter::successors()`] function.
    36/// See its documentation for more.
    37///
    38/// [`iter::successors()`]: successors
    39#[derive(Clone)]
    40#[stable(feature = "iter_successors", since = "1.34.0")]
    41pub struct Successors<T, F> {
    42    next: Option<T>,
    43    succ: F,
    44}
    45
    46#[stable(feature = "iter_successors", since = "1.34.0")]
    47impl<T, F> Iterator for Successors<T, F>
    48where
    49    F: FnMut(&T) -> Option<T>,
    50{
    51    type Item = T;
    52
    53    #[inline]
    54    fn next(&mut self) -> Option<Self::Item> {
    55        let item = self.next.take()?;
    56        self.next = (self.succ)(&item);
    57        Some(item)
    58    }
    59
    60    #[inline]
    61    fn size_hint(&self) -> (usize, Option<usize>) {
    62        if self.next.is_some() { (1, None) } else { (0, Some(0)) }
    63    }
    64}
    65
    66#[stable(feature = "iter_successors", since = "1.34.0")]
    67impl<T, F> FusedIterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {}
    68
    69#[stable(feature = "iter_successors", since = "1.34.0")]
    70impl<T: fmt::Debug, F> fmt::Debug for Successors<T, F> {
    71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    72        f.debug_struct("Successors").field("next", &self.next).finish()
    73    }
    74}