1use crate::cbig::CBig;
9use core::iter::{Product, Sum};
10use dashu_float::round::Round;
11use dashu_int::Word;
12
13impl<R: Round, const B: Word> Sum for CBig<R, B> {
14 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
15 iter.fold(CBig::ZERO, |acc, x| acc + x)
16 }
17}
18
19impl<'a, R: Round, const B: Word> Sum<&'a CBig<R, B>> for CBig<R, B> {
20 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
21 iter.fold(CBig::ZERO, |acc, x| acc + x)
22 }
23}
24
25impl<R: Round, const B: Word> Product for CBig<R, B> {
26 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
27 iter.fold(CBig::ONE, |acc, x| acc * x)
28 }
29}
30
31impl<'a, R: Round, const B: Word> Product<&'a CBig<R, B>> for CBig<R, B> {
32 fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
33 iter.fold(CBig::ONE, |acc, x| acc * x)
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use crate::cbig::CBig;
40 use dashu_float::round::mode::HalfAway;
41 use dashu_float::FBig;
42
43 type C = CBig<HalfAway, 10>;
44 type F = FBig<HalfAway, 10>;
45
46 #[test]
47 fn sum_owned_and_ref() {
48 let z = C::from_parts(F::from(3), F::from(4)); let w = C::from_parts(F::from(1), F::from(2)); let expected = C::from_parts(F::from(4), F::from(6));
51
52 let owned: C = [z.clone(), w.clone()].into_iter().sum();
53 assert_eq!(owned, expected);
54
55 let by_ref: C = [z, w].iter().sum();
56 assert_eq!(by_ref, expected);
57 }
58
59 #[test]
60 fn product_owned_and_ref() {
61 let z = C::from_parts(F::from(3), F::from(4));
63 let w = C::from_parts(F::from(1), F::from(2));
64 let expected = C::from_parts(F::from(-5), F::from(10));
65
66 let owned: C = [z.clone(), w.clone()].into_iter().product();
67 assert_eq!(owned, expected);
68
69 let by_ref: C = [z, w].iter().product();
70 assert_eq!(by_ref, expected);
71 }
72
73 #[test]
74 fn sum_and_product_empty() {
75 let s: C = core::iter::empty::<C>().sum();
76 assert_eq!(s, C::ZERO);
77 let p: C = core::iter::empty::<C>().product();
78 assert_eq!(p, C::ONE);
79 }
80}