| @@ -15,7 +15,7 @@ use crate::{ | |||
| count::Count, | |||
| filter::Filter, | |||
| filter_map::FilterMap, | |||
| find::{Find, FindMap, FindMatch}, | |||
| find::{All, Any, Find, FindMap, FindMatch}, | |||
| flatten::{FlatMapIter, FlattenIter}, | |||
| fold::{Fold, FoldWith}, | |||
| for_each::ForEach, | |||
| @@ -155,7 +155,7 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| /// ``` | |||
| fn for_each_with<O, T>(self, init: T, operation: O) -> Collect<MapWith<Self, T, O>, ()> | |||
| where | |||
| O: Fn(&mut T, Self::Item) + Clone + Send + Sync + 'a, | |||
| O: Fn(&mut T, Self::Item) + Clone + Send + 'a, | |||
| T: Clone + Send + 'a, | |||
| { | |||
| self.map_with(init, operation).collect() | |||
| @@ -189,8 +189,8 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| /// ``` | |||
| fn for_each_init<O, S, T>(self, init: S, operation: O) -> Collect<MapInit<Self, S, O>, ()> | |||
| where | |||
| O: Fn(&mut T, Self::Item) + Clone + Sync + Send + 'a, | |||
| S: Fn() -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(&mut T, Self::Item) + Clone + Send + 'a, | |||
| S: Fn() -> T + Clone + Send + 'a, | |||
| { | |||
| self.map_init(init, operation).collect() | |||
| } | |||
| @@ -217,7 +217,7 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| /// ``` | |||
| fn try_for_each<O, T>(self, operation: O) -> TryForEach<Self, O> | |||
| where | |||
| O: Fn(Self::Item) -> T + Clone + Sync + Send, | |||
| O: Fn(Self::Item) -> T + Clone + Send, | |||
| T: Try<Ok = ()> + Send, | |||
| { | |||
| TryForEach::new(self, operation) | |||
| @@ -253,7 +253,7 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| fn try_for_each_with<O, S, T>(self, init: S, operation: O) -> TryForEachWith<Self, S, O> | |||
| where | |||
| S: Clone + Send + 'a, | |||
| O: Fn(&mut S, Self::Item) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(&mut S, Self::Item) -> T + Clone + Send + 'a, | |||
| T: Try<Ok = ()> + Send + 'a, | |||
| { | |||
| TryForEachWith::new(self, init, operation) | |||
| @@ -290,8 +290,8 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| /// ``` | |||
| fn try_for_each_init<O, S, T, U>(self, init: S, operation: O) -> TryForEachInit<Self, S, O> | |||
| where | |||
| O: Fn(&mut U, Self::Item) -> T + Clone + Sync + Send + 'a, | |||
| S: Fn() -> U + Clone + Send + Sync + 'a, | |||
| O: Fn(&mut U, Self::Item) -> T + Clone + Send + 'a, | |||
| S: Fn() -> U + Clone + Send + 'a, | |||
| T: Try<Ok = ()> + Send + 'a, | |||
| { | |||
| TryForEachInit::new(self, init, operation) | |||
| @@ -328,7 +328,7 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| /// ``` | |||
| fn map<O, T>(self, operation: O) -> Map<Self, O> | |||
| where | |||
| O: Fn(Self::Item) -> T + Sync + Send, | |||
| O: Fn(Self::Item) -> T + Clone + Send, | |||
| T: Send, | |||
| { | |||
| Map::new(self, operation) | |||
| @@ -366,7 +366,7 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| /// ``` | |||
| fn map_with<O, T, S>(self, init: S, operation: O) -> MapWith<Self, S, O> | |||
| where | |||
| O: Fn(&mut S, Self::Item) -> T + Clone + Sync + Send, | |||
| O: Fn(&mut S, Self::Item) -> T + Clone + Send, | |||
| S: Send + Clone, | |||
| T: Send, | |||
| { | |||
| @@ -403,8 +403,8 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| /// ``` | |||
| fn map_init<O, T, S, U>(self, init: S, operation: O) -> MapInit<Self, S, O> | |||
| where | |||
| O: Fn(&mut U, Self::Item) -> T + Sync + Send, | |||
| S: Fn() -> U + Sync + Send, | |||
| O: Fn(&mut U, Self::Item) -> T + Send, | |||
| S: Fn() -> U + Send, | |||
| T: Send, | |||
| { | |||
| MapInit::new(self, init, operation) | |||
| @@ -707,7 +707,7 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| /// [associative]: https://en.wikipedia.org/wiki/Associative_property | |||
| fn reduce_with<O>(self, operation: O) -> ReduceWith<Self, O> | |||
| where | |||
| O: Fn(Self::Item, Self::Item) -> Self::Item + Sync + Send + 'a, | |||
| O: Fn(Self::Item, Self::Item) -> Self::Item + Clone + Send + 'a, | |||
| { | |||
| ReduceWith::new(self, operation) | |||
| } | |||
| @@ -745,9 +745,9 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| /// ``` | |||
| fn try_reduce<S, O, T>(self, identity: S, operation: O) -> TryReduce<Self, S, O> | |||
| where | |||
| S: Fn() -> T + Sync + Send, | |||
| O: Fn(T, T) -> Self::Item + Sync + Send, | |||
| Self::Item: Try<Ok = T>, | |||
| S: Fn() -> T + Clone + Send + 'a, | |||
| O: Fn(T, T) -> Self::Item + Clone + Send + 'a, | |||
| { | |||
| TryReduce::new(self, identity, operation) | |||
| } | |||
| @@ -790,7 +790,7 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| fn try_reduce_with<O, T>(self, operation: O) -> TryReduceWith<Self, O> | |||
| where | |||
| Self::Item: Try<Ok = T>, | |||
| O: Fn(T, T) -> Self::Item + Sync + Send + 'a, | |||
| O: Fn(T, T) -> Self::Item + Clone + Send + 'a, | |||
| { | |||
| TryReduceWith::new(self, operation) | |||
| } | |||
| @@ -1452,6 +1452,52 @@ pub trait ParallelIterator<'a>: Sized + Send { | |||
| FindMap::new(self, operation, FindMatch::Last) | |||
| } | |||
| /// Searches for **some** item in the parallel iterator that | |||
| /// matches the given operation, and if so returns true. Once | |||
| /// a match is found, we'll attempt to stop process the rest | |||
| /// of the items. Proving that there's no match, returning false, | |||
| /// does require visiting every item. | |||
| /// | |||
| /// # Examples | |||
| /// | |||
| /// ``` | |||
| /// use rayon::prelude::*; | |||
| /// | |||
| /// let a = [0, 12, 3, 4, 0, 23, 0]; | |||
| /// | |||
| /// let is_valid = a.par_iter().any(|&x| x > 10); | |||
| /// | |||
| /// assert!(is_valid); | |||
| /// ``` | |||
| fn any<O>(self, operation: O) -> Any<Self, O> | |||
| where | |||
| O: Fn(Self::Item) -> bool + Clone + Send + 'a, | |||
| { | |||
| Any::new(self, operation) | |||
| } | |||
| /// Tests that every item in the parallel iterator matches the given | |||
| /// operation, and if so returns true. If a counter-example is found, | |||
| /// we'll attempt to stop processing more items, then return false. | |||
| /// | |||
| /// # Examples | |||
| /// | |||
| /// ``` | |||
| /// use rayon::prelude::*; | |||
| /// | |||
| /// let a = [0, 12, 3, 4, 0, 23, 0]; | |||
| /// | |||
| /// let is_valid = a.par_iter().all(|&x| x > 10); | |||
| /// | |||
| /// assert!(!is_valid); | |||
| /// ``` | |||
| fn all<O>(self, operation: O) -> All<Self, O> | |||
| where | |||
| O: Fn(Self::Item) -> bool + Clone + Send + 'a, | |||
| { | |||
| All::new(self, operation) | |||
| } | |||
| /// Creates a fresh collection containing all the elements produced | |||
| /// by this parallel iterator. | |||
| /// | |||
| @@ -88,6 +88,82 @@ where | |||
| } | |||
| } | |||
| /* Any */ | |||
| pub struct Any<X, O> { | |||
| iterator: X, | |||
| operation: O, | |||
| } | |||
| impl<X, O> Any<X, O> { | |||
| pub fn new(iterator: X, operation: O) -> Self { | |||
| Self { | |||
| iterator, | |||
| operation, | |||
| } | |||
| } | |||
| } | |||
| impl<'a, X, O> Driver<'a, bool, Option<bool>> for Any<X, O> | |||
| where | |||
| X: ParallelIterator<'a>, | |||
| O: Fn(X::Item) -> bool + Clone + Send + 'a, | |||
| { | |||
| fn exec_with<E>(self, executor: E) -> E::Result | |||
| where | |||
| E: Executor<'a, bool, Option<bool>>, | |||
| { | |||
| let executor = executor.into_inner(); | |||
| let ret = Find::new( | |||
| self.iterator.map(self.operation), | |||
| bool::clone, | |||
| FindMatch::Any, | |||
| ) | |||
| .exec_with(executor); | |||
| E::map(ret, |x| x.is_some()) | |||
| } | |||
| } | |||
| /* All */ | |||
| pub struct All<X, O> { | |||
| iterator: X, | |||
| operation: O, | |||
| } | |||
| impl<X, O> All<X, O> { | |||
| pub fn new(iterator: X, operation: O) -> Self { | |||
| Self { | |||
| iterator, | |||
| operation, | |||
| } | |||
| } | |||
| } | |||
| impl<'a, X, O> Driver<'a, bool, Option<bool>> for All<X, O> | |||
| where | |||
| X: ParallelIterator<'a>, | |||
| O: Fn(X::Item) -> bool + Clone + Send + 'a, | |||
| { | |||
| fn exec_with<E>(self, executor: E) -> E::Result | |||
| where | |||
| E: Executor<'a, bool, Option<bool>>, | |||
| { | |||
| let executor = executor.into_inner(); | |||
| let ret = Find::new( | |||
| self.iterator.map(self.operation), | |||
| |x: &bool| !x, | |||
| FindMatch::Any, | |||
| ) | |||
| .exec_with(executor); | |||
| E::map(ret, |x| x.is_some()) | |||
| } | |||
| } | |||
| /* FindConsumer */ | |||
| struct FindConsumer<O> { | |||
| @@ -19,7 +19,7 @@ impl<X, O> Map<X, O> { | |||
| impl<'a, X, O, T> ParallelIterator<'a> for Map<X, O> | |||
| where | |||
| X: ParallelIterator<'a>, | |||
| O: Fn(X::Item) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(X::Item) -> T + Clone + Send + 'a, | |||
| T: Send + 'a, | |||
| { | |||
| type Item = O::Output; | |||
| @@ -54,7 +54,7 @@ where | |||
| impl<'a, X, O, T> IndexedParallelIterator<'a> for Map<X, O> | |||
| where | |||
| X: IndexedParallelIterator<'a>, | |||
| O: Fn(X::Item) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(X::Item) -> T + Clone + Send + 'a, | |||
| T: Send + 'a, | |||
| { | |||
| fn drive_indexed<E, C, D, R>(self, executor: E, consumer: C) -> E::Result | |||
| @@ -94,7 +94,7 @@ struct MapCallback<CB, O> { | |||
| impl<'a, I, O, T, CB> ProducerCallback<'a, I> for MapCallback<CB, O> | |||
| where | |||
| CB: ProducerCallback<'a, T>, | |||
| O: Fn(I) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(I) -> T + Clone + Send + 'a, | |||
| T: Send, | |||
| { | |||
| type Output = CB::Output; | |||
| @@ -115,7 +115,7 @@ where | |||
| impl<'a, I, O, T, CB> IndexedProducerCallback<'a, I> for MapCallback<CB, O> | |||
| where | |||
| CB: IndexedProducerCallback<'a, T>, | |||
| O: Fn(I) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(I) -> T + Clone + Send + 'a, | |||
| T: Send, | |||
| { | |||
| type Output = CB::Output; | |||
| @@ -143,7 +143,7 @@ struct MapProducer<P, O> { | |||
| impl<P, O, T> Producer for MapProducer<P, O> | |||
| where | |||
| P: Producer, | |||
| O: Fn(P::Item) -> T + Clone + Sync + Send, | |||
| O: Fn(P::Item) -> T + Clone + Send, | |||
| T: Send, | |||
| { | |||
| type Item = O::Output; | |||
| @@ -185,7 +185,7 @@ where | |||
| impl<P, O, T> IndexedProducer for MapProducer<P, O> | |||
| where | |||
| P: IndexedProducer, | |||
| O: Fn(P::Item) -> T + Clone + Sync + Send, | |||
| O: Fn(P::Item) -> T + Clone + Send, | |||
| T: Send, | |||
| { | |||
| type Item = O::Output; | |||
| @@ -255,7 +255,7 @@ impl<C, O> MapConsumer<C, O> { | |||
| impl<I, T, C, O> Consumer<I> for MapConsumer<C, O> | |||
| where | |||
| C: Consumer<O::Output>, | |||
| O: Fn(I) -> T + Clone + Send + Sync, | |||
| O: Fn(I) -> T + Clone + Send, | |||
| T: Send, | |||
| { | |||
| type Folder = MapFolder<C::Folder, O>; | |||
| @@ -26,7 +26,7 @@ impl<X, S, O> MapInit<X, S, O> { | |||
| impl<'a, X, O, T, S, U> ParallelIterator<'a> for MapInit<X, S, O> | |||
| where | |||
| X: ParallelIterator<'a>, | |||
| O: Fn(&mut U, X::Item) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(&mut U, X::Item) -> T + Clone + Send + 'a, | |||
| T: Send + 'a, | |||
| S: Fn() -> U + Clone + Send + 'a, | |||
| { | |||
| @@ -63,7 +63,7 @@ where | |||
| impl<'a, X, O, T, S, U> IndexedParallelIterator<'a> for MapInit<X, S, O> | |||
| where | |||
| X: IndexedParallelIterator<'a>, | |||
| O: Fn(&mut U, X::Item) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(&mut U, X::Item) -> T + Clone + Send + 'a, | |||
| T: Send + 'a, | |||
| S: Fn() -> U + Clone + Send + 'a, | |||
| { | |||
| @@ -106,7 +106,7 @@ struct MapInitCallback<CB, S, O> { | |||
| impl<'a, I, S, O, T, U, CB> ProducerCallback<'a, I> for MapInitCallback<CB, S, O> | |||
| where | |||
| CB: ProducerCallback<'a, T>, | |||
| O: Fn(&mut U, I) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(&mut U, I) -> T + Clone + Send + 'a, | |||
| T: Send, | |||
| S: Fn() -> U + Clone + Send + 'a, | |||
| { | |||
| @@ -129,7 +129,7 @@ where | |||
| impl<'a, I, S, O, T, U, CB> IndexedProducerCallback<'a, I> for MapInitCallback<CB, S, O> | |||
| where | |||
| CB: IndexedProducerCallback<'a, T>, | |||
| O: Fn(&mut U, I) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(&mut U, I) -> T + Clone + Send + 'a, | |||
| T: Send, | |||
| S: Fn() -> U + Clone + Send + 'a, | |||
| { | |||
| @@ -160,7 +160,7 @@ struct MapInitProducer<P, S, O> { | |||
| impl<P, S, O, T, U> Producer for MapInitProducer<P, S, O> | |||
| where | |||
| P: Producer, | |||
| O: Fn(&mut U, P::Item) -> T + Clone + Sync + Send, | |||
| O: Fn(&mut U, P::Item) -> T + Clone + Send, | |||
| T: Send, | |||
| S: Fn() -> U + Clone + Send, | |||
| { | |||
| @@ -211,7 +211,7 @@ where | |||
| impl<P, S, O, T, U> IndexedProducer for MapInitProducer<P, S, O> | |||
| where | |||
| P: IndexedProducer, | |||
| O: Fn(&mut U, P::Item) -> T + Clone + Sync + Send, | |||
| O: Fn(&mut U, P::Item) -> T + Clone + Send, | |||
| T: Send, | |||
| S: Fn() -> U + Clone + Send, | |||
| { | |||
| @@ -294,7 +294,7 @@ impl<C, S, O> MapInitConsumer<C, S, O> { | |||
| impl<I, T, C, S, U, O> Consumer<I> for MapInitConsumer<C, S, O> | |||
| where | |||
| C: Consumer<T>, | |||
| O: Fn(&mut U, I) -> T + Clone + Send + Sync, | |||
| O: Fn(&mut U, I) -> T + Clone + Send, | |||
| T: Send, | |||
| S: Fn() -> U + Clone + Send, | |||
| { | |||
| @@ -24,7 +24,7 @@ impl<X, S, O> MapWith<X, S, O> { | |||
| impl<'a, X, O, T, S> ParallelIterator<'a> for MapWith<X, S, O> | |||
| where | |||
| X: ParallelIterator<'a>, | |||
| O: Fn(&mut S, X::Item) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(&mut S, X::Item) -> T + Clone + Send + 'a, | |||
| T: Send + 'a, | |||
| S: Clone + Send + 'a, | |||
| { | |||
| @@ -61,7 +61,7 @@ where | |||
| impl<'a, X, O, T, S> IndexedParallelIterator<'a> for MapWith<X, S, O> | |||
| where | |||
| X: IndexedParallelIterator<'a>, | |||
| O: Fn(&mut S, X::Item) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(&mut S, X::Item) -> T + Clone + Send + 'a, | |||
| T: Send + 'a, | |||
| S: Clone + Send + 'a, | |||
| { | |||
| @@ -104,7 +104,7 @@ struct MapWithCallback<CB, S, O> { | |||
| impl<'a, I, S, O, T, CB> ProducerCallback<'a, I> for MapWithCallback<CB, S, O> | |||
| where | |||
| CB: ProducerCallback<'a, T>, | |||
| O: Fn(&mut S, I) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(&mut S, I) -> T + Clone + Send + 'a, | |||
| T: Send, | |||
| S: Clone + Send + 'a, | |||
| { | |||
| @@ -127,7 +127,7 @@ where | |||
| impl<'a, I, S, O, T, CB> IndexedProducerCallback<'a, I> for MapWithCallback<CB, S, O> | |||
| where | |||
| CB: IndexedProducerCallback<'a, T>, | |||
| O: Fn(&mut S, I) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(&mut S, I) -> T + Clone + Send + 'a, | |||
| T: Send, | |||
| S: Clone + Send + 'a, | |||
| { | |||
| @@ -158,7 +158,7 @@ struct MapWithProducer<P, S, O> { | |||
| impl<P, S, O, T> Producer for MapWithProducer<P, S, O> | |||
| where | |||
| P: Producer, | |||
| O: Fn(&mut S, P::Item) -> T + Clone + Sync + Send, | |||
| O: Fn(&mut S, P::Item) -> T + Clone + Send, | |||
| T: Send, | |||
| S: Clone + Send, | |||
| { | |||
| @@ -209,7 +209,7 @@ where | |||
| impl<P, S, O, T> IndexedProducer for MapWithProducer<P, S, O> | |||
| where | |||
| P: IndexedProducer, | |||
| O: Fn(&mut S, P::Item) -> T + Clone + Sync + Send, | |||
| O: Fn(&mut S, P::Item) -> T + Clone + Send, | |||
| T: Send, | |||
| S: Clone + Send, | |||
| { | |||
| @@ -337,7 +337,7 @@ impl<C, S, O> MapWithConsumer<C, S, O> { | |||
| impl<I, T, C, S, O> Consumer<I> for MapWithConsumer<C, S, O> | |||
| where | |||
| C: Consumer<T>, | |||
| O: Fn(&mut S, I) -> T + Clone + Send + Sync, | |||
| O: Fn(&mut S, I) -> T + Clone + Send, | |||
| T: Send, | |||
| S: Clone + Send, | |||
| { | |||
| @@ -19,7 +19,7 @@ impl<X, O> TryForEach<X, O> { | |||
| impl<'a, X, O, T> Driver<'a, T> for TryForEach<X, O> | |||
| where | |||
| X: ParallelIterator<'a>, | |||
| O: Fn(X::Item) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(X::Item) -> T + Clone + Send + 'a, | |||
| T: Try<Ok = ()> + Send + 'a, | |||
| { | |||
| fn exec_with<E>(self, executor: E) -> E::Result | |||
| @@ -64,7 +64,7 @@ impl<'a, X, S, O, T> Driver<'a, T> for TryForEachWith<X, S, O> | |||
| where | |||
| X: ParallelIterator<'a>, | |||
| S: Clone + Send + 'a, | |||
| O: Fn(&mut S, X::Item) -> T + Clone + Sync + Send + 'a, | |||
| O: Fn(&mut S, X::Item) -> T + Clone + Send + 'a, | |||
| T: Try<Ok = ()> + Send + 'a, | |||
| { | |||
| fn exec_with<E>(self, executor: E) -> E::Result | |||
| @@ -109,8 +109,8 @@ impl<X, S, O> TryForEachInit<X, S, O> { | |||
| impl<'a, X, S, O, T, U> Driver<'a, T> for TryForEachInit<X, S, O> | |||
| where | |||
| X: ParallelIterator<'a>, | |||
| S: Fn() -> U + Clone + Send + Sync + 'a, | |||
| O: Fn(&mut U, X::Item) -> T + Clone + Sync + Send + 'a, | |||
| S: Fn() -> U + Clone + Send + 'a, | |||
| O: Fn(&mut U, X::Item) -> T + Clone + Send + 'a, | |||
| T: Try<Ok = ()> + Send + 'a, | |||
| { | |||
| fn exec_with<E>(self, executor: E) -> E::Result | |||