]> git.proxmox.com Git - rustc.git/blob - src/vendor/rayon/src/iter/product.rs
New upstream version 1.25.0+dfsg1
[rustc.git] / src / vendor / rayon / src / iter / product.rs
1 use super::ParallelIterator;
2 use super::plumbing::*;
3
4 use std::iter::{self, Product};
5 use std::marker::PhantomData;
6
7
8 pub fn product<PI, P>(pi: PI) -> P
9 where PI: ParallelIterator,
10 P: Send + Product<PI::Item> + Product
11 {
12 pi.drive_unindexed(ProductConsumer::new())
13 }
14
15 fn mul<T: Product>(left: T, right: T) -> T {
16 iter::once(left).chain(iter::once(right)).product()
17 }
18
19
20 struct ProductConsumer<P: Send> {
21 _marker: PhantomData<*const P>,
22 }
23
24 unsafe impl<P: Send> Send for ProductConsumer<P> {}
25
26 impl<P: Send> ProductConsumer<P> {
27 fn new() -> ProductConsumer<P> {
28 ProductConsumer { _marker: PhantomData }
29 }
30 }
31
32 impl<P, T> Consumer<T> for ProductConsumer<P>
33 where P: Send + Product<T> + Product
34 {
35 type Folder = ProductFolder<P>;
36 type Reducer = Self;
37 type Result = P;
38
39 fn split_at(self, _index: usize) -> (Self, Self, Self) {
40 (ProductConsumer::new(), ProductConsumer::new(), ProductConsumer::new())
41 }
42
43 fn into_folder(self) -> Self::Folder {
44 ProductFolder { product: iter::empty::<T>().product() }
45 }
46
47 fn full(&self) -> bool {
48 false
49 }
50 }
51
52 impl<P, T> UnindexedConsumer<T> for ProductConsumer<P>
53 where P: Send + Product<T> + Product
54 {
55 fn split_off_left(&self) -> Self {
56 ProductConsumer::new()
57 }
58
59 fn to_reducer(&self) -> Self::Reducer {
60 ProductConsumer::new()
61 }
62 }
63
64 impl<P> Reducer<P> for ProductConsumer<P>
65 where P: Send + Product
66 {
67 fn reduce(self, left: P, right: P) -> P {
68 mul(left, right)
69 }
70 }
71
72
73 struct ProductFolder<P> {
74 product: P,
75 }
76
77 impl<P, T> Folder<T> for ProductFolder<P>
78 where P: Product<T> + Product
79 {
80 type Result = P;
81
82 fn consume(self, item: T) -> Self {
83 ProductFolder { product: mul(self.product, iter::once(item).product()) }
84 }
85
86 fn consume_iter<I>(self, iter: I) -> Self
87 where I: IntoIterator<Item = T>
88 {
89 ProductFolder { product: mul(self.product, iter.into_iter().product()) }
90 }
91
92 fn complete(self) -> P {
93 self.product
94 }
95
96 fn full(&self) -> bool {
97 false
98 }
99 }