From aa2fee237c42efe197d287138ac34b487b210628 Mon Sep 17 00:00:00 2001 From: Owen Leung Date: Tue, 10 Oct 2023 21:40:15 +0800 Subject: [PATCH 1/3] Implement custom fold for while some Implement custom fold for while some --- benches/bench1.rs | 19 +++++++++++++++++++ src/adaptors/mod.rs | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/benches/bench1.rs b/benches/bench1.rs index fbcaa05a7..46d7953e4 100644 --- a/benches/bench1.rs +++ b/benches/bench1.rs @@ -448,6 +448,24 @@ fn group_by_lazy_2(c: &mut Criterion) { }); } +fn while_some(c: &mut Criterion) { + c.bench_function("while_some", |b| { + b.iter(|| { + let data = black_box( + (0..) + .fuse() + .map(|i| std::char::from_digit(i, 16)) + .while_some(), + ); + let result: String = data.fold(String::new(), |acc, ch| acc + &ch.to_string()); + assert_eq!( + result.chars().collect::>(), + "0123456789abcdef".chars().collect::>() + ); + }); + }); +} + fn slice_chunks(c: &mut Criterion) { let data = vec![0; 1024]; @@ -884,5 +902,6 @@ criterion_group!( permutations_range, permutations_slice, with_position_fold, + while_some, ); criterion_main!(benches); diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs index 90cf46eed..6ee2adc5f 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -581,6 +581,17 @@ where fn size_hint(&self) -> (usize, Option) { (0, self.iter.size_hint().1) } + + fn fold(self, acc: B, f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + self.iter + .take_while(|opt| opt.is_some()) + .map(|item| item.unwrap()) + .fold(acc, f) + } } /// An iterator to iterate through all combinations in a `Clone`-able iterator that produces tuples From 147915b8d6151513db7790dd8eca955151d5ba8d Mon Sep 17 00:00:00 2001 From: Owen Leung Date: Wed, 11 Oct 2023 22:13:26 +0800 Subject: [PATCH 2/3] Revise benchmark & use try_fold for fold --- benches/bench1.rs | 11 ++++++----- src/adaptors/mod.rs | 12 +++++++----- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/benches/bench1.rs b/benches/bench1.rs index 46d7953e4..664191ab4 100644 --- a/benches/bench1.rs +++ b/benches/bench1.rs @@ -457,11 +457,12 @@ fn while_some(c: &mut Criterion) { .map(|i| std::char::from_digit(i, 16)) .while_some(), ); - let result: String = data.fold(String::new(), |acc, ch| acc + &ch.to_string()); - assert_eq!( - result.chars().collect::>(), - "0123456789abcdef".chars().collect::>() - ); + // let result: String = data.fold(String::new(), |acc, ch| acc + &ch.to_string()); + let result = data.fold(String::new(), |mut acc, ch| { + acc.push(ch); + acc + }); + assert_eq!(result.as_str(), "0123456789abcdef"); }); }); } diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs index 6ee2adc5f..c5a0bfccb 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -582,15 +582,17 @@ where (0, self.iter.size_hint().1) } - fn fold(self, acc: B, f: F) -> B + fn fold(mut self, acc: B, mut f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { - self.iter - .take_while(|opt| opt.is_some()) - .map(|item| item.unwrap()) - .fold(acc, f) + let res = self.iter.try_fold(acc, |acc, item| match item { + Some(item) => Ok(f(acc, item)), + None => Err(acc), + }); + let (Err(res) | Ok(res)) = res; + res } } From 2a592401266a9be227461fac244947e26a7f661b Mon Sep 17 00:00:00 2001 From: Owen Leung Date: Wed, 11 Oct 2023 22:27:34 +0800 Subject: [PATCH 3/3] fix failing msrv test --- src/adaptors/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs index c5a0bfccb..18c864ad1 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -591,7 +591,10 @@ where Some(item) => Ok(f(acc, item)), None => Err(acc), }); - let (Err(res) | Ok(res)) = res; + let res = match res { + Ok(val) => val, + Err(val) => val, + }; res } }