summaryrefslogtreecommitdiffstats
path: root/vendor/rayon/src/iter/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rayon/src/iter/mod.rs')
-rw-r--r--vendor/rayon/src/iter/mod.rs123
1 files changed, 99 insertions, 24 deletions
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! {}