diff options
| -rw-r--r-- | src/libcore/benches/iter.rs | 6 | ||||
| -rw-r--r-- | src/libcore/iter/mod.rs | 13 | ||||
| -rw-r--r-- | src/libcore/tests/iter.rs | 2 |
3 files changed, 21 insertions, 0 deletions
diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs index 6c597301ac2..b0aca658343 100644 --- a/src/libcore/benches/iter.rs +++ b/src/libcore/benches/iter.rs @@ -282,6 +282,12 @@ bench_sums! { (0i64..1000000).chain(1000000..).take_while(|&x| x < 1111111) } +bench_sums! { + bench_cycle_take_sum, + bench_cycle_take_ref_sum, + (0i64..10000).cycle().take(1000000) +} + // Checks whether Skip<Zip<A,B>> is as fast as Zip<Skip<A>, Skip<B>>, from // https://users.rust-lang.org/t/performance-difference-between-iterator-zip-and-skip-order/15743 #[bench] diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index de7ab8843da..83d35324bc2 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -649,6 +649,19 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator { _ => (usize::MAX, None) } } + + #[inline] + fn try_fold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where + Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc> + { + let mut accum = init; + while let Some(x) = self.iter.next() { + accum = f(accum, x)?; + accum = self.iter.try_fold(accum, &mut f)?; + self.iter = self.orig.clone(); + } + Try::from_ok(accum) + } } #[stable(feature = "fused", since = "1.26.0")] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 19be1a07c5b..4efa0136314 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1001,6 +1001,8 @@ fn test_cycle() { let mut it = (0..).step_by(1).take(0).cycle(); assert_eq!(it.size_hint(), (0, Some(0))); assert_eq!(it.next(), None); + + assert_eq!(empty::<i32>().cycle().fold(0, |acc, x| acc + x), 0); } #[test] |
