diff --git a/src/iter/find.rs b/src/iter/find.rs index 86b1fc17c..6358d5280 100644 --- a/src/iter/find.rs +++ b/src/iter/find.rs @@ -87,10 +87,14 @@ where where I: IntoIterator, { + fn not_full(found: &AtomicBool) -> impl Fn(&T) -> bool + '_ { + move |_| !found.load(Ordering::Relaxed) + } + self.item = iter .into_iter() // stop iterating if another thread has found something - .take_while(|_| !self.full()) + .take_while(not_full(&self.found)) .find(self.find_op); if self.item.is_some() { self.found.store(true, Ordering::Relaxed) diff --git a/src/iter/flatten.rs b/src/iter/flatten.rs index 5862adc81..939ba1636 100644 --- a/src/iter/flatten.rs +++ b/src/iter/flatten.rs @@ -35,6 +35,10 @@ where where C: UnindexedConsumer, { - self.base.flat_map(|x| x).drive_unindexed(consumer) + fn id(x: T) -> T { + x + } + + self.base.flat_map(id).drive_unindexed(consumer) } } diff --git a/src/iter/fold.rs b/src/iter/fold.rs index 9ae937c9d..0de0aa3f0 100644 --- a/src/iter/fold.rs +++ b/src/iter/fold.rs @@ -147,11 +147,18 @@ where where I: IntoIterator, { + fn not_full(base: &C) -> impl Fn(&T) -> bool + '_ + where + C: Folder, + { + move |_| !base.full() + } + let base = self.base; let item = iter .into_iter() // stop iterating if another thread has finished - .take_while(|_| !base.full()) + .take_while(not_full(&base)) .fold(self.item, self.fold_op); FoldFolder { diff --git a/src/iter/for_each.rs b/src/iter/for_each.rs index 994140458..5307939ba 100644 --- a/src/iter/for_each.rs +++ b/src/iter/for_each.rs @@ -52,7 +52,7 @@ where where I: IntoIterator, { - iter.into_iter().fold((), |_, item| (self.op)(item)); + iter.into_iter().for_each(self.op); self } diff --git a/src/iter/from_par_iter.rs b/src/iter/from_par_iter.rs index 21860a4e0..5797df427 100644 --- a/src/iter/from_par_iter.rs +++ b/src/iter/from_par_iter.rs @@ -1,3 +1,4 @@ +use super::noop::NoopConsumer; use super::{FromParallelIterator, IntoParallelIterator, ParallelExtend, ParallelIterator}; use std::borrow::Cow; @@ -222,6 +223,6 @@ impl FromParallelIterator<()> for () { where I: IntoParallelIterator, { - par_iter.into_par_iter().for_each(|()| {}) + par_iter.into_par_iter().drive_unindexed(NoopConsumer) } } diff --git a/src/iter/interleave.rs b/src/iter/interleave.rs index 028f70b8d..34f301762 100644 --- a/src/iter/interleave.rs +++ b/src/iter/interleave.rs @@ -205,11 +205,14 @@ where /// should yield the next element, otherwise, if `j` should yield /// the next element, set a = index/2 and b = (index/2)+1 fn split_at(self, index: usize) -> (Self, Self) { + #[inline] + fn odd_offset(flag: bool) -> usize { + (!flag) as usize + } + let even = index % 2 == 0; let idx = index >> 1; - let odd_offset = |flag| if flag { 0 } else { 1 }; - // desired split let (i_idx, j_idx) = ( idx + odd_offset(even || self.i_next), diff --git a/src/iter/map_with.rs b/src/iter/map_with.rs index c5eafc728..22733b315 100644 --- a/src/iter/map_with.rs +++ b/src/iter/map_with.rs @@ -310,10 +310,15 @@ where where I: IntoIterator, { + fn with<'f, T, U, R>( + item: &'f mut U, + map_op: impl Fn(&mut U, T) -> R + 'f, + ) -> impl FnMut(T) -> R + 'f { + move |x| map_op(item, x) + } + { - let map_op = self.map_op; - let item = &mut self.item; - let mapped_iter = iter.into_iter().map(|x| map_op(item, x)); + let mapped_iter = iter.into_iter().map(with(&mut self.item, self.map_op)); self.base = self.base.consume_iter(mapped_iter); } self diff --git a/src/iter/mod.rs b/src/iter/mod.rs index 425618437..cf25b232c 100644 --- a/src/iter/mod.rs +++ b/src/iter/mod.rs @@ -377,7 +377,7 @@ pub trait ParallelIterator: Sized + Send { OP: Fn(&mut T, Self::Item) + Sync + Send, T: Send + Clone, { - self.map_with(init, op).for_each(|()| ()) + self.map_with(init, op).collect() } /// Executes `OP` on a value returned by `init` with each item produced by @@ -414,7 +414,7 @@ pub trait ParallelIterator: Sized + Send { OP: Fn(&mut T, Self::Item) + Sync + Send, INIT: Fn() -> T + Sync + Send, { - self.map_init(init, op).for_each(|()| ()) + self.map_init(init, op).collect() } /// Executes a fallible `OP` on each item produced by the iterator, in parallel. @@ -442,7 +442,11 @@ pub trait ParallelIterator: Sized + Send { OP: Fn(Self::Item) -> R + Sync + Send, R: Try + Send, { - self.map(op).try_reduce(|| (), |(), ()| R::from_ok(())) + fn ok>(_: (), _: ()) -> R { + R::from_ok(()) + } + + self.map(op).try_reduce(<()>::default, ok) } /// Executes a fallible `OP` on the given `init` value with each item @@ -478,8 +482,11 @@ pub trait ParallelIterator: Sized + Send { T: Send + Clone, R: Try + Send, { - self.map_with(init, op) - .try_reduce(|| (), |(), ()| R::from_ok(())) + fn ok>(_: (), _: ()) -> R { + R::from_ok(()) + } + + self.map_with(init, op).try_reduce(<()>::default, ok) } /// Executes a fallible `OP` on a value returned by `init` with each item @@ -520,8 +527,11 @@ pub trait ParallelIterator: Sized + Send { INIT: Fn() -> T + Sync + Send, R: Try + Send, { - self.map_init(init, op) - .try_reduce(|| (), |(), ()| R::from_ok(())) + fn ok>(_: (), _: ()) -> R { + R::from_ok(()) + } + + self.map_init(init, op).try_reduce(<()>::default, ok) } /// Counts the number of items in this parallel iterator. @@ -536,7 +546,11 @@ pub trait ParallelIterator: Sized + Send { /// assert_eq!(count, 100); /// ``` fn count(self) -> usize { - self.map(|_| 1).sum() + fn one(_: T) -> usize { + 1 + } + + self.map(one).sum() } /// Applies `map_op` to each item of this iterator, producing a new @@ -879,21 +893,23 @@ pub trait ParallelIterator: Sized + Send { where OP: Fn(Self::Item, Self::Item) -> Self::Item + Sync + Send, { - self.fold( - || None, - |opt_a, b| match opt_a { + fn opt_fold(op: impl Fn(T, T) -> T) -> impl Fn(Option, T) -> Option { + move |opt_a, b| match opt_a { Some(a) => Some(op(a, b)), None => Some(b), - }, - ) - .reduce( - || None, - |opt_a, opt_b| match (opt_a, opt_b) { + } + } + + fn opt_reduce(op: impl Fn(T, T) -> T) -> impl Fn(Option, Option) -> Option { + move |opt_a, opt_b| match (opt_a, opt_b) { (Some(a), Some(b)) => Some(op(a, b)), (Some(v), None) | (None, Some(v)) => Some(v), (None, None) => None, - }, - ) + } + } + + self.fold(<_>::default, opt_fold(&op)) + .reduce(<_>::default, opt_reduce(&op)) } /// Reduces the items in the iterator into one item using a fallible `op`. @@ -1324,10 +1340,14 @@ pub trait ParallelIterator: Sized + Send { where F: Sync + Send + Fn(&Self::Item, &Self::Item) -> Ordering, { - self.reduce_with(|a, b| match f(&a, &b) { - Ordering::Greater => b, - _ => a, - }) + fn min(f: impl Fn(&T, &T) -> Ordering) -> impl Fn(T, T) -> T { + move |a, b| match f(&a, &b) { + Ordering::Greater => b, + _ => a, + } + } + + self.reduce_with(min(f)) } /// Computes the item that yields the minimum value for the given @@ -1352,7 +1372,18 @@ pub trait ParallelIterator: Sized + Send { K: Ord + Send, F: Sync + Send + Fn(&Self::Item) -> K, { - let (_, x) = self.map(|x| (f(&x), x)).min_by(|a, b| (a.0).cmp(&b.0))?; + fn key(f: impl Fn(&T) -> K) -> impl Fn(T) -> (K, T) { + move |x| (f(&x), x) + } + + fn min_key(a: (K, T), b: (K, T)) -> (K, T) { + match (a.0).cmp(&b.0) { + Ordering::Greater => b, + _ => a, + } + } + + let (_, x) = self.map(key(f)).reduce_with(min_key)?; Some(x) } @@ -1407,10 +1438,14 @@ pub trait ParallelIterator: Sized + Send { where F: Sync + Send + Fn(&Self::Item, &Self::Item) -> Ordering, { - self.reduce_with(|a, b| match f(&a, &b) { - Ordering::Greater => a, - _ => b, - }) + fn max(f: impl Fn(&T, &T) -> Ordering) -> impl Fn(T, T) -> T { + move |a, b| match f(&a, &b) { + Ordering::Greater => a, + _ => b, + } + } + + self.reduce_with(max(f)) } /// Computes the item that yields the maximum value for the given @@ -1435,7 +1470,18 @@ pub trait ParallelIterator: Sized + Send { K: Ord + Send, F: Sync + Send + Fn(&Self::Item) -> K, { - let (_, x) = self.map(|x| (f(&x), x)).max_by(|a, b| (a.0).cmp(&b.0))?; + fn key(f: impl Fn(&T) -> K) -> impl Fn(T) -> (K, T) { + move |x| (f(&x), x) + } + + fn max_key(a: (K, T), b: (K, T)) -> (K, T) { + match (a.0).cmp(&b.0) { + Ordering::Greater => a, + _ => b, + } + } + + let (_, x) = self.map(key(f)).reduce_with(max_key)?; Some(x) } @@ -1579,7 +1625,10 @@ pub trait ParallelIterator: Sized + Send { P: Fn(Self::Item) -> Option + Sync + Send, R: Send, { - self.filter_map(predicate).find_any(|_| true) + fn yes(_: &T) -> bool { + true + } + self.filter_map(predicate).find_any(yes) } /// Applies the given predicate to the items in the parallel iterator and @@ -1610,7 +1659,10 @@ pub trait ParallelIterator: Sized + Send { P: Fn(Self::Item) -> Option + Sync + Send, R: Send, { - self.filter_map(predicate).find_first(|_| true) + fn yes(_: &T) -> bool { + true + } + self.filter_map(predicate).find_first(yes) } /// Applies the given predicate to the items in the parallel iterator and @@ -1641,7 +1693,10 @@ pub trait ParallelIterator: Sized + Send { P: Fn(Self::Item) -> Option + Sync + Send, R: Send, { - self.filter_map(predicate).find_last(|_| true) + fn yes(_: &T) -> bool { + true + } + self.filter_map(predicate).find_last(yes) } #[doc(hidden)] @@ -1675,7 +1730,7 @@ pub trait ParallelIterator: Sized + Send { where P: Fn(Self::Item) -> bool + Sync + Send, { - self.map(predicate).find_any(|&p| p).is_some() + self.map(predicate).find_any(bool::clone).is_some() } /// Tests that every item in the parallel iterator matches the given @@ -1697,7 +1752,12 @@ pub trait ParallelIterator: Sized + Send { where P: Fn(Self::Item) -> bool + Sync + Send, { - self.map(predicate).find_any(|&p| !p).is_none() + #[inline] + fn is_false(x: &bool) -> bool { + !x + } + + self.map(predicate).find_any(is_false).is_none() } /// Creates an iterator over the `Some` items of this iterator, halting @@ -2179,11 +2239,21 @@ pub trait IndexedParallelIterator: ParallelIterator { I::Iter: IndexedParallelIterator, Self::Item: Ord, { + #[inline] + fn ordering((x, y): (T, T)) -> Ordering { + Ord::cmp(&x, &y) + } + + #[inline] + fn inequal(&ord: &Ordering) -> bool { + ord != Ordering::Equal + } + let other = other.into_par_iter(); let ord_len = self.len().cmp(&other.len()); self.zip(other) - .map(|(x, y)| Ord::cmp(&x, &y)) - .find_first(|&ord| ord != Ordering::Equal) + .map(ordering) + .find_first(inequal) .unwrap_or(ord_len) } @@ -2209,12 +2279,22 @@ pub trait IndexedParallelIterator: ParallelIterator { I::Iter: IndexedParallelIterator, Self::Item: PartialOrd, { + #[inline] + fn ordering, U>((x, y): (T, U)) -> Option { + PartialOrd::partial_cmp(&x, &y) + } + + #[inline] + fn inequal(&ord: &Option) -> bool { + ord != Some(Ordering::Equal) + } + let other = other.into_par_iter(); - let ord_len = Some(self.len().cmp(&other.len())); + let ord_len = self.len().cmp(&other.len()); self.zip(other) - .map(|(x, y)| PartialOrd::partial_cmp(&x, &y)) - .find_first(|&ord| ord != Some(Ordering::Equal)) - .unwrap_or(ord_len) + .map(ordering) + .find_first(inequal) + .unwrap_or(Some(ord_len)) } /// Determines if the elements of this `ParallelIterator` @@ -2225,8 +2305,13 @@ pub trait IndexedParallelIterator: ParallelIterator { I::Iter: IndexedParallelIterator, Self::Item: PartialEq, { + #[inline] + fn eq, U>((x, y): (T, U)) -> bool { + PartialEq::eq(&x, &y) + } + let other = other.into_par_iter(); - self.len() == other.len() && self.zip(other).all(|(x, y)| x.eq(&y)) + self.len() == other.len() && self.zip(other).all(eq) } /// Determines if the elements of this `ParallelIterator` @@ -2363,7 +2448,12 @@ pub trait IndexedParallelIterator: ParallelIterator { where P: Fn(Self::Item) -> bool + Sync + Send, { - let (i, _) = self.map(predicate).enumerate().find_any(|&(_, p)| p)?; + #[inline] + fn check(&(_, p): &(usize, bool)) -> bool { + p + } + + let (i, _) = self.map(predicate).enumerate().find_any(check)?; Some(i) } @@ -2395,7 +2485,12 @@ pub trait IndexedParallelIterator: ParallelIterator { where P: Fn(Self::Item) -> bool + Sync + Send, { - let (i, _) = self.map(predicate).enumerate().find_first(|&(_, p)| p)?; + #[inline] + fn check(&(_, p): &(usize, bool)) -> bool { + p + } + + let (i, _) = self.map(predicate).enumerate().find_first(check)?; Some(i) } @@ -2427,7 +2522,12 @@ pub trait IndexedParallelIterator: ParallelIterator { where P: Fn(Self::Item) -> bool + Sync + Send, { - let (i, _) = self.map(predicate).enumerate().find_last(|&(_, p)| p)?; + #[inline] + fn check(&(_, p): &(usize, bool)) -> bool { + p + } + + let (i, _) = self.map(predicate).enumerate().find_last(check)?; Some(i) } diff --git a/src/iter/noop.rs b/src/iter/noop.rs index 31d7528ed..1e55ecb20 100644 --- a/src/iter/noop.rs +++ b/src/iter/noop.rs @@ -2,12 +2,6 @@ use super::plumbing::*; pub(super) struct NoopConsumer; -impl NoopConsumer { - pub(super) fn new() -> Self { - NoopConsumer - } -} - impl Consumer for NoopConsumer { type Folder = NoopConsumer; type Reducer = NoopReducer; @@ -37,7 +31,7 @@ impl Folder for NoopConsumer { where I: IntoIterator, { - iter.into_iter().fold((), |_, _| ()); + iter.into_iter().for_each(drop); self } diff --git a/src/iter/panic_fuse.rs b/src/iter/panic_fuse.rs index d0cbbd4c1..b0d1ac0eb 100644 --- a/src/iter/panic_fuse.rs +++ b/src/iter/panic_fuse.rs @@ -306,9 +306,13 @@ where where I: IntoIterator, { + fn cool<'a, T>(fuse: &'a Fuse) -> impl Fn(&T) -> bool + 'a { + move |_| !fuse.panicked() + } + self.base = { let fuse = &self.fuse; - let iter = iter.into_iter().take_while(move |_| !fuse.panicked()); + let iter = iter.into_iter().take_while(cool(fuse)); self.base.consume_iter(iter) }; self diff --git a/src/iter/skip.rs b/src/iter/skip.rs index 73653f24e..903934c74 100644 --- a/src/iter/skip.rs +++ b/src/iter/skip.rs @@ -80,7 +80,7 @@ where P: Producer, { let (before_skip, after_skip) = base.split_at(self.n); - bridge_producer_consumer(self.n, before_skip, NoopConsumer::new()); + bridge_producer_consumer(self.n, before_skip, NoopConsumer); self.callback.callback(after_skip) } } diff --git a/src/iter/try_fold.rs b/src/iter/try_fold.rs index 13165c9ec..51f988179 100644 --- a/src/iter/try_fold.rs +++ b/src/iter/try_fold.rs @@ -141,10 +141,12 @@ where { type Result = C::Result; - fn consume(self, item: T) -> Self { + fn consume(mut self, item: T) -> Self { let fold_op = self.fold_op; - let result = self.result.and_then(|acc| fold_op(acc, item).into_result()); - TryFoldFolder { result, ..self } + if let Ok(acc) = self.result { + self.result = fold_op(acc, item).into_result(); + } + self } fn complete(self) -> C::Result { diff --git a/src/iter/try_reduce.rs b/src/iter/try_reduce.rs index 926746456..6c9f24181 100644 --- a/src/iter/try_reduce.rs +++ b/src/iter/try_reduce.rs @@ -102,15 +102,18 @@ where { type Result = T; - fn consume(self, item: T) -> Self { + fn consume(mut self, item: T) -> Self { let reduce_op = self.reduce_op; - let result = self - .result - .and_then(|left| reduce_op(left, item.into_result()?).into_result()); - if result.is_err() { + if let Ok(left) = self.result { + self.result = match item.into_result() { + Ok(right) => reduce_op(left, right).into_result(), + Err(error) => Err(error), + }; + } + if self.result.is_err() { self.full.store(true, Ordering::Relaxed) } - TryReduceFolder { result, ..self } + self } fn complete(self) -> T { diff --git a/src/iter/update.rs b/src/iter/update.rs index 7bed5d9a4..e822f4878 100644 --- a/src/iter/update.rs +++ b/src/iter/update.rs @@ -223,6 +223,13 @@ struct UpdateFolder<'f, C, F: 'f> { update_op: &'f F, } +fn apply(update_op: impl Fn(&mut T)) -> impl Fn(T) -> T { + move |mut item| { + update_op(&mut item); + item + } +} + impl<'f, T, C, F> Folder for UpdateFolder<'f, C, F> where C: Folder, @@ -244,10 +251,9 @@ where I: IntoIterator, { let update_op = self.update_op; - self.base = self.base.consume_iter(iter.into_iter().map(|mut item| { - update_op(&mut item); - item - })); + self.base = self + .base + .consume_iter(iter.into_iter().map(apply(update_op))); self } @@ -271,7 +277,7 @@ struct UpdateSeq { impl Iterator for UpdateSeq where I: Iterator, - F: FnMut(&mut I::Item), + F: Fn(&mut I::Item), { type Item = I::Item; @@ -285,15 +291,11 @@ where self.base.size_hint() } - fn fold(self, init: Acc, mut g: G) -> Acc + fn fold(self, init: Acc, g: G) -> Acc where G: FnMut(Acc, Self::Item) -> Acc, { - let mut f = self.update_op; - self.base.fold(init, move |acc, mut v| { - f(&mut v); - g(acc, v) - }) + self.base.map(apply(self.update_op)).fold(init, g) } // if possible, re-use inner iterator specializations in collect @@ -301,27 +303,21 @@ where where C: ::std::iter::FromIterator, { - let mut f = self.update_op; - self.base - .map(move |mut v| { - f(&mut v); - v - }) - .collect() + self.base.map(apply(self.update_op)).collect() } } impl ExactSizeIterator for UpdateSeq where I: ExactSizeIterator, - F: FnMut(&mut I::Item), + F: Fn(&mut I::Item), { } impl DoubleEndedIterator for UpdateSeq where I: DoubleEndedIterator, - F: FnMut(&mut I::Item), + F: Fn(&mut I::Item), { fn next_back(&mut self) -> Option { let mut v = self.base.next_back()?; diff --git a/src/option.rs b/src/option.rs index 0c021d93f..925107f82 100644 --- a/src/option.rs +++ b/src/option.rs @@ -180,14 +180,18 @@ where where I: IntoParallelIterator>, { - let found_none = AtomicBool::new(false); - let collection = par_iter - .into_par_iter() - .inspect(|item| { + fn check(found_none: &AtomicBool) -> impl Fn(&Option) + '_ { + move |item| { if item.is_none() { found_none.store(true, Ordering::Relaxed); } - }) + } + } + + let found_none = AtomicBool::new(false); + let collection = par_iter + .into_par_iter() + .inspect(check(&found_none)) .while_some() .collect(); diff --git a/src/range.rs b/src/range.rs index bd4c7dcec..1a0f2c5d3 100644 --- a/src/range.rs +++ b/src/range.rs @@ -156,11 +156,16 @@ macro_rules! unindexed_range_impl { where C: UnindexedConsumer, { + #[inline] + fn offset(start: $t) -> impl Fn(usize) -> $t { + move |i| start.wrapping_add(i as $t) + } + if let Some(len) = self.opt_len() { // Drive this in indexed mode for better `collect`. (0..len) .into_par_iter() - .map(|i| self.range.start.wrapping_add(i as $t)) + .map(offset(self.range.start)) .drive(consumer) } else { bridge_unindexed(IterProducer { range: self.range }, consumer) diff --git a/src/slice/mod.rs b/src/slice/mod.rs index d78786996..72f50f713 100644 --- a/src/slice/mod.rs +++ b/src/slice/mod.rs @@ -186,7 +186,7 @@ pub trait ParallelSliceMut { where T: Ord, { - par_mergesort(self.as_parallel_slice_mut(), |a, b| a.lt(b)); + par_mergesort(self.as_parallel_slice_mut(), T::lt); } /// Sorts the slice in parallel with a comparator function. @@ -310,7 +310,7 @@ pub trait ParallelSliceMut { where T: Ord, { - par_quicksort(self.as_parallel_slice_mut(), |a, b| a.lt(b)); + par_quicksort(self.as_parallel_slice_mut(), T::lt); } /// Sorts the slice in parallel with a comparator function, but may not preserve the order of diff --git a/src/split_producer.rs b/src/split_producer.rs index 36d1b70f2..99c2a89c5 100644 --- a/src/split_producer.rs +++ b/src/split_producer.rs @@ -84,11 +84,10 @@ where fn split(self) -> (Self, Option) { // Look forward for the separator, and failing that look backward. let mid = self.data.midpoint(self.tail); - let index = self - .data - .find(self.separator, mid, self.tail) - .map(|i| mid + i) - .or_else(|| self.data.rfind(self.separator, mid)); + let index = match self.data.find(self.separator, mid, self.tail) { + Some(i) => Some(mid + i), + None => self.data.rfind(self.separator, mid), + }; if let Some(index) = index { let len = self.data.length(); diff --git a/src/str.rs b/src/str.rs index a60555dce..3b4573cf0 100644 --- a/src/str.rs +++ b/src/str.rs @@ -298,6 +298,11 @@ mod private { } use self::private::Pattern; +#[inline] +fn offset(base: usize) -> impl Fn((usize, T)) -> (usize, T) { + move |(i, x)| (base + i, x) +} + impl Pattern for char { private_impl! {} @@ -338,7 +343,7 @@ impl Pattern for char { where F: Folder<(usize, &'ch str)>, { - folder.consume_iter(chars.match_indices(*self).map(move |(i, s)| (base + i, s))) + folder.consume_iter(chars.match_indices(*self).map(offset(base))) } } @@ -379,7 +384,7 @@ impl bool> Pattern for FN { where F: Folder<(usize, &'ch str)>, { - folder.consume_iter(chars.match_indices(self).map(move |(i, s)| (base + i, s))) + folder.consume_iter(chars.match_indices(self).map(offset(base))) } } @@ -479,7 +484,7 @@ impl<'ch> UnindexedProducer for CharIndicesProducer<'ch> { F: Folder, { let base = self.index; - folder.consume_iter(self.chars.char_indices().map(move |(i, c)| (base + i, c))) + folder.consume_iter(self.chars.char_indices().map(offset(base))) } } @@ -704,6 +709,15 @@ impl<'ch, 'sep, P: Pattern + 'sep> UnindexedProducer for SplitTerminatorProducer #[derive(Debug, Clone)] pub struct Lines<'ch>(&'ch str); +#[inline] +fn no_carriage_return(line: &str) -> &str { + if line.ends_with('\r') { + &line[..line.len() - 1] + } else { + line + } +} + impl<'ch> ParallelIterator for Lines<'ch> { type Item = &'ch str; @@ -713,13 +727,7 @@ impl<'ch> ParallelIterator for Lines<'ch> { { self.0 .par_split_terminator('\n') - .map(|line| { - if line.ends_with('\r') { - &line[..line.len() - 1] - } else { - line - } - }) + .map(no_carriage_return) .drive_unindexed(consumer) } } @@ -730,6 +738,11 @@ impl<'ch> ParallelIterator for Lines<'ch> { #[derive(Debug, Clone)] pub struct SplitWhitespace<'ch>(&'ch str); +#[inline] +fn not_empty(s: &&str) -> bool { + !s.is_empty() +} + impl<'ch> ParallelIterator for SplitWhitespace<'ch> { type Item = &'ch str; @@ -739,7 +752,7 @@ impl<'ch> ParallelIterator for SplitWhitespace<'ch> { { self.0 .par_split(char::is_whitespace) - .filter(|string| !string.is_empty()) + .filter(not_empty) .drive_unindexed(consumer) } }