Wed, 06 Nov 2024 15:34:17 -0500
Add iter_init
src/iterate.rs | file | annotate | diff | comparison | revisions |
--- a/src/iterate.rs Wed Oct 30 14:22:06 2024 -0500 +++ b/src/iterate.rs Wed Nov 06 15:34:17 2024 -0500 @@ -135,7 +135,7 @@ /// The closure `calc_objective` should return an arbitrary value of type `V`, to be inserted /// into the log, or whatever is deemed by the [`AlgIterator`]. For usage instructions see the /// [module documentation][self]. - fn if_verbose<V, E : Error>(self, calc_objective : impl FnMut() -> V) -> Step<V, Self, E>; + fn if_verbose<V, E : Error>(self, calc_objective : impl FnOnce() -> V) -> Step<V, Self, E>; /// Returns the current iteration count. fn iteration(&self) -> usize; @@ -260,7 +260,7 @@ self.prepare().iterate(step) } - /// Iterate the the closure `step`. + /// Iterate the closure `step`. /// /// The closure should accept a `state` parameter (satisfying the trait [`AlgIteratorState`]), /// It should return the output of @@ -406,6 +406,19 @@ algi : Rc::new(RefCell::new(self.prepare())), } } + + /// Returns an an [`std::iter::Iterator`] that can be used in a `for`-loop, + /// also inputting an initial iteration status calculated by `f` if needed. + fn iter_init(self, f : impl FnOnce() -> <Self::Iter as AlgIterator>::Input) + -> AlgIteratorIterator<Self::Iter> { + let mut i = self.prepare(); + let st = i.state(); + let step : Step<<Self::Iter as AlgIterator>::Input, Self::State> = st.if_verbose(f); + i.poststep(step); + AlgIteratorIterator { + algi : Rc::new(RefCell::new(i)), + } + } } /// Options for [`BasicAlgIteratorFactory`]. @@ -598,7 +611,7 @@ impl AlgIteratorState for BasicState { #[inline] - fn if_verbose<V, E : Error>(self, mut calc_objective : impl FnMut() -> V) -> Step<V, Self, E> { + fn if_verbose<V, E : Error>(self, calc_objective : impl FnOnce() -> V) -> Step<V, Self, E> { if self.calc { Step::Result(calc_objective(), self) } else { @@ -1062,12 +1075,12 @@ /// This function may panic if result reporting is not ordered correctly (an unlikely mistake /// if using this facility correctly). For a version that propagates errors, see /// [`Self::if_verbose_check`]. - pub fn if_verbose(self, calc_objective : impl FnMut() -> I::Input) { + pub fn if_verbose(self, calc_objective : impl FnOnce() -> I::Input) { self.if_verbose_check(calc_objective).unwrap() } /// Version of [`Self::if_verbose`] that propagates errors instead of panicking. - pub fn if_verbose_check(self, calc_objective : impl FnMut() -> I::Input) + pub fn if_verbose_check(self, calc_objective : impl FnOnce() -> I::Input) -> Result<(), IterationError> { let mut algi = match RefCell::try_borrow_mut(&self.algi) { Err(_) => return Err(IterationError::ReportingOrderingError),