-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed
Labels
T-libs-apiRelevant to the library API team, which will review and decide on the RFC.Relevant to the library API team, which will review and decide on the RFC.
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.
Metadata
Metadata
Assignees
Labels
T-libs-apiRelevant to the library API team, which will review and decide on the RFC.Relevant to the library API team, which will review and decide on the RFC.