Skip to content

Commit 959bd48

Browse files
committed
Add some more rfold implementations.
1 parent c2abf8f commit 959bd48

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/libcore/iter/adapters/mod.rs

+53
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,29 @@ where
724724
}
725725
}
726726
}
727+
728+
#[inline]
729+
fn rfold<Acc, F>(mut self, init: Acc, mut f: F) -> Acc
730+
where
731+
Self: Sized,
732+
F: FnMut(Acc, Self::Item) -> Acc,
733+
{
734+
#[inline]
735+
fn nth_back<I: DoubleEndedIterator>(
736+
iter: &mut I,
737+
step: usize,
738+
) -> impl FnMut() -> Option<I::Item> + '_ {
739+
move || iter.nth_back(step)
740+
}
741+
742+
match self.next_back() {
743+
None => init,
744+
Some(x) => {
745+
let acc = f(init, x);
746+
from_fn(nth_back(&mut self.iter, self.step)).fold(acc, f)
747+
}
748+
}
749+
}
727750
}
728751

729752
// StepBy can only make the iterator shorter, so the len will still fit.
@@ -2056,6 +2079,18 @@ where
20562079
self.iter.try_rfold(init, check(n, fold)).into_try()
20572080
}
20582081
}
2082+
2083+
fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
2084+
where
2085+
Fold: FnMut(Acc, Self::Item) -> Acc,
2086+
{
2087+
#[inline]
2088+
fn ok<Acc, T>(mut f: impl FnMut(Acc, T) -> Acc) -> impl FnMut(Acc, T) -> Result<Acc, !> {
2089+
move |acc, x| Ok(f(acc, x))
2090+
}
2091+
2092+
self.try_rfold(init, ok(fold)).unwrap()
2093+
}
20592094
}
20602095

20612096
#[stable(feature = "fused", since = "1.26.0")]
@@ -2220,6 +2255,24 @@ where
22202255
}
22212256
}
22222257
}
2258+
2259+
#[inline]
2260+
fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
2261+
where
2262+
Self: Sized,
2263+
Fold: FnMut(Acc, Self::Item) -> Acc,
2264+
{
2265+
if self.n == 0 {
2266+
init
2267+
} else {
2268+
let len = self.iter.len();
2269+
if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
2270+
init
2271+
} else {
2272+
self.iter.rfold(init, fold)
2273+
}
2274+
}
2275+
}
22232276
}
22242277

22252278
#[stable(feature = "rust1", since = "1.0.0")]

src/libcore/iter/range.rs

+15
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
671671

672672
self.try_fold(init, ok(f)).unwrap()
673673
}
674+
674675
#[inline]
675676
fn last(mut self) -> Option<A> {
676677
self.next_back()
@@ -759,6 +760,20 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
759760

760761
Try::from_ok(accum)
761762
}
763+
764+
#[inline]
765+
fn rfold<B, F>(mut self, init: B, f: F) -> B
766+
where
767+
Self: Sized,
768+
F: FnMut(B, Self::Item) -> B,
769+
{
770+
#[inline]
771+
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
772+
move |acc, x| Ok(f(acc, x))
773+
}
774+
775+
self.try_rfold(init, ok(f)).unwrap()
776+
}
762777
}
763778

764779
#[unstable(feature = "trusted_len", issue = "37572")]

0 commit comments

Comments
 (0)