summaryrefslogtreecommitdiffstats
path: root/vendor/rayon/src/iter
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:25 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:25 +0000
commit5363f350887b1e5b5dd21a86f88c8af9d7fea6da (patch)
tree35ca005eb6e0e9a1ba3bb5dbc033209ad445dc17 /vendor/rayon/src/iter
parentAdding debian version 1.66.0+dfsg1-1. (diff)
downloadrustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.tar.xz
rustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/rayon/src/iter')
-rw-r--r--vendor/rayon/src/iter/chunks.rs50
-rw-r--r--vendor/rayon/src/iter/filter.rs2
-rw-r--r--vendor/rayon/src/iter/filter_map.rs2
-rw-r--r--vendor/rayon/src/iter/find.rs2
-rw-r--r--vendor/rayon/src/iter/fold_chunks.rs236
-rw-r--r--vendor/rayon/src/iter/fold_chunks_with.rs231
-rw-r--r--vendor/rayon/src/iter/inspect.rs2
-rw-r--r--vendor/rayon/src/iter/interleave.rs18
-rw-r--r--vendor/rayon/src/iter/map.rs2
-rw-r--r--vendor/rayon/src/iter/mod.rs123
-rw-r--r--vendor/rayon/src/iter/plumbing/README.md2
-rw-r--r--vendor/rayon/src/iter/step_by.rs1
-rw-r--r--vendor/rayon/src/iter/test.rs21
-rw-r--r--vendor/rayon/src/iter/try_fold.rs3
-rw-r--r--vendor/rayon/src/iter/try_reduce.rs3
-rw-r--r--vendor/rayon/src/iter/try_reduce_with.rs3
-rw-r--r--vendor/rayon/src/iter/update.rs2
17 files changed, 624 insertions, 79 deletions
diff --git a/vendor/rayon/src/iter/chunks.rs b/vendor/rayon/src/iter/chunks.rs
index be5f84cc7..ec48278d0 100644
--- a/vendor/rayon/src/iter/chunks.rs
+++ b/vendor/rayon/src/iter/chunks.rs
@@ -90,38 +90,46 @@ where
where
P: Producer<Item = T>,
{
- self.callback.callback(ChunkProducer {
- chunk_size: self.size,
- len: self.len,
- base,
- })
+ let producer = ChunkProducer::new(self.size, self.len, base, Vec::from_iter);
+ self.callback.callback(producer)
}
}
}
}
-struct ChunkProducer<P>
-where
- P: Producer,
-{
+pub(super) struct ChunkProducer<P, F> {
chunk_size: usize,
len: usize,
base: P,
+ map: F,
}
-impl<P> Producer for ChunkProducer<P>
+impl<P, F> ChunkProducer<P, F> {
+ pub(super) fn new(chunk_size: usize, len: usize, base: P, map: F) -> Self {
+ Self {
+ chunk_size,
+ len,
+ base,
+ map,
+ }
+ }
+}
+
+impl<P, F, T> Producer for ChunkProducer<P, F>
where
P: Producer,
+ F: Fn(P::IntoIter) -> T + Send + Clone,
{
- type Item = Vec<P::Item>;
- type IntoIter = ChunkSeq<P>;
+ type Item = T;
+ type IntoIter = std::iter::Map<ChunkSeq<P>, F>;
fn into_iter(self) -> Self::IntoIter {
- ChunkSeq {
+ let chunks = ChunkSeq {
chunk_size: self.chunk_size,
len: self.len,
inner: if self.len > 0 { Some(self.base) } else { None },
- }
+ };
+ chunks.map(self.map)
}
fn split_at(self, index: usize) -> (Self, Self) {
@@ -132,11 +140,13 @@ where
chunk_size: self.chunk_size,
len: elem_index,
base: left,
+ map: self.map.clone(),
},
ChunkProducer {
chunk_size: self.chunk_size,
len: self.len - elem_index,
base: right,
+ map: self.map,
},
)
}
@@ -150,7 +160,7 @@ where
}
}
-struct ChunkSeq<P> {
+pub(super) struct ChunkSeq<P> {
chunk_size: usize,
len: usize,
inner: Option<P>,
@@ -160,7 +170,7 @@ impl<P> Iterator for ChunkSeq<P>
where
P: Producer,
{
- type Item = Vec<P::Item>;
+ type Item = P::IntoIter;
fn next(&mut self) -> Option<Self::Item> {
let producer = self.inner.take()?;
@@ -168,11 +178,11 @@ where
let (left, right) = producer.split_at(self.chunk_size);
self.inner = Some(right);
self.len -= self.chunk_size;
- Some(left.into_iter().collect())
+ Some(left.into_iter())
} else {
debug_assert!(self.len > 0);
self.len = 0;
- Some(producer.into_iter().collect())
+ Some(producer.into_iter())
}
}
@@ -206,11 +216,11 @@ where
let (left, right) = producer.split_at(self.len - size);
self.inner = Some(left);
self.len -= size;
- Some(right.into_iter().collect())
+ Some(right.into_iter())
} else {
debug_assert!(self.len > 0);
self.len = 0;
- Some(producer.into_iter().collect())
+ Some(producer.into_iter())
}
}
}
diff --git a/vendor/rayon/src/iter/filter.rs b/vendor/rayon/src/iter/filter.rs
index 38627f7c0..e1b74ba52 100644
--- a/vendor/rayon/src/iter/filter.rs
+++ b/vendor/rayon/src/iter/filter.rs
@@ -97,7 +97,7 @@ where
P: Fn(&T) -> bool + Sync,
{
fn split_off_left(&self) -> Self {
- FilterConsumer::new(self.base.split_off_left(), &self.filter_op)
+ FilterConsumer::new(self.base.split_off_left(), self.filter_op)
}
fn to_reducer(&self) -> Self::Reducer {
diff --git a/vendor/rayon/src/iter/filter_map.rs b/vendor/rayon/src/iter/filter_map.rs
index f19c38563..db1c7e3f0 100644
--- a/vendor/rayon/src/iter/filter_map.rs
+++ b/vendor/rayon/src/iter/filter_map.rs
@@ -98,7 +98,7 @@ where
P: Fn(T) -> Option<U> + Sync + 'p,
{
fn split_off_left(&self) -> Self {
- FilterMapConsumer::new(self.base.split_off_left(), &self.filter_op)
+ FilterMapConsumer::new(self.base.split_off_left(), self.filter_op)
}
fn to_reducer(&self) -> Self::Reducer {
diff --git a/vendor/rayon/src/iter/find.rs b/vendor/rayon/src/iter/find.rs
index 971db2b3c..b16ee8446 100644
--- a/vendor/rayon/src/iter/find.rs
+++ b/vendor/rayon/src/iter/find.rs
@@ -94,7 +94,7 @@ where
self.item = iter
.into_iter()
// stop iterating if another thread has found something
- .take_while(not_full(&self.found))
+ .take_while(not_full(self.found))
.find(self.find_op);
if self.item.is_some() {
self.found.store(true, Ordering::Relaxed)
diff --git a/vendor/rayon/src/iter/fold_chunks.rs b/vendor/rayon/src/iter/fold_chunks.rs
new file mode 100644
index 000000000..185fb1a65
--- /dev/null
+++ b/vendor/rayon/src/iter/fold_chunks.rs
@@ -0,0 +1,236 @@
+use std::fmt::{self, Debug};
+
+use super::chunks::ChunkProducer;
+use super::plumbing::*;
+use super::*;
+use crate::math::div_round_up;
+
+/// `FoldChunks` is an iterator that groups elements of an underlying iterator and applies a
+/// function over them, producing a single value for each group.
+///
+/// This struct is created by the [`fold_chunks()`] method on [`IndexedParallelIterator`]
+///
+/// [`fold_chunks()`]: trait.IndexedParallelIterator.html#method.fold_chunks
+/// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Clone)]
+pub struct FoldChunks<I, ID, F>
+where
+ I: IndexedParallelIterator,
+{
+ base: I,
+ chunk_size: usize,
+ fold_op: F,
+ identity: ID,
+}
+
+impl<I: IndexedParallelIterator + Debug, ID, F> Debug for FoldChunks<I, ID, F> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Fold")
+ .field("base", &self.base)
+ .field("chunk_size", &self.chunk_size)
+ .finish()
+ }
+}
+
+impl<I, ID, U, F> FoldChunks<I, ID, F>
+where
+ I: IndexedParallelIterator,
+ ID: Fn() -> U + Send + Sync,
+ F: Fn(U, I::Item) -> U + Send + Sync,
+ U: Send,
+{
+ /// Creates a new `FoldChunks` iterator
+ pub(super) fn new(base: I, chunk_size: usize, identity: ID, fold_op: F) -> Self {
+ FoldChunks {
+ base,
+ chunk_size,
+ identity,
+ fold_op,
+ }
+ }
+}
+
+impl<I, ID, U, F> ParallelIterator for FoldChunks<I, ID, F>
+where
+ I: IndexedParallelIterator,
+ ID: Fn() -> U + Send + Sync,
+ F: Fn(U, I::Item) -> U + Send + Sync,
+ U: Send,
+{
+ type Item = U;
+
+ fn drive_unindexed<C>(self, consumer: C) -> C::Result
+ where
+ C: Consumer<U>,
+ {
+ bridge(self, consumer)
+ }
+
+ fn opt_len(&self) -> Option<usize> {
+ Some(self.len())
+ }
+}
+
+impl<I, ID, U, F> IndexedParallelIterator for FoldChunks<I, ID, F>
+where
+ I: IndexedParallelIterator,
+ ID: Fn() -> U + Send + Sync,
+ F: Fn(U, I::Item) -> U + Send + Sync,
+ U: Send,
+{
+ fn len(&self) -> usize {
+ div_round_up(self.base.len(), self.chunk_size)
+ }
+
+ fn drive<C>(self, consumer: C) -> C::Result
+ where
+ C: Consumer<Self::Item>,
+ {
+ bridge(self, consumer)
+ }
+
+ fn with_producer<CB>(self, callback: CB) -> CB::Output
+ where
+ CB: ProducerCallback<Self::Item>,
+ {
+ let len = self.base.len();
+ return self.base.with_producer(Callback {
+ chunk_size: self.chunk_size,
+ len,
+ identity: self.identity,
+ fold_op: self.fold_op,
+ callback,
+ });
+
+ struct Callback<CB, ID, F> {
+ chunk_size: usize,
+ len: usize,
+ identity: ID,
+ fold_op: F,
+ callback: CB,
+ }
+
+ impl<T, CB, ID, U, F> ProducerCallback<T> for Callback<CB, ID, F>
+ where
+ CB: ProducerCallback<U>,
+ ID: Fn() -> U + Send + Sync,
+ F: Fn(U, T) -> U + Send + Sync,
+ {
+ type Output = CB::Output;
+
+ fn callback<P>(self, base: P) -> CB::Output
+ where
+ P: Producer<Item = T>,
+ {
+ let identity = &self.identity;
+ let fold_op = &self.fold_op;
+ let fold_iter = move |iter: P::IntoIter| iter.fold(identity(), fold_op);
+ let producer = ChunkProducer::new(self.chunk_size, self.len, base, fold_iter);
+ self.callback.callback(producer)
+ }
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use std::ops::Add;
+
+ #[test]
+ fn check_fold_chunks() {
+ let words = "bishbashbosh!"
+ .chars()
+ .collect::<Vec<_>>()
+ .into_par_iter()
+ .fold_chunks(4, String::new, |mut s, c| {
+ s.push(c);
+ s
+ })
+ .collect::<Vec<_>>();
+
+ assert_eq!(words, vec!["bish", "bash", "bosh", "!"]);
+ }
+
+ // 'closure' values for tests below
+ fn id() -> i32 {
+ 0
+ }
+ fn sum<T, U>(x: T, y: U) -> T
+ where
+ T: Add<U, Output = T>,
+ {
+ x + y
+ }
+
+ #[test]
+ #[should_panic(expected = "chunk_size must not be zero")]
+ fn check_fold_chunks_zero_size() {
+ let _: Vec<i32> = vec![1, 2, 3]
+ .into_par_iter()
+ .fold_chunks(0, id, sum)
+ .collect();
+ }
+
+ #[test]
+ fn check_fold_chunks_even_size() {
+ assert_eq!(
+ vec![1 + 2 + 3, 4 + 5 + 6, 7 + 8 + 9],
+ (1..10)
+ .into_par_iter()
+ .fold_chunks(3, id, sum)
+ .collect::<Vec<i32>>()
+ );
+ }
+
+ #[test]
+ fn check_fold_chunks_empty() {
+ let v: Vec<i32> = vec![];
+ let expected: Vec<i32> = vec![];
+ assert_eq!(
+ expected,
+ v.into_par_iter()
+ .fold_chunks(2, id, sum)
+ .collect::<Vec<i32>>()
+ );
+ }
+
+ #[test]
+ fn check_fold_chunks_len() {
+ assert_eq!(4, (0..8).into_par_iter().fold_chunks(2, id, sum).len());
+ assert_eq!(3, (0..9).into_par_iter().fold_chunks(3, id, sum).len());
+ assert_eq!(3, (0..8).into_par_iter().fold_chunks(3, id, sum).len());
+ assert_eq!(1, (&[1]).par_iter().fold_chunks(3, id, sum).len());
+ assert_eq!(0, (0..0).into_par_iter().fold_chunks(3, id, sum).len());
+ }
+
+ #[test]
+ fn check_fold_chunks_uneven() {
+ let cases: Vec<(Vec<u32>, usize, Vec<u32>)> = vec![
+ ((0..5).collect(), 3, vec![0 + 1 + 2, 3 + 4]),
+ (vec![1], 5, vec![1]),
+ ((0..4).collect(), 3, vec![0 + 1 + 2, 3]),
+ ];
+
+ for (i, (v, n, expected)) in cases.into_iter().enumerate() {
+ let mut res: Vec<u32> = vec![];
+ v.par_iter()
+ .fold_chunks(n, || 0, sum)
+ .collect_into_vec(&mut res);
+ assert_eq!(expected, res, "Case {} failed", i);
+
+ res.truncate(0);
+ v.into_par_iter()
+ .fold_chunks(n, || 0, sum)
+ .rev()
+ .collect_into_vec(&mut res);
+ assert_eq!(
+ expected.into_iter().rev().collect::<Vec<u32>>(),
+ res,
+ "Case {} reversed failed",
+ i
+ );
+ }
+ }
+}
diff --git a/vendor/rayon/src/iter/fold_chunks_with.rs b/vendor/rayon/src/iter/fold_chunks_with.rs
new file mode 100644
index 000000000..af120aec4
--- /dev/null
+++ b/vendor/rayon/src/iter/fold_chunks_with.rs
@@ -0,0 +1,231 @@
+use std::fmt::{self, Debug};
+
+use super::chunks::ChunkProducer;
+use super::plumbing::*;
+use super::*;
+use crate::math::div_round_up;
+
+/// `FoldChunksWith` is an iterator that groups elements of an underlying iterator and applies a
+/// function over them, producing a single value for each group.
+///
+/// This struct is created by the [`fold_chunks_with()`] method on [`IndexedParallelIterator`]
+///
+/// [`fold_chunks_with()`]: trait.IndexedParallelIterator.html#method.fold_chunks
+/// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Clone)]
+pub struct FoldChunksWith<I, U, F>
+where
+ I: IndexedParallelIterator,
+{
+ base: I,
+ chunk_size: usize,
+ item: U,
+ fold_op: F,
+}
+
+impl<I: IndexedParallelIterator + Debug, U: Debug, F> Debug for FoldChunksWith<I, U, F> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Fold")
+ .field("base", &self.base)
+ .field("chunk_size", &self.chunk_size)
+ .field("item", &self.item)
+ .finish()
+ }
+}
+
+impl<I, U, F> FoldChunksWith<I, U, F>
+where
+ I: IndexedParallelIterator,
+ U: Send + Clone,
+ F: Fn(U, I::Item) -> U + Send + Sync,
+{
+ /// Creates a new `FoldChunksWith` iterator
+ pub(super) fn new(base: I, chunk_size: usize, item: U, fold_op: F) -> Self {
+ FoldChunksWith {
+ base,
+ chunk_size,
+ item,
+ fold_op,
+ }
+ }
+}
+
+impl<I, U, F> ParallelIterator for FoldChunksWith<I, U, F>
+where
+ I: IndexedParallelIterator,
+ U: Send + Clone,
+ F: Fn(U, I::Item) -> U + Send + Sync,
+{
+ type Item = U;
+
+ fn drive_unindexed<C>(self, consumer: C) -> C::Result
+ where
+ C: Consumer<U>,
+ {
+ bridge(self, consumer)
+ }
+
+ fn opt_len(&self) -> Option<usize> {
+ Some(self.len())
+ }
+}
+
+impl<I, U, F> IndexedParallelIterator for FoldChunksWith<I, U, F>
+where
+ I: IndexedParallelIterator,
+ U: Send + Clone,
+ F: Fn(U, I::Item) -> U + Send + Sync,
+{
+ fn len(&self) -> usize {
+ div_round_up(self.base.len(), self.chunk_size)
+ }
+
+ fn drive<C>(self, consumer: C) -> C::Result
+ where
+ C: Consumer<Self::Item>,
+ {
+ bridge(self, consumer)
+ }
+
+ fn with_producer<CB>(self, callback: CB) -> CB::Output
+ where
+ CB: ProducerCallback<Self::Item>,
+ {
+ let len = self.base.len();
+ return self.base.with_producer(Callback {
+ chunk_size: self.chunk_size,
+ len,
+ item: self.item,
+ fold_op: self.fold_op,
+ callback,
+ });
+
+ struct Callback<CB, T, F> {
+ chunk_size: usize,
+ len: usize,
+ item: T,
+ fold_op: F,
+ callback: CB,
+ }
+
+ impl<T, U, F, CB> ProducerCallback<T> for Callback<CB, U, F>
+ where
+ CB: ProducerCallback<U>,
+ U: Send + Clone,
+ F: Fn(U, T) -> U + Send + Sync,
+ {
+ type Output = CB::Output;
+
+ fn callback<P>(self, base: P) -> CB::Output
+ where
+ P: Producer<Item = T>,
+ {
+ let item = self.item;
+ let fold_op = &self.fold_op;
+ let fold_iter = move |iter: P::IntoIter| iter.fold(item.clone(), fold_op);
+ let producer = ChunkProducer::new(self.chunk_size, self.len, base, fold_iter);
+ self.callback.callback(producer)
+ }
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use std::ops::Add;
+
+ #[test]
+ fn check_fold_chunks_with() {
+ let words = "bishbashbosh!"
+ .chars()
+ .collect::<Vec<_>>()
+ .into_par_iter()
+ .fold_chunks_with(4, String::new(), |mut s, c| {
+ s.push(c);
+ s
+ })
+ .collect::<Vec<_>>();
+
+ assert_eq!(words, vec!["bish", "bash", "bosh", "!"]);
+ }
+
+ // 'closure' value for tests below
+ fn sum<T, U>(x: T, y: U) -> T
+ where
+ T: Add<U, Output = T>,
+ {
+ x + y
+ }
+
+ #[test]
+ #[should_panic(expected = "chunk_size must not be zero")]
+ fn check_fold_chunks_zero_size() {
+ let _: Vec<i32> = vec![1, 2, 3]
+ .into_par_iter()
+ .fold_chunks_with(0, 0, sum)
+ .collect();
+ }
+
+ #[test]
+ fn check_fold_chunks_even_size() {
+ assert_eq!(
+ vec![1 + 2 + 3, 4 + 5 + 6, 7 + 8 + 9],
+ (1..10)
+ .into_par_iter()
+ .fold_chunks_with(3, 0, sum)
+ .collect::<Vec<i32>>()
+ );
+ }
+
+ #[test]
+ fn check_fold_chunks_with_empty() {
+ let v: Vec<i32> = vec![];
+ let expected: Vec<i32> = vec![];
+ assert_eq!(
+ expected,
+ v.into_par_iter()
+ .fold_chunks_with(2, 0, sum)
+ .collect::<Vec<i32>>()
+ );
+ }
+
+ #[test]
+ fn check_fold_chunks_len() {
+ assert_eq!(4, (0..8).into_par_iter().fold_chunks_with(2, 0, sum).len());
+ assert_eq!(3, (0..9).into_par_iter().fold_chunks_with(3, 0, sum).len());
+ assert_eq!(3, (0..8).into_par_iter().fold_chunks_with(3, 0, sum).len());
+ assert_eq!(1, (&[1]).par_iter().fold_chunks_with(3, 0, sum).len());
+ assert_eq!(0, (0..0).into_par_iter().fold_chunks_with(3, 0, sum).len());
+ }
+
+ #[test]
+ fn check_fold_chunks_uneven() {
+ let cases: Vec<(Vec<u32>, usize, Vec<u32>)> = vec![
+ ((0..5).collect(), 3, vec![0 + 1 + 2, 3 + 4]),
+ (vec![1], 5, vec![1]),
+ ((0..4).collect(), 3, vec![0 + 1 + 2, 3]),
+ ];
+
+ for (i, (v, n, expected)) in cases.into_iter().enumerate() {
+ let mut res: Vec<u32> = vec![];
+ v.par_iter()
+ .fold_chunks_with(n, 0, sum)
+ .collect_into_vec(&mut res);
+ assert_eq!(expected, res, "Case {} failed", i);
+
+ res.truncate(0);
+ v.into_par_iter()
+ .fold_chunks_with(n, 0, sum)
+ .rev()
+ .collect_into_vec(&mut res);
+ assert_eq!(
+ expected.into_iter().rev().collect::<Vec<u32>>(),
+ res,
+ "Case {} reversed failed",
+ i
+ );
+ }
+ }
+}
diff --git a/vendor/rayon/src/iter/inspect.rs b/vendor/rayon/src/iter/inspect.rs
index 9b1cd094d..c50ca022d 100644
--- a/vendor/rayon/src/iter/inspect.rs
+++ b/vendor/rayon/src/iter/inspect.rs
@@ -209,7 +209,7 @@ where
F: Fn(&T) + Sync,
{
fn split_off_left(&self) -> Self {
- InspectConsumer::new(self.base.split_off_left(), &self.inspect_op)
+ InspectConsumer::new(self.base.split_off_left(), self.inspect_op)
}
fn to_reducer(&self) -> Self::Reducer {
diff --git a/vendor/rayon/src/iter/interleave.rs b/vendor/rayon/src/iter/interleave.rs
index b5d43d53d..3cacc49f9 100644
--- a/vendor/rayon/src/iter/interleave.rs
+++ b/vendor/rayon/src/iter/interleave.rs
@@ -310,16 +310,16 @@ where
{
#[inline]
fn next_back(&mut self) -> Option<I::Item> {
- if self.i.len() == self.j.len() {
- if self.i_next {
- self.i.next_back()
- } else {
- self.j.next_back()
+ match self.i.len().cmp(&self.j.len()) {
+ Ordering::Less => self.j.next_back(),
+ Ordering::Equal => {
+ if self.i_next {
+ self.i.next_back()
+ } else {
+ self.j.next_back()
+ }
}
- } else if self.i.len() < self.j.len() {
- self.j.next_back()
- } else {
- self.i.next_back()
+ Ordering::Greater => self.i.next_back(),
}
}
}
diff --git a/vendor/rayon/src/iter/map.rs b/vendor/rayon/src/iter/map.rs
index f2a35ff8c..da14d4082 100644
--- a/vendor/rayon/src/iter/map.rs
+++ b/vendor/rayon/src/iter/map.rs
@@ -213,7 +213,7 @@ where
R: Send,
{
fn split_off_left(&self) -> Self {
- MapConsumer::new(self.base.split_off_left(), &self.map_op)
+ MapConsumer::new(self.base.split_off_left(), self.map_op)
}
fn to_reducer(&self) -> Self::Reducer {
diff --git a/vendor/rayon/src/iter/mod.rs b/vendor/rayon/src/iter/mod.rs
index 89e96fcef..98c93267f 100644
--- a/vendor/rayon/src/iter/mod.rs
+++ b/vendor/rayon/src/iter/mod.rs
@@ -119,6 +119,8 @@ mod flat_map_iter;
mod flatten;
mod flatten_iter;
mod fold;
+mod fold_chunks;
+mod fold_chunks_with;
mod for_each;
mod from_par_iter;
mod inspect;
@@ -140,6 +142,7 @@ mod repeat;
mod rev;
mod skip;
mod splitter;
+mod step_by;
mod sum;
mod take;
mod try_fold;
@@ -165,6 +168,8 @@ pub use self::{
flatten::Flatten,
flatten_iter::FlattenIter,
fold::{Fold, FoldWith},
+ fold_chunks::FoldChunks,
+ fold_chunks_with::FoldChunksWith,
inspect::Inspect,
interleave::Interleave,
interleave_shortest::InterleaveShortest,
@@ -181,6 +186,7 @@ pub use self::{
rev::Rev,
skip::Skip,
splitter::{split, Split},
+ step_by::StepBy,
take::Take,
try_fold::{TryFold, TryFoldWith},
update::Update,
@@ -189,10 +195,6 @@ pub use self::{
zip_eq::ZipEq,
};
-mod step_by;
-#[cfg(has_step_by_rev)]
-pub use self::step_by::StepBy;
-
/// `IntoParallelIterator` implements the conversion to a [`ParallelIterator`].
///
/// By implementing `IntoParallelIterator` for a type, you define how it will
@@ -1124,7 +1126,7 @@ pub trait ParallelIterator: Sized + Send {
/// multiple sums. The number of results is nondeterministic, as
/// is the point where the breaks occur.
///
- /// So if did the same parallel fold (`fold(0, |a,b| a+b)`) on
+ /// So if we did the same parallel fold (`fold(0, |a,b| a+b)`) on
/// our example list, we might wind up with a sequence of two numbers,
/// like so:
///
@@ -2241,6 +2243,8 @@ impl<T: ParallelIterator> IntoParallelIterator for T {
/// those points.
///
/// **Note:** Not implemented for `u64`, `i64`, `u128`, or `i128` ranges
+// Waiting for `ExactSizeIterator::is_empty` to be stabilized. See rust-lang/rust#35428
+#[allow(clippy::len_without_is_empty)]
pub trait IndexedParallelIterator: ParallelIterator {
/// Collects the results of the iterator into the specified
/// vector. The vector is always truncated before execution
@@ -2339,13 +2343,18 @@ pub trait IndexedParallelIterator: ParallelIterator {
/// // we should never get here
/// assert_eq!(1, zipped.len());
/// ```
+ #[track_caller]
fn zip_eq<Z>(self, zip_op: Z) -> ZipEq<Self, Z::Iter>
where
Z: IntoParallelIterator,
Z::Iter: IndexedParallelIterator,
{
let zip_op_iter = zip_op.into_par_iter();
- assert_eq!(self.len(), zip_op_iter.len());
+ assert_eq!(
+ self.len(),
+ zip_op_iter.len(),
+ "iterators must have the same length"
+ );
ZipEq::new(self, zip_op_iter)
}
@@ -2415,6 +2424,89 @@ pub trait IndexedParallelIterator: ParallelIterator {
Chunks::new(self, chunk_size)
}
+ /// Splits an iterator into fixed-size chunks, performing a sequential [`fold()`] on
+ /// each chunk.
+ ///
+ /// Returns an iterator that produces a folded result for each chunk of items
+ /// produced by this iterator.
+ ///
+ /// This works essentially like:
+ ///
+ /// ```text
+ /// iter.chunks(chunk_size)
+ /// .map(|chunk|
+ /// chunk.into_iter()
+ /// .fold(identity, fold_op)
+ /// )
+ /// ```
+ ///
+ /// except there is no per-chunk allocation overhead.
+ ///
+ /// [`fold()`]: std::iter::Iterator#method.fold
+ ///
+ /// **Panics** if `chunk_size` is 0.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rayon::prelude::*;
+ /// let nums = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ /// let chunk_sums = nums.into_par_iter().fold_chunks(2, || 0, |a, n| a + n).collect::<Vec<_>>();
+ /// assert_eq!(chunk_sums, vec![3, 7, 11, 15, 19]);
+ /// ```
+ #[track_caller]
+ fn fold_chunks<T, ID, F>(
+ self,
+ chunk_size: usize,
+ identity: ID,
+ fold_op: F,
+ ) -> FoldChunks<Self, ID, F>
+ where
+ ID: Fn() -> T + Send + Sync,
+ F: Fn(T, Self::Item) -> T + Send + Sync,
+ T: Send,
+ {
+ assert!(chunk_size != 0, "chunk_size must not be zero");
+ FoldChunks::new(self, chunk_size, identity, fold_op)
+ }
+
+ /// Splits an iterator into fixed-size chunks, performing a sequential [`fold()`] on
+ /// each chunk.
+ ///
+ /// Returns an iterator that produces a folded result for each chunk of items
+ /// produced by this iterator.
+ ///
+ /// This works essentially like `fold_chunks(chunk_size, || init.clone(), fold_op)`,
+ /// except it doesn't require the `init` type to be `Sync`, nor any other form of
+ /// added synchronization.
+ ///
+ /// [`fold()`]: std::iter::Iterator#method.fold
+ ///
+ /// **Panics** if `chunk_size` is 0.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rayon::prelude::*;
+ /// let nums = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ /// let chunk_sums = nums.into_par_iter().fold_chunks_with(2, 0, |a, n| a + n).collect::<Vec<_>>();
+ /// assert_eq!(chunk_sums, vec![3, 7, 11, 15, 19]);
+ /// ```
+ #[track_caller]
+ fn fold_chunks_with<T, F>(
+ self,
+ chunk_size: usize,
+ init: T,
+ fold_op: F,
+ ) -> FoldChunksWith<Self, T, F>
+ where
+ T: Send + Clone,
+ F: Fn(T, Self::Item) -> T + Send + Sync,
+ {
+ assert!(chunk_size != 0, "chunk_size must not be zero");
+ FoldChunksWith::new(self, chunk_size, init, fold_op)
+ }
+
/// Lexicographically compares the elements of this `ParallelIterator` with those of
/// another.
///
@@ -2601,11 +2693,6 @@ pub trait IndexedParallelIterator: ParallelIterator {
///
/// assert_eq!(result, [3, 6, 9])
/// ```
- ///
- /// # Compatibility
- ///
- /// This method is only available on Rust 1.38 or greater.
- #[cfg(has_step_by_rev)]
fn step_by(self, step: usize) -> StepBy<Self> {
StepBy::new(self, step)
}
@@ -3146,20 +3233,9 @@ pub trait ParallelDrainRange<Idx = usize> {
/// stable clone of the standard library's `Try` trait, as yet unstable.
mod private {
use std::convert::Infallible;
+ use std::ops::ControlFlow::{self, Break, Continue};
use std::task::Poll;
- #[cfg(has_control_flow)]
- pub(crate) use std::ops::ControlFlow;
-
- #[cfg(not(has_control_flow))]
- #[allow(missing_debug_implementations)]
- pub enum ControlFlow<B, C = ()> {
- Continue(C),
- Break(B),
- }
-
- use self::ControlFlow::{Break, Continue};
-
/// Clone of `std::ops::Try`.
///
/// Implementing this trait is not permitted outside of `rayon`.
@@ -3176,7 +3252,6 @@ mod private {
fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
}
- #[cfg(has_control_flow)]
impl<B, C> Try for ControlFlow<B, C> {
private_impl! {}
diff --git a/vendor/rayon/src/iter/plumbing/README.md b/vendor/rayon/src/iter/plumbing/README.md
index cd94eae30..dbee36ba0 100644
--- a/vendor/rayon/src/iter/plumbing/README.md
+++ b/vendor/rayon/src/iter/plumbing/README.md
@@ -124,7 +124,7 @@ implement `IndexedParallelIterator`.
The `bridge` function will then connect the consumer, which is
handling the `flat_map` and `for_each`, with the producer, which is
-handling the `zip` and its preecessors. It will split down until the
+handling the `zip` and its predecessors. It will split down until the
chunks seem reasonably small, then pull items from the producer and
feed them to the consumer.
diff --git a/vendor/rayon/src/iter/step_by.rs b/vendor/rayon/src/iter/step_by.rs
index 863de3cf0..94b8334e8 100644
--- a/vendor/rayon/src/iter/step_by.rs
+++ b/vendor/rayon/src/iter/step_by.rs
@@ -1,4 +1,3 @@
-#![cfg(has_step_by_rev)]
use std::cmp::min;
use super::plumbing::*;
diff --git a/vendor/rayon/src/iter/test.rs b/vendor/rayon/src/iter/test.rs
index bc5106bec..94323d79d 100644
--- a/vendor/rayon/src/iter/test.rs
+++ b/vendor/rayon/src/iter/test.rs
@@ -117,13 +117,10 @@ fn fold_map_reduce() {
let r1 = (0_i32..32)
.into_par_iter()
.with_max_len(1)
- .fold(
- || vec![],
- |mut v, e| {
- v.push(e);
- v
- },
- )
+ .fold(Vec::new, |mut v, e| {
+ v.push(e);
+ v
+ })
.map(|v| vec![v])
.reduce_with(|mut v_a, v_b| {
v_a.extend(v_b);
@@ -394,7 +391,7 @@ fn check_slice_mut_indexed() {
#[test]
fn check_vec_indexed() {
let a = vec![1, 2, 3];
- is_indexed(a.clone().into_par_iter());
+ is_indexed(a.into_par_iter());
}
#[test]
@@ -1371,10 +1368,10 @@ fn check_find_is_present() {
let counter = AtomicUsize::new(0);
let value: Option<i32> = (0_i32..2048).into_par_iter().find_any(|&p| {
counter.fetch_add(1, Ordering::SeqCst);
- p >= 1024 && p < 1096
+ (1024..1096).contains(&p)
});
let q = value.unwrap();
- assert!(q >= 1024 && q < 1096);
+ assert!((1024..1096).contains(&q));
assert!(counter.load(Ordering::SeqCst) < 2048); // should not have visited every single one
}
@@ -1892,7 +1889,7 @@ fn check_either() {
// try an indexed iterator
let left: E = Either::Left(v.clone().into_par_iter());
- assert!(left.enumerate().eq(v.clone().into_par_iter().enumerate()));
+ assert!(left.enumerate().eq(v.into_par_iter().enumerate()));
}
#[test]
@@ -2063,7 +2060,7 @@ fn check_chunks_len() {
assert_eq!(4, (0..8).into_par_iter().chunks(2).len());
assert_eq!(3, (0..9).into_par_iter().chunks(3).len());
assert_eq!(3, (0..8).into_par_iter().chunks(3).len());
- assert_eq!(1, (&[1]).par_iter().chunks(3).len());
+ assert_eq!(1, [1].par_iter().chunks(3).len());
assert_eq!(0, (0..0).into_par_iter().chunks(3).len());
}
diff --git a/vendor/rayon/src/iter/try_fold.rs b/vendor/rayon/src/iter/try_fold.rs
index c1881d10f..6d1048d75 100644
--- a/vendor/rayon/src/iter/try_fold.rs
+++ b/vendor/rayon/src/iter/try_fold.rs
@@ -2,10 +2,9 @@ use super::plumbing::*;
use super::ParallelIterator;
use super::Try;
-use super::private::ControlFlow::{self, Break, Continue};
-
use std::fmt::{self, Debug};
use std::marker::PhantomData;
+use std::ops::ControlFlow::{self, Break, Continue};
impl<U, I, ID, F> TryFold<I, U, ID, F>
where
diff --git a/vendor/rayon/src/iter/try_reduce.rs b/vendor/rayon/src/iter/try_reduce.rs
index 7bf6cc4a5..35a724c94 100644
--- a/vendor/rayon/src/iter/try_reduce.rs
+++ b/vendor/rayon/src/iter/try_reduce.rs
@@ -2,8 +2,7 @@ use super::plumbing::*;
use super::ParallelIterator;
use super::Try;
-use super::private::ControlFlow::{self, Break, Continue};
-
+use std::ops::ControlFlow::{self, Break, Continue};
use std::sync::atomic::{AtomicBool, Ordering};
pub(super) fn try_reduce<PI, R, ID, T>(pi: PI, identity: ID, reduce_op: R) -> T
diff --git a/vendor/rayon/src/iter/try_reduce_with.rs b/vendor/rayon/src/iter/try_reduce_with.rs
index 9fe34d61d..cd7c83e27 100644
--- a/vendor/rayon/src/iter/try_reduce_with.rs
+++ b/vendor/rayon/src/iter/try_reduce_with.rs
@@ -2,8 +2,7 @@ use super::plumbing::*;
use super::ParallelIterator;
use super::Try;
-use super::private::ControlFlow::{self, Break, Continue};
-
+use std::ops::ControlFlow::{self, Break, Continue};
use std::sync::atomic::{AtomicBool, Ordering};
pub(super) fn try_reduce_with<PI, R, T>(pi: PI, reduce_op: R) -> Option<T>
diff --git a/vendor/rayon/src/iter/update.rs b/vendor/rayon/src/iter/update.rs
index 373a4d772..c693ac8d6 100644
--- a/vendor/rayon/src/iter/update.rs
+++ b/vendor/rayon/src/iter/update.rs
@@ -210,7 +210,7 @@ where
F: Fn(&mut T) + Send + Sync,
{
fn split_off_left(&self) -> Self {
- UpdateConsumer::new(self.base.split_off_left(), &self.update_op)
+ UpdateConsumer::new(self.base.split_off_left(), self.update_op)
}
fn to_reducer(&self) -> Self::Reducer {