successors.rs - source
Description: Source of the Rust file `library/core/src/iter/sources/successors.rs`.
Keywords: rust, rustlang, rust-lang

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66

    use crate::{fmt, iter::FusedIterator};

    /// Creates a new iterator where each successive item is computed based on the preceding one.
    ///
    /// The iterator starts with the given first item (if any)
    /// and calls the given `FnMut(&T) -> Option<T>` closure to compute each item’s successor.
    ///
    /// ```
    /// use std::iter::successors;
    ///
    /// let powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
    /// assert_eq!(powers_of_10.collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
    /// ```
    #[stable(feature = "iter_successors", since = "1.34.0")]
    pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F>
    where
        F: FnMut(&T) -> Option<T>,
    {
        // If this function returned `impl Iterator<Item=T>`
        // it could be based on `unfold` and not need a dedicated type.
        // However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
        Successors { next: first, succ }
    }

    /// An new iterator where each successive item is computed based on the preceding one.
    ///
    /// This `struct` is created by the [`iter::successors()`] function.
    /// See its documentation for more.
    ///
    /// [`iter::successors()`]: successors
    #[derive(Clone)]
    #[stable(feature = "iter_successors", since = "1.34.0")]
    pub struct Successors<T, F> {
        next: Option<T>,
        succ: F,
    }

    #[stable(feature = "iter_successors", since = "1.34.0")]
    impl<T, F> Iterator for Successors<T, F>
    where
        F: FnMut(&T) -> Option<T>,
    {
        type Item = T;

        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            let item = self.next.take()?;
            self.next = (self.succ)(&item);
            Some(item)
        }

        #[inline]
        fn size_hint(&self) -> (usize, Option<usize>) {
            if self.next.is_some() { (1, None) } else { (0, Some(0)) }
        }
    }

    #[stable(feature = "iter_successors", since = "1.34.0")]
    impl<T, F> FusedIterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {}

    #[stable(feature = "iter_successors", since = "1.34.0")]
    impl<T: fmt::Debug, F> fmt::Debug for Successors<T, F> {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("Successors").field("next", &self.next).finish()
        }
    }