Skip to content

Commit 16da81c

Browse files
committed
Add better Iterator::try_fold and Iterator::fold implementations for &mut impl Iterator
1 parent 032fa35 commit 16da81c

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

library/core/src/iter/traits/iterator.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3430,4 +3430,77 @@ impl<I: Iterator + ?Sized> Iterator for &mut I {
34303430
fn nth(&mut self, n: usize) -> Option<Self::Item> {
34313431
(**self).nth(n)
34323432
}
3433+
#[inline]
3434+
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
3435+
where
3436+
F: FnMut(B, Self::Item) -> R,
3437+
R: Try<Ok = B>,
3438+
{
3439+
SpecSizedIterator::try_fold(self, init, f)
3440+
}
3441+
#[inline]
3442+
fn fold<B, F>(self, init: B, f: F) -> B
3443+
where
3444+
F: FnMut(B, Self::Item) -> B,
3445+
{
3446+
SpecSizedIterator::fold(self, init, f)
3447+
}
3448+
}
3449+
3450+
trait SpecSizedIterator: Iterator {
3451+
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
3452+
where
3453+
F: FnMut(B, Self::Item) -> R,
3454+
R: Try<Ok = B>;
3455+
fn fold<B, F>(self, init: B, f: F) -> B
3456+
where
3457+
F: FnMut(B, Self::Item) -> B;
3458+
}
3459+
3460+
impl<I: Iterator + ?Sized> SpecSizedIterator for &mut I {
3461+
#[inline]
3462+
default fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
3463+
where
3464+
F: FnMut(B, Self::Item) -> R,
3465+
R: Try<Ok = B>,
3466+
{
3467+
let mut accum = init;
3468+
while let Some(x) = self.next() {
3469+
accum = f(accum, x)?;
3470+
}
3471+
try { accum }
3472+
}
3473+
#[inline]
3474+
default fn fold<B, F>(mut self, init: B, mut f: F) -> B
3475+
where
3476+
F: FnMut(B, Self::Item) -> B,
3477+
{
3478+
let mut accum = init;
3479+
while let Some(x) = (&mut self).next() {
3480+
accum = f(accum, x);
3481+
}
3482+
accum
3483+
}
3484+
}
3485+
3486+
impl<I: Iterator + Sized> SpecSizedIterator for &mut I {
3487+
#[inline]
3488+
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
3489+
where
3490+
F: FnMut(B, Self::Item) -> R,
3491+
R: Try<Ok = B>,
3492+
{
3493+
(**self).try_fold(init, f)
3494+
}
3495+
#[inline]
3496+
fn fold<B, F>(self, init: B, f: F) -> B
3497+
where
3498+
F: FnMut(B, Self::Item) -> B,
3499+
{
3500+
#[inline]
3501+
fn ok<T, U>(mut f: impl FnMut(T, U) -> T) -> impl FnMut(T, U) -> Result<T, !> {
3502+
move |acc, x| Ok(f(acc, x))
3503+
}
3504+
self.try_fold(init, ok(f)).unwrap()
3505+
}
34333506
}

0 commit comments

Comments
 (0)