1 | use crate::fmt; |
2 | use 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" )] |
22 | pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F> |
23 | where |
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" )] |
41 | pub struct Successors<T, F> { |
42 | next: Option<T>, |
43 | succ: F, |
44 | } |
45 | |
46 | #[stable (feature = "iter_successors" , since = "1.34.0" )] |
47 | impl<T, F> Iterator for Successors<T, F> |
48 | where |
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: T = 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" )] |
67 | impl<T, F> FusedIterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {} |
68 | |
69 | #[stable (feature = "iter_successors" , since = "1.34.0" )] |
70 | impl<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(name:"next" , &self.next).finish() |
73 | } |
74 | } |
75 | |