1 use super::plumbing::*;
2 use super::ParallelIterator;
3
4 use std::iter::{self, Sum};
5 use std::marker::PhantomData;
6
sum<PI, S>(pi: PI) -> S where PI: ParallelIterator, S: Send + Sum<PI::Item> + Sum,7 pub(super) fn sum<PI, S>(pi: PI) -> S
8 where
9 PI: ParallelIterator,
10 S: Send + Sum<PI::Item> + Sum,
11 {
12 pi.drive_unindexed(SumConsumer::new())
13 }
14
add<T: Sum>(left: T, right: T) -> T15 fn add<T: Sum>(left: T, right: T) -> T {
16 [left, right].into_iter().sum()
17 }
18
19 struct SumConsumer<S: Send> {
20 _marker: PhantomData<*const S>,
21 }
22
23 unsafe impl<S: Send> Send for SumConsumer<S> {}
24
25 impl<S: Send> SumConsumer<S> {
new() -> SumConsumer<S>26 fn new() -> SumConsumer<S> {
27 SumConsumer {
28 _marker: PhantomData,
29 }
30 }
31 }
32
33 impl<S, T> Consumer<T> for SumConsumer<S>
34 where
35 S: Send + Sum<T> + Sum,
36 {
37 type Folder = SumFolder<S>;
38 type Reducer = Self;
39 type Result = S;
40
split_at(self, _index: usize) -> (Self, Self, Self)41 fn split_at(self, _index: usize) -> (Self, Self, Self) {
42 (SumConsumer::new(), SumConsumer::new(), SumConsumer::new())
43 }
44
into_folder(self) -> Self::Folder45 fn into_folder(self) -> Self::Folder {
46 SumFolder {
47 sum: iter::empty::<T>().sum(),
48 }
49 }
50
full(&self) -> bool51 fn full(&self) -> bool {
52 false
53 }
54 }
55
56 impl<S, T> UnindexedConsumer<T> for SumConsumer<S>
57 where
58 S: Send + Sum<T> + Sum,
59 {
split_off_left(&self) -> Self60 fn split_off_left(&self) -> Self {
61 SumConsumer::new()
62 }
63
to_reducer(&self) -> Self::Reducer64 fn to_reducer(&self) -> Self::Reducer {
65 SumConsumer::new()
66 }
67 }
68
69 impl<S> Reducer<S> for SumConsumer<S>
70 where
71 S: Send + Sum,
72 {
reduce(self, left: S, right: S) -> S73 fn reduce(self, left: S, right: S) -> S {
74 add(left, right)
75 }
76 }
77
78 struct SumFolder<S> {
79 sum: S,
80 }
81
82 impl<S, T> Folder<T> for SumFolder<S>
83 where
84 S: Sum<T> + Sum,
85 {
86 type Result = S;
87
consume(self, item: T) -> Self88 fn consume(self, item: T) -> Self {
89 SumFolder {
90 sum: add(self.sum, iter::once(item).sum()),
91 }
92 }
93
consume_iter<I>(self, iter: I) -> Self where I: IntoIterator<Item = T>,94 fn consume_iter<I>(self, iter: I) -> Self
95 where
96 I: IntoIterator<Item = T>,
97 {
98 SumFolder {
99 sum: add(self.sum, iter.into_iter().sum()),
100 }
101 }
102
complete(self) -> S103 fn complete(self) -> S {
104 self.sum
105 }
106
full(&self) -> bool107 fn full(&self) -> bool {
108 false
109 }
110 }
111