@@ -59,3 +59,75 @@ impl<A, F> DoubleEndedIterator for RepeatCall<F> where
59
59
}
60
60
61
61
62
+ /// **Unfold** is a general iterator builder: it has a mutable state value,
63
+ /// and a closure with access to the state that produces the next value.
64
+ ///
65
+ /// This more or less equivalent to a regular struct with an **Iterator**
66
+ /// implementation, and is useful for one-off iterators.
67
+ ///
68
+ /// ```
69
+ /// // an example of iterator that yields sequential Fibonacci numbers, and stops
70
+ /// // on overflow.
71
+ /// use itertools::Unfold;
72
+ ///
73
+ /// // This iterator will yield up to the last Fibonacci number before the max
74
+ /// // value of `u32`. You can simply change `u32` to `u64` in this line if
75
+ /// // you want higher values than that.
76
+ /// let mut fibonacci = Unfold::new((Some(0u32), Some(1u32)),
77
+ /// |&mut (ref mut x2, ref mut x1)| {
78
+ /// // Attempt to get the next Fibonacci number
79
+ /// // `x1` will be `None` if previously overflowed.
80
+ /// let next = match (*x2, *x1) {
81
+ /// (Some(x2), Some(x1)) => x2.checked_add(x1),
82
+ /// _ => None,
83
+ /// };
84
+ ///
85
+ /// // Shift left: ret <- x2 <- x1 <- next
86
+ /// let ret = *x2;
87
+ /// *x2 = *x1;
88
+ /// *x1 = next;
89
+ ///
90
+ /// ret
91
+ /// });
92
+ ///
93
+ /// itertools::assert_equal(fibonacci.take(8),
94
+ /// vec![0, 1, 1, 2, 3, 5, 8, 13]);
95
+ /// ```
96
+ #[ derive( Clone ) ]
97
+ pub struct Unfold < St , F > {
98
+ f : F ,
99
+ /// Internal state that will be passed to the closure on the next iteration
100
+ pub state : St ,
101
+ }
102
+
103
+ impl < A , St , F > Unfold < St , F >
104
+ where F : FnMut ( & mut St ) -> Option < A >
105
+ {
106
+ /// Creates a new iterator with the specified closure as the "iterator
107
+ /// function" and an initial state to eventually pass to the closure
108
+ #[ inline]
109
+ pub fn new ( initial_state : St , f : F ) -> Unfold < St , F > {
110
+ Unfold {
111
+ f : f,
112
+ state : initial_state
113
+ }
114
+ }
115
+ }
116
+
117
+ impl < A , St , F > Iterator for Unfold < St , F >
118
+ where F : FnMut ( & mut St ) -> Option < A >
119
+ {
120
+ type Item = A ;
121
+
122
+ #[ inline]
123
+ fn next ( & mut self ) -> Option < A > {
124
+ ( self . f ) ( & mut self . state )
125
+ }
126
+
127
+ #[ inline]
128
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
129
+ // no possible known bounds at this point
130
+ ( 0 , None )
131
+ }
132
+ }
133
+
0 commit comments