aboutsummaryrefslogtreecommitdiff
path: root/src/iter/product.rs
diff options
context:
space:
mode:
authorJakub Kotur <qtr@google.com>2021-03-16 20:22:30 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-03-16 20:22:30 +0000
commit4c0b8e0ef78bcd80a4facc34c6a2158d83f96802 (patch)
tree13641ab7afc7aa43b586606c18d53084dedf7ace /src/iter/product.rs
parenta679e9b8b7e4ae27a19b81f216e375ea8a9cdb8e (diff)
parent7522a9ba008ac88224e0990932bdd298a43a2336 (diff)
downloadrayon-4c0b8e0ef78bcd80a4facc34c6a2158d83f96802.tar.gz
Initial import of rayon-1.5.0. am: 041839ceab am: d836dd6404 am: 7522a9ba00
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/rayon/+/1622436 Change-Id: I94b0e06d9da131d6f98db436ad1a178dfff2ec90
Diffstat (limited to 'src/iter/product.rs')
-rw-r--r--src/iter/product.rs114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/iter/product.rs b/src/iter/product.rs
new file mode 100644
index 0000000..a3d0727
--- /dev/null
+++ b/src/iter/product.rs
@@ -0,0 +1,114 @@
+use super::plumbing::*;
+use super::ParallelIterator;
+
+use std::iter::{self, Product};
+use std::marker::PhantomData;
+
+pub(super) fn product<PI, P>(pi: PI) -> P
+where
+ PI: ParallelIterator,
+ P: Send + Product<PI::Item> + Product,
+{
+ pi.drive_unindexed(ProductConsumer::new())
+}
+
+fn mul<T: Product>(left: T, right: T) -> T {
+ iter::once(left).chain(iter::once(right)).product()
+}
+
+struct ProductConsumer<P: Send> {
+ _marker: PhantomData<*const P>,
+}
+
+unsafe impl<P: Send> Send for ProductConsumer<P> {}
+
+impl<P: Send> ProductConsumer<P> {
+ fn new() -> ProductConsumer<P> {
+ ProductConsumer {
+ _marker: PhantomData,
+ }
+ }
+}
+
+impl<P, T> Consumer<T> for ProductConsumer<P>
+where
+ P: Send + Product<T> + Product,
+{
+ type Folder = ProductFolder<P>;
+ type Reducer = Self;
+ type Result = P;
+
+ fn split_at(self, _index: usize) -> (Self, Self, Self) {
+ (
+ ProductConsumer::new(),
+ ProductConsumer::new(),
+ ProductConsumer::new(),
+ )
+ }
+
+ fn into_folder(self) -> Self::Folder {
+ ProductFolder {
+ product: iter::empty::<T>().product(),
+ }
+ }
+
+ fn full(&self) -> bool {
+ false
+ }
+}
+
+impl<P, T> UnindexedConsumer<T> for ProductConsumer<P>
+where
+ P: Send + Product<T> + Product,
+{
+ fn split_off_left(&self) -> Self {
+ ProductConsumer::new()
+ }
+
+ fn to_reducer(&self) -> Self::Reducer {
+ ProductConsumer::new()
+ }
+}
+
+impl<P> Reducer<P> for ProductConsumer<P>
+where
+ P: Send + Product,
+{
+ fn reduce(self, left: P, right: P) -> P {
+ mul(left, right)
+ }
+}
+
+struct ProductFolder<P> {
+ product: P,
+}
+
+impl<P, T> Folder<T> for ProductFolder<P>
+where
+ P: Product<T> + Product,
+{
+ type Result = P;
+
+ fn consume(self, item: T) -> Self {
+ ProductFolder {
+ product: mul(self.product, iter::once(item).product()),
+ }
+ }
+
+ fn consume_iter<I>(self, iter: I) -> Self
+ where
+ I: IntoIterator<Item = T>,
+ {
+ ProductFolder {
+ product: mul(self.product, iter.into_iter().product()),
+ }
+ }
+
+ fn complete(self) -> P {
+ self.product
+ }
+
+ fn full(&self) -> bool {
+ false
+ }
+}