Skip to content

Commit f78d59a

Browse files
committed
Add better DoubleEndedIterator::try_rfold and DoubleEndedIterator::rfold implementations for &mut impl DoubleEndedIterator
1 parent 16da81c commit f78d59a

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

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

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,4 +360,77 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
360360
fn nth_back(&mut self, n: usize) -> Option<I::Item> {
361361
(**self).nth_back(n)
362362
}
363+
#[inline]
364+
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
365+
where
366+
F: FnMut(B, Self::Item) -> R,
367+
R: Try<Ok = B>,
368+
{
369+
SpecSizedDoubleEndedIterator::try_rfold(self, init, f)
370+
}
371+
#[inline]
372+
fn rfold<B, F>(self, init: B, f: F) -> B
373+
where
374+
F: FnMut(B, Self::Item) -> B,
375+
{
376+
SpecSizedDoubleEndedIterator::rfold(self, init, f)
377+
}
378+
}
379+
380+
trait SpecSizedDoubleEndedIterator: DoubleEndedIterator {
381+
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
382+
where
383+
F: FnMut(B, Self::Item) -> R,
384+
R: Try<Ok = B>;
385+
fn rfold<B, F>(self, init: B, f: F) -> B
386+
where
387+
F: FnMut(B, Self::Item) -> B;
388+
}
389+
390+
impl<I: DoubleEndedIterator + ?Sized> SpecSizedDoubleEndedIterator for &mut I {
391+
#[inline]
392+
default fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
393+
where
394+
F: FnMut(B, Self::Item) -> R,
395+
R: Try<Ok = B>,
396+
{
397+
let mut accum = init;
398+
while let Some(x) = self.next_back() {
399+
accum = f(accum, x)?;
400+
}
401+
try { accum }
402+
}
403+
#[inline]
404+
default fn rfold<B, F>(mut self, init: B, mut f: F) -> B
405+
where
406+
F: FnMut(B, Self::Item) -> B,
407+
{
408+
let mut accum = init;
409+
while let Some(x) = (&mut self).next_back() {
410+
accum = f(accum, x);
411+
}
412+
accum
413+
}
414+
}
415+
416+
impl<I: DoubleEndedIterator + Sized> SpecSizedDoubleEndedIterator for &mut I {
417+
#[inline]
418+
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
419+
where
420+
F: FnMut(B, Self::Item) -> R,
421+
R: Try<Ok = B>,
422+
{
423+
(**self).try_rfold(init, f)
424+
}
425+
#[inline]
426+
fn rfold<B, F>(self, init: B, f: F) -> B
427+
where
428+
F: FnMut(B, Self::Item) -> B,
429+
{
430+
#[inline]
431+
fn ok<T, U>(mut f: impl FnMut(T, U) -> T) -> impl FnMut(T, U) -> Result<T, !> {
432+
move |acc, x| Ok(f(acc, x))
433+
}
434+
self.try_rfold(init, ok(f)).unwrap()
435+
}
363436
}

0 commit comments

Comments
 (0)