use super::plumbing::*; use super::ParallelIterator; use std::iter::{self, Product}; use std::marker::PhantomData; pub(super) fn product(pi: PI) -> P where PI: ParallelIterator, P: Send + Product + Product, { pi.drive_unindexed(ProductConsumer::new()) } fn mul(left: T, right: T) -> T { [left, right].into_iter().product() } struct ProductConsumer { _marker: PhantomData<*const P>, } unsafe impl Send for ProductConsumer

{} impl ProductConsumer

{ fn new() -> ProductConsumer

{ ProductConsumer { _marker: PhantomData, } } } impl Consumer for ProductConsumer

where P: Send + Product + Product, { type Folder = ProductFolder

; 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::().product(), } } fn full(&self) -> bool { false } } impl UnindexedConsumer for ProductConsumer

where P: Send + Product + Product, { fn split_off_left(&self) -> Self { ProductConsumer::new() } fn to_reducer(&self) -> Self::Reducer { ProductConsumer::new() } } impl

Reducer

for ProductConsumer

where P: Send + Product, { fn reduce(self, left: P, right: P) -> P { mul(left, right) } } struct ProductFolder

{ product: P, } impl Folder for ProductFolder

where P: Product + Product, { type Result = P; fn consume(self, item: T) -> Self { ProductFolder { product: mul(self.product, iter::once(item).product()), } } fn consume_iter(self, iter: I) -> Self where I: IntoIterator, { ProductFolder { product: mul(self.product, iter.into_iter().product()), } } fn complete(self) -> P { self.product } fn full(&self) -> bool { false } }