1 use super::ParallelIterator
;
2 use super::plumbing
::*;
4 use std
::iter
::{self, Product}
;
5 use std
::marker
::PhantomData
;
8 pub fn product
<PI
, P
>(pi
: PI
) -> P
9 where PI
: ParallelIterator
,
10 P
: Send
+ Product
<PI
::Item
> + Product
12 pi
.drive_unindexed(ProductConsumer
::new())
15 fn mul
<T
: Product
>(left
: T
, right
: T
) -> T
{
16 iter
::once(left
).chain(iter
::once(right
)).product()
20 struct ProductConsumer
<P
: Send
> {
21 _marker
: PhantomData
<*const P
>,
24 unsafe impl<P
: Send
> Send
for ProductConsumer
<P
> {}
26 impl<P
: Send
> ProductConsumer
<P
> {
27 fn new() -> ProductConsumer
<P
> {
28 ProductConsumer { _marker: PhantomData }
32 impl<P
, T
> Consumer
<T
> for ProductConsumer
<P
>
33 where P
: Send
+ Product
<T
> + Product
35 type Folder
= ProductFolder
<P
>;
39 fn split_at(self, _index
: usize) -> (Self, Self, Self) {
40 (ProductConsumer
::new(), ProductConsumer
::new(), ProductConsumer
::new())
43 fn into_folder(self) -> Self::Folder
{
44 ProductFolder { product: iter::empty::<T>().product() }
47 fn full(&self) -> bool
{
52 impl<P
, T
> UnindexedConsumer
<T
> for ProductConsumer
<P
>
53 where P
: Send
+ Product
<T
> + Product
55 fn split_off_left(&self) -> Self {
56 ProductConsumer
::new()
59 fn to_reducer(&self) -> Self::Reducer
{
60 ProductConsumer
::new()
64 impl<P
> Reducer
<P
> for ProductConsumer
<P
>
65 where P
: Send
+ Product
67 fn reduce(self, left
: P
, right
: P
) -> P
{
73 struct ProductFolder
<P
> {
77 impl<P
, T
> Folder
<T
> for ProductFolder
<P
>
78 where P
: Product
<T
> + Product
82 fn consume(self, item
: T
) -> Self {
83 ProductFolder { product: mul(self.product, iter::once(item).product()) }
86 fn consume_iter
<I
>(self, iter
: I
) -> Self
87 where I
: IntoIterator
<Item
= T
>
89 ProductFolder { product: mul(self.product, iter.into_iter().product()) }
92 fn complete(self) -> P
{
96 fn full(&self) -> bool
{