diff --git a/benches/bench1.rs b/benches/bench1.rs index f718ce2c9..f5d71a641 100644 --- a/benches/bench1.rs +++ b/benches/bench1.rs @@ -792,6 +792,21 @@ fn permutations_slice(c: &mut Criterion) { }); } +fn take_while_ref(c: &mut Criterion) { + c.bench_function("take_while_ref", |b| { + b.iter(|| { + let mut data = black_box("0123456789abcdef".chars()); + let result = + data.take_while_ref(|c| c.is_numeric()) + .fold(String::new(), |mut acc, ch| { + acc.push(ch); + acc + }); + assert_eq!(result.as_str(), "0123456789"); + }); + }); +} + criterion_group!( benches, slice_iter, @@ -837,5 +852,6 @@ criterion_group!( permutations_iter, permutations_range, permutations_slice, + take_while_ref ); criterion_main!(benches); diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs index 57b604908..a8c0acc03 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -13,6 +13,8 @@ pub use self::map::{map_into, map_ok, MapInto, MapOk}; pub use self::multi_product::*; use crate::size_hint::{self, SizeHint}; +use crate::FoldWhile::{Continue, Done}; +use crate::Itertools; use std::fmt; use std::iter::{Enumerate, FromIterator, Fuse, FusedIterator}; use std::marker::PhantomData; @@ -555,6 +557,30 @@ where fn size_hint(&self) -> (usize, Option) { (0, self.iter.size_hint().1) } + + fn fold(mut self, init: B, mut g: G) -> B + where + G: FnMut(B, I::Item) -> B, + { + let acc = init; + let original_iter = self.iter.clone(); + + let result = self.iter.clone().fold_while(acc, |acc, x| { + if (self.f)(&x) { + Continue(g(acc, x)) + } else { + Done(acc) + } + }); + + match result { + Done(acc) => { + *self.iter = original_iter; + acc + } + Continue(acc) => acc, + } + } } /// An iterator adaptor that filters `Option` iterator elements