1 | **use** **super**::plumbing::*; |

2 | **use** **super**::ParallelIterator; |

3 | |

4 | **use** std::iter::{self, Sum}; |

5 | **use** std::marker::PhantomData; |

6 | |

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 | |

15 | **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> { |

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 | |

41 | **fn** split_at(self, _index: **usize**) -> (Self, Self, Self) { |

42 | (SumConsumer::new(), SumConsumer::new(), SumConsumer::new()) |

43 | } |

44 | |

45 | **fn** into_folder(self) -> Self::Folder { |

46 | SumFolder { |

47 | sum: iter::empty::<T>().sum(), |

48 | } |

49 | } |

50 | |

51 | **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 | { |

60 | **fn** split_off_left(&self) -> Self { |

61 | SumConsumer::new() |

62 | } |

63 | |

64 | **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 | { |

73 | **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 | |

88 | **fn** consume(self, item: T) -> Self { |

89 | SumFolder { |

90 | sum: add(self.sum, iter::once(item).sum()), |

91 | } |

92 | } |

93 | |

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 | |

103 | **fn** complete(self) -> S { |

104 | self.sum |

105 | } |

106 | |

107 | **fn** full(&self) -> **bool** { |

108 | `false` |

109 | } |

110 | } |

111 | |