Skip to content

Commit 688c112

Browse files
committed
Override Cycle::try_fold
1 parent d36b7f6 commit 688c112

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

src/libcore/iter/adapters/mod.rs

+30
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,36 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator {
387387
_ => (usize::MAX, None)
388388
}
389389
}
390+
391+
#[inline]
392+
fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
393+
where
394+
F: FnMut(Acc, Self::Item) -> R,
395+
R: Try<Ok = Acc>,
396+
{
397+
// fully iterate the current iterator. this is necessary because
398+
// `self.iter` may be empty even when `self.orig` isn't
399+
acc = self.iter.try_fold(acc, &mut f)?;
400+
self.iter = self.orig.clone();
401+
402+
// complete a full cycle, keeping track of whether the cycled
403+
// iterator is empty or not. we need to return early in case
404+
// of an empty iterator to prevent an infinite loop
405+
let mut is_empty = true;
406+
acc = self.iter.try_fold(acc, |acc, x| {
407+
is_empty = false;
408+
f(acc, x)
409+
})?;
410+
411+
if is_empty {
412+
return Try::from_ok(acc);
413+
}
414+
415+
loop {
416+
self.iter = self.orig.clone();
417+
acc = self.iter.try_fold(acc, &mut f)?;
418+
}
419+
}
390420
}
391421

392422
#[stable(feature = "fused", since = "1.26.0")]

src/libcore/tests/iter.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,18 @@ fn test_cycle() {
10151015
assert_eq!(empty::<i32>().cycle().fold(0, |acc, x| acc + x), 0);
10161016

10171017
assert_eq!(once(1).cycle().skip(1).take(4).fold(0, |acc, x| acc + x), 4);
1018+
1019+
assert_eq!((0..10).cycle().take(5).sum::<i32>(), 10);
1020+
assert_eq!((0..10).cycle().take(15).sum::<i32>(), 55);
1021+
assert_eq!((0..10).cycle().take(25).sum::<i32>(), 100);
1022+
1023+
let mut iter = (0..10).cycle();
1024+
iter.nth(14);
1025+
assert_eq!(iter.take(8).sum::<i32>(), 38);
1026+
1027+
let mut iter = (0..10).cycle();
1028+
iter.nth(9);
1029+
assert_eq!(iter.take(3).sum::<i32>(), 3);
10181030
}
10191031

10201032
#[test]

0 commit comments

Comments
 (0)