pub struct StatefulMapIterator<I, S, F> {
state: S,
iter: I,
func: F,
}
impl<I: Iterator, S, F, FO> Iterator for StatefulMapIterator<I, S, F>
where
F: FnMut(&mut S, I::Item) -> FO,
{
type Item = FO;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|x| (self.func)(&mut self.state, x))
}
}
pub trait IntoStatefulMapIterator: IntoIterator {
fn stateful_map<S, F>(self, func: F, state: S) -> StatefulMapIterator<Self::IntoIter, S, F>
where
Self: Sized,
{
StatefulMapIterator {
iter: self.into_iter(),
state,
func,
}
}
}
impl<I: IntoIterator> IntoStatefulMapIterator for I {}
#[cfg(test)]
mod tests {
use crate::stateful::IntoStatefulMapIterator;
#[test]
fn test_simple_stateful() {
struct State {
total: u8,
}
fn cumsum(state: &mut State, x: u8) -> u8 {
state.total += x;
state.total
}
let values = (0_u8..16).collect::<Vec<_>>();
let mapped = values
.stateful_map(cumsum, State { total: 0 })
.collect::<Vec<_>>();
println!("{:?}", mapped);
}
#[test]
fn test_fib() {
struct State {
prev0: usize,
prev1: usize,
}
fn fib(state: &mut State, _x: usize) -> usize {
let next = state.prev0 + state.prev1;
state.prev0 = state.prev1;
state.prev1 = next;
next
}
let values = (0..16).collect::<Vec<_>>();
let mapped = values
.stateful_map(fib, State { prev0: 1, prev1: 0 })
.collect::<Vec<_>>();
println!("{:?}", mapped);
}
#[test]
fn test_reuse_alloc() {
struct State {
buffer: Vec<u8>,
}
fn arbitrary_vector_stuff(state: &mut State, _x: u8) -> u8 {
for item in state.buffer.iter_mut() {
for _ in 0..100 {
*item += 1;
*item -= 1;
}
}
_x
}
let values = (0..16).collect::<Vec<_>>();
let mapped = values
.stateful_map(
arbitrary_vector_stuff,
State {
buffer: vec![0; 1000000],
},
)
.collect::<Vec<_>>();
println!("{:?}", mapped);
}
}