1use std::ops::{Add, AddAssign, Mul};
2
3use crate::big_int::BigInt;
4
5use super::types::{Fraction, NormalizeModuli};
6
7impl<Digit, const DIGIT_BITNESS: usize> AddAssign
8 for Fraction<BigInt<Digit, DIGIT_BITNESS>>
9where
10 for<'a> BigInt<Digit, DIGIT_BITNESS>: Add<Output = BigInt<Digit, DIGIT_BITNESS>>
11 + NormalizeModuli<
12 Output = (
13 BigInt<Digit, DIGIT_BITNESS>,
14 BigInt<Digit, DIGIT_BITNESS>,
15 ),
16 >,
17 for<'a> &'a BigInt<Digit, DIGIT_BITNESS>: Mul<Output = BigInt<Digit, DIGIT_BITNESS>>
18 + Mul<
19 BigInt<Digit, DIGIT_BITNESS>,
20 Output = BigInt<Digit, DIGIT_BITNESS>,
21 >,
22{
23 fn add_assign(&mut self, other: Self) {
24 (self.numerator, self.denominator) = (&self.numerator
25 * &other.denominator
26 + &self.denominator * other.numerator)
27 .normalize_moduli(&self.denominator * other.denominator);
28 }
29}
30
31impl<Digit, const DIGIT_BITNESS: usize> AddAssign<&Self>
32 for Fraction<BigInt<Digit, DIGIT_BITNESS>>
33where
34 for<'a> BigInt<Digit, DIGIT_BITNESS>: Add<Output = BigInt<Digit, DIGIT_BITNESS>>
35 + NormalizeModuli<
36 Output = (
37 BigInt<Digit, DIGIT_BITNESS>,
38 BigInt<Digit, DIGIT_BITNESS>,
39 ),
40 >,
41 for<'a> &'a BigInt<Digit, DIGIT_BITNESS>:
42 Mul<Output = BigInt<Digit, DIGIT_BITNESS>>,
43{
44 fn add_assign(&mut self, other: &Self) {
45 (self.numerator, self.denominator) = (&self.numerator
46 * &other.denominator
47 + &self.denominator * &other.numerator)
48 .normalize_moduli(&self.denominator * &other.denominator);
49 }
50}
51
52impl<Digit, const DIGIT_BITNESS: usize> AddAssign<BigInt<Digit, DIGIT_BITNESS>>
53 for Fraction<BigInt<Digit, DIGIT_BITNESS>>
54where
55 for<'a> BigInt<Digit, DIGIT_BITNESS>: NormalizeModuli<
56 &'a BigInt<Digit, DIGIT_BITNESS>,
57 Output = (BigInt<Digit, DIGIT_BITNESS>, BigInt<Digit, DIGIT_BITNESS>),
58 >,
59 for<'a> &'a BigInt<Digit, DIGIT_BITNESS>: Add<
60 BigInt<Digit, DIGIT_BITNESS>,
61 Output = BigInt<Digit, DIGIT_BITNESS>,
62 > + Mul<
63 BigInt<Digit, DIGIT_BITNESS>,
64 Output = BigInt<Digit, DIGIT_BITNESS>,
65 >,
66{
67 fn add_assign(&mut self, other: BigInt<Digit, DIGIT_BITNESS>) {
68 (self.numerator, self.denominator) = (&self.numerator
69 + &self.denominator * other)
70 .normalize_moduli(&self.denominator);
71 }
72}
73
74impl<Digit, const DIGIT_BITNESS: usize>
75 AddAssign<&BigInt<Digit, DIGIT_BITNESS>>
76 for Fraction<BigInt<Digit, DIGIT_BITNESS>>
77where
78 for<'a> BigInt<Digit, DIGIT_BITNESS>: NormalizeModuli<
79 &'a BigInt<Digit, DIGIT_BITNESS>,
80 Output = (BigInt<Digit, DIGIT_BITNESS>, BigInt<Digit, DIGIT_BITNESS>),
81 >,
82 for<'a> &'a BigInt<Digit, DIGIT_BITNESS>: Add<
83 BigInt<Digit, DIGIT_BITNESS>,
84 Output = BigInt<Digit, DIGIT_BITNESS>,
85 > + Mul<Output = BigInt<Digit, DIGIT_BITNESS>>,
86{
87 fn add_assign(&mut self, other: &BigInt<Digit, DIGIT_BITNESS>) {
88 (self.numerator, self.denominator) = (&self.numerator
89 + &self.denominator * other)
90 .normalize_moduli(&self.denominator);
91 }
92}
93
94macro_rules! integer_fraction_add_assign_impl {
95 ($($integer:ty)*) => ($(
96 impl AddAssign for Fraction<$integer> {
97 fn add_assign(&mut self, other: Self) {
98 (self.numerator, self.denominator) = (self.numerator
99 * other.denominator
100 + self.denominator * other.numerator)
101 .normalize_moduli(self.denominator * other.denominator);
102 }
103 }
104
105 impl AddAssign<$integer> for Fraction<$integer> {
106 fn add_assign(&mut self, other: $integer) {
107 (self.numerator, self.denominator) = (self.numerator
108 + self.denominator * other)
109 .normalize_moduli(self.denominator);
110 }
111 }
112 )*)
113}
114
115integer_fraction_add_assign_impl!(
116 i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize
117);