]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | //! Iterators that are sources (produce elements from parameters, |
2 | //! not from another iterator). | |
3 | #![allow(deprecated)] | |
4 | ||
5 | use std::fmt; | |
6 | use std::mem; | |
7 | ||
8 | /// See [`repeat_call`](../fn.repeat_call.html) for more information. | |
9 | #[deprecated(note="Use std repeat_with() instead", since="0.8")] | |
10 | pub struct RepeatCall<F> { | |
11 | f: F, | |
12 | } | |
13 | ||
14 | impl<F> fmt::Debug for RepeatCall<F> | |
15 | { | |
16 | debug_fmt_fields!(RepeatCall, ); | |
17 | } | |
18 | ||
19 | /// An iterator source that produces elements indefinitely by calling | |
20 | /// a given closure. | |
21 | /// | |
22 | /// Iterator element type is the return type of the closure. | |
23 | /// | |
24 | /// ``` | |
25 | /// use itertools::repeat_call; | |
26 | /// use itertools::Itertools; | |
27 | /// use std::collections::BinaryHeap; | |
28 | /// | |
29 | /// let mut heap = BinaryHeap::from(vec![2, 5, 3, 7, 8]); | |
30 | /// | |
31 | /// // extract each element in sorted order | |
32 | /// for element in repeat_call(|| heap.pop()).while_some() { | |
33 | /// print!("{}", element); | |
34 | /// } | |
35 | /// | |
36 | /// itertools::assert_equal( | |
37 | /// repeat_call(|| 1).take(5), | |
38 | /// vec![1, 1, 1, 1, 1] | |
39 | /// ); | |
40 | /// ``` | |
41 | #[deprecated(note="Use std repeat_with() instead", since="0.8")] | |
42 | pub fn repeat_call<F, A>(function: F) -> RepeatCall<F> | |
43 | where F: FnMut() -> A | |
44 | { | |
45 | RepeatCall { f: function } | |
46 | } | |
47 | ||
48 | impl<A, F> Iterator for RepeatCall<F> | |
49 | where F: FnMut() -> A | |
50 | { | |
51 | type Item = A; | |
52 | ||
53 | #[inline] | |
54 | fn next(&mut self) -> Option<A> { | |
55 | Some((self.f)()) | |
56 | } | |
57 | ||
58 | fn size_hint(&self) -> (usize, Option<usize>) { | |
59 | (usize::max_value(), None) | |
60 | } | |
61 | } | |
62 | ||
63 | /// Creates a new unfold source with the specified closure as the "iterator | |
64 | /// function" and an initial state to eventually pass to the closure | |
65 | /// | |
66 | /// `unfold` is a general iterator builder: it has a mutable state value, | |
67 | /// and a closure with access to the state that produces the next value. | |
68 | /// | |
69 | /// This more or less equivalent to a regular struct with an `Iterator` | |
70 | /// implementation, and is useful for one-off iterators. | |
71 | /// | |
72 | /// ``` | |
73 | /// // an iterator that yields sequential Fibonacci numbers, | |
74 | /// // and stops at the maximum representable value. | |
75 | /// | |
76 | /// use itertools::unfold; | |
77 | /// | |
78 | /// let (mut x1, mut x2) = (1u32, 1u32); | |
79 | /// let mut fibonacci = unfold((), move |_| { | |
80 | /// // Attempt to get the next Fibonacci number | |
81 | /// let next = x1.saturating_add(x2); | |
82 | /// | |
83 | /// // Shift left: ret <- x1 <- x2 <- next | |
84 | /// let ret = x1; | |
85 | /// x1 = x2; | |
86 | /// x2 = next; | |
87 | /// | |
88 | /// // If addition has saturated at the maximum, we are finished | |
89 | /// if ret == x1 && ret > 1 { | |
90 | /// return None; | |
91 | /// } | |
92 | /// | |
93 | /// Some(ret) | |
94 | /// }); | |
95 | /// | |
96 | /// itertools::assert_equal(fibonacci.by_ref().take(8), | |
97 | /// vec![1, 1, 2, 3, 5, 8, 13, 21]); | |
98 | /// assert_eq!(fibonacci.last(), Some(2_971_215_073)) | |
99 | /// ``` | |
100 | pub fn unfold<A, St, F>(initial_state: St, f: F) -> Unfold<St, F> | |
101 | where F: FnMut(&mut St) -> Option<A> | |
102 | { | |
103 | Unfold { | |
104 | f: f, | |
105 | state: initial_state, | |
106 | } | |
107 | } | |
108 | ||
109 | impl<St, F> fmt::Debug for Unfold<St, F> | |
110 | where St: fmt::Debug, | |
111 | { | |
112 | debug_fmt_fields!(Unfold, state); | |
113 | } | |
114 | ||
115 | /// See [`unfold`](../fn.unfold.html) for more information. | |
116 | #[derive(Clone)] | |
117 | #[must_use = "iterators are lazy and do nothing unless consumed"] | |
118 | pub struct Unfold<St, F> { | |
119 | f: F, | |
120 | /// Internal state that will be passed to the closure on the next iteration | |
121 | pub state: St, | |
122 | } | |
123 | ||
124 | impl<A, St, F> Iterator for Unfold<St, F> | |
125 | where F: FnMut(&mut St) -> Option<A> | |
126 | { | |
127 | type Item = A; | |
128 | ||
129 | #[inline] | |
130 | fn next(&mut self) -> Option<A> { | |
131 | (self.f)(&mut self.state) | |
132 | } | |
133 | ||
134 | #[inline] | |
135 | fn size_hint(&self) -> (usize, Option<usize>) { | |
136 | // no possible known bounds at this point | |
137 | (0, None) | |
138 | } | |
139 | } | |
140 | ||
141 | /// An iterator that infinitely applies function to value and yields results. | |
142 | /// | |
143 | /// This `struct` is created by the [`iterate()`] function. See its documentation for more. | |
144 | /// | |
145 | /// [`iterate()`]: ../fn.iterate.html | |
146 | #[derive(Clone)] | |
147 | #[must_use = "iterators are lazy and do nothing unless consumed"] | |
148 | pub struct Iterate<St, F> { | |
149 | state: St, | |
150 | f: F, | |
151 | } | |
152 | ||
153 | impl<St, F> fmt::Debug for Iterate<St, F> | |
154 | where St: fmt::Debug, | |
155 | { | |
156 | debug_fmt_fields!(Iterate, state); | |
157 | } | |
158 | ||
159 | impl<St, F> Iterator for Iterate<St, F> | |
160 | where F: FnMut(&St) -> St | |
161 | { | |
162 | type Item = St; | |
163 | ||
164 | #[inline] | |
165 | fn next(&mut self) -> Option<Self::Item> { | |
166 | let next_state = (self.f)(&self.state); | |
167 | Some(mem::replace(&mut self.state, next_state)) | |
168 | } | |
169 | ||
170 | #[inline] | |
171 | fn size_hint(&self) -> (usize, Option<usize>) { | |
172 | (usize::max_value(), None) | |
173 | } | |
174 | } | |
175 | ||
176 | /// Creates a new iterator that infinitely applies function to value and yields results. | |
177 | /// | |
178 | /// ``` | |
179 | /// use itertools::iterate; | |
180 | /// | |
181 | /// itertools::assert_equal(iterate(1, |&i| i * 3).take(5), vec![1, 3, 9, 27, 81]); | |
182 | /// ``` | |
183 | pub fn iterate<St, F>(initial_value: St, f: F) -> Iterate<St, F> | |
184 | where F: FnMut(&St) -> St | |
185 | { | |
186 | Iterate { | |
187 | state: initial_value, | |
188 | f: f, | |
189 | } | |
190 | } |