Closed
Description
On my project, I recently found a problem that I can't implement a comfortable interface that do operation on Iterator
directly using existing API.
/* not work because iterator state is changed after each operation */
pub fn do_operateion<'a, T, U>(input_iter: &mut T, output_iter: &mut U)
where
T: Iterator<Item = &'a f32>,
U: Iterator<Item = &'a mut f32>,
{
let temp = input_iter.skip(2).map(...).sum();
output_iter.step_by(2).zip(input_iter).for_each(|a, b| *a * temp);
output_iter.skip(1).step_by(2).zip(input_iter).for_each(|a, b| *a * temp * 123.0);
}
Hence the idea of adding StateSavableIterator
trait:
pub trait StateSavableIterator: Iterator {
type IteratorState;
fn save(&self) -> IteratorState;
fn load(&mut self, state: &IteratorState) -> Self;
}
So that I can:
pub fn do_operateion<'a, T, U>(input_iter: &mut T, output_iter: &mut U)
where
T: StateSavableIterator<Item = &'a f32>,
U: StateSavableIterator<Item = &'a mut f32>,
{
let input_init = input_iter.save();
let out_init = output_iter.save();
let temp = input_iter.load(input_init).skip(2).map(...).sum();
output_iter.load(out_init).step_by(2).zip(input_iter.load(input_init)).for_each(|a, b| *a * temp);
output_iter.load(out_init).skip(1).step_by(2).zip(input_iter.load(input_init)).for_each(|a, b| *a * temp * 123.0);
}
We don't have to pass &slice
anymore! This trait benefits to writing more generic and readable API.