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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
//! Iterators that are sources (produce elements from parameters, //! not from another iterator). /// See [`repeat_call`](../fn.repeat_call.html) for more information. pub struct RepeatCall<F> { f: F, } /// An iterator source that produces elements indefinitely by calling /// a given closure. /// /// Iterator element type is the return type of the closure. /// /// ``` /// use itertools::repeat_call; /// use itertools::Itertools; /// use std::collections::BinaryHeap; /// /// let mut heap = BinaryHeap::from(vec![2, 5, 3, 7, 8]); /// /// // extract each element in sorted order /// for element in repeat_call(|| heap.pop()).while_some() { /// print!("{}", element); /// } /// /// itertools::assert_equal( /// repeat_call(|| 1).take(5), /// vec![1, 1, 1, 1, 1] /// ); /// ``` pub fn repeat_call<F>(function: F) -> RepeatCall<F> { RepeatCall { f: function } } impl<A, F> Iterator for RepeatCall<F> where F: FnMut() -> A { type Item = A; #[inline] fn next(&mut self) -> Option<A> { Some((self.f)()) } fn size_hint(&self) -> (usize, Option<usize>) { (usize::max_value(), None) } } /// Creates a new unfold source with the specified closure as the "iterator /// function" and an initial state to eventually pass to the closure /// /// `unfold` is a general iterator builder: it has a mutable state value, /// and a closure with access to the state that produces the next value. /// /// This more or less equivalent to a regular struct with an `Iterator` /// implementation, and is useful for one-off iterators. /// /// ``` /// // an iterator that yields sequential Fibonacci numbers, /// // and stops at the maximum representable value. /// /// use itertools::unfold; /// /// let mut fibonacci = unfold((1_u32, 1_u32), |state| { /// let (ref mut x1, ref mut x2) = *state; /// /// // Attempt to get the next Fibonacci number /// let next = x1.saturating_add(*x2); /// /// // Shift left: ret <- x1 <- x2 <- next /// let ret = *x1; /// *x1 = *x2; /// *x2 = next; /// /// // If addition has saturated at the maximum, we are finished /// if ret == *x1 && ret > 1 { /// return None; /// } /// /// Some(ret) /// }); /// /// itertools::assert_equal(fibonacci.by_ref().take(8), /// vec![1, 1, 2, 3, 5, 8, 13, 21]); /// assert_eq!(fibonacci.last(), Some(2_971_215_073)) /// ``` pub fn unfold<A, St, F>(initial_state: St, f: F) -> Unfold<St, F> where F: FnMut(&mut St) -> Option<A> { Unfold { f: f, state: initial_state, } } /// See [`unfold`](../fn.unfold.html) for more information. #[derive(Clone)] pub struct Unfold<St, F> { f: F, /// Internal state that will be passed to the closure on the next iteration pub state: St, } impl<A, St, F> Iterator for Unfold<St, F> where F: FnMut(&mut St) -> Option<A> { type Item = A; #[inline] fn next(&mut self) -> Option<A> { (self.f)(&mut self.state) } #[inline] fn size_hint(&self) -> (usize, Option<usize>) { // no possible known bounds at this point (0, None) } }