Tune RepeatWith::try_fold and Take::for_each and Vec::extend_trusted
This commit is contained in:
parent
a8954f1f6a
commit
9d68a1a74c
6 changed files with 73 additions and 6 deletions
|
@ -75,7 +75,6 @@ where
|
|||
#[inline]
|
||||
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
|
||||
where
|
||||
Self: Sized,
|
||||
Fold: FnMut(Acc, Self::Item) -> R,
|
||||
R: Try<Output = Acc>,
|
||||
{
|
||||
|
@ -100,6 +99,26 @@ where
|
|||
|
||||
impl_fold_via_try_fold! { fold -> try_fold }
|
||||
|
||||
#[inline]
|
||||
fn for_each<F: FnMut(Self::Item)>(mut self, f: F) {
|
||||
// The default implementation would use a unit accumulator, so we can
|
||||
// avoid a stateful closure by folding over the remaining number
|
||||
// of items we wish to return instead.
|
||||
fn check<'a, Item>(
|
||||
mut action: impl FnMut(Item) + 'a,
|
||||
) -> impl FnMut(usize, Item) -> Option<usize> + 'a {
|
||||
move |more, x| {
|
||||
action(x);
|
||||
more.checked_sub(1)
|
||||
}
|
||||
}
|
||||
|
||||
let remaining = self.n;
|
||||
if remaining > 0 {
|
||||
self.iter.try_fold(remaining - 1, check(f));
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::iter::{FusedIterator, TrustedLen};
|
||||
use crate::ops::Try;
|
||||
|
||||
/// Creates a new iterator that repeats elements of type `A` endlessly by
|
||||
/// applying the provided closure, the repeater, `F: FnMut() -> A`.
|
||||
|
@ -89,6 +90,22 @@ impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
|
|||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(usize::MAX, None)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
|
||||
where
|
||||
Fold: FnMut(Acc, Self::Item) -> R,
|
||||
R: Try<Output = Acc>,
|
||||
{
|
||||
// This override isn't strictly needed, but avoids the need to optimize
|
||||
// away the `next`-always-returns-`Some` and emphasizes that the `?`
|
||||
// is the only way to exit the loop.
|
||||
|
||||
loop {
|
||||
let item = (self.repeater)();
|
||||
init = fold(init, item)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue