fixed_bigint/heapless/
iter.rs1use super::HeaplessBigInt;
13use crate::MachineWord;
14use const_num_traits::{CarryingMul, One, Personality, Zero};
15
16impl<T, const CAP: usize, P: Personality> core::iter::Sum for HeaplessBigInt<T, CAP, P>
17where
18 T: MachineWord,
19{
20 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
21 iter.fold(<Self as Zero>::zero(), |acc, x| acc + x)
22 }
23}
24
25impl<'a, T, const CAP: usize, P: Personality> core::iter::Sum<&'a Self>
26 for HeaplessBigInt<T, CAP, P>
27where
28 T: MachineWord,
29{
30 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
31 iter.fold(<Self as Zero>::zero(), |acc, x| acc + *x)
32 }
33}
34
35impl<T, const CAP: usize, P: Personality> core::iter::Product for HeaplessBigInt<T, CAP, P>
36where
37 T: MachineWord + CarryingMul<Unsigned = T, Output = T>,
38{
39 fn product<I: Iterator<Item = Self>>(mut iter: I) -> Self {
40 match iter.next() {
41 None => <Self as One>::one(),
42 Some(first) => iter.fold(first, |acc, x| acc * x),
43 }
44 }
45}
46
47impl<'a, T, const CAP: usize, P: Personality> core::iter::Product<&'a Self>
48 for HeaplessBigInt<T, CAP, P>
49where
50 T: MachineWord + CarryingMul<Unsigned = T, Output = T>,
51{
52 fn product<I: Iterator<Item = &'a Self>>(mut iter: I) -> Self {
53 match iter.next() {
54 None => <Self as One>::one(),
55 Some(first) => iter.fold(*first, |acc, x| acc * *x),
56 }
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::HeaplessBigInt;
63
64 type H = HeaplessBigInt<u8, 8>;
65
66 #[test]
67 fn sum_product() {
68 let vals = [H::from(1u8), H::from(2u8), H::from(3u8), H::from(4u8)];
69 assert_eq!(vals.iter().copied().sum::<H>(), H::from(10u8));
70 assert_eq!(vals.iter().sum::<H>(), H::from(10u8));
71 assert_eq!(vals.iter().copied().product::<H>(), H::from(24u8));
72 assert_eq!(vals.iter().product::<H>(), H::from(24u8));
73 }
74
75 #[test]
76 fn empty_iter_is_identity() {
77 let empty: [H; 0] = [];
78 assert_eq!(empty.iter().copied().sum::<H>(), H::from(0u8));
79 assert_eq!(empty.iter().copied().product::<H>(), H::from(1u8));
80 }
81
82 #[test]
85 fn product_preserves_operand_width_not_identity() {
86 let zeros = [H::new_zero_with_len(0)];
88 let p = zeros.iter().copied().product::<H>();
89 assert!(<H as const_num_traits::Zero>::is_zero(&p));
90 assert_eq!(p.len(), 0);
91
92 let mixed = [H::from(2u8), H::from(3u8).widened(8)];
94 assert_eq!(mixed.iter().copied().product::<H>().len(), 8);
95 }
96}