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