relp_num/rational/small/ops/
with_one.rs1use std::cmp::Ordering;
2use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
3
4use num_traits::Zero;
5
6use crate::{Rational128, Rational16, Rational32, Rational64, Rational8, Sign};
7use crate::one::One;
8
9macro_rules! impls {
10 ($name:ty) => {
11 impl From<One> for $name {
12 #[inline]
13 #[must_use]
14 fn from(_: One) -> Self {
15 num_traits::One::one()
16 }
17 }
18
19 impl From<&One> for $name {
20 #[inline]
21 #[must_use]
22 fn from(_: &One) -> Self {
23 num_traits::One::one()
24 }
25 }
26
27 impl Add<One> for $name {
28 type Output = Self;
29
30 #[inline]
31 #[must_use]
32 fn add(mut self, _: One) -> Self::Output {
33 AddAssign::add_assign(&mut self, One);
34 self
35 }
36 }
37
38 impl Add<&One> for $name {
39 type Output = Self;
40
41 #[inline]
42 #[must_use]
43 fn add(mut self, _: &One) -> Self::Output {
44 AddAssign::add_assign(&mut self, &One);
45 self
46 }
47 }
48
49 impl AddAssign<One> for $name {
50 #[inline]
51 fn add_assign(&mut self, _: One) {
52 AddAssign::add_assign(self, &One);
53 }
54 }
55
56 impl AddAssign<&One> for $name {
57 #[inline]
58 fn add_assign(&mut self, _: &One) {
59 match self.sign {
60 Sign::Positive => self.numerator += self.denominator,
61 Sign::Zero => {
62 self.sign = Sign::Positive;
63 debug_assert!(self.numerator.is_zero());
64 num_traits::One::set_one(&mut self.numerator);
65 debug_assert!(num_traits::One::is_one(&self.denominator));
66 }
67 Sign::Negative => {
68 if self.numerator != 1 || self.denominator != 1 {
69 match self.numerator.cmp(&self.denominator) {
70 Ordering::Less => {
71 self.numerator = self.denominator - self.numerator;
72 self.sign = Sign::Positive;
73 }
74 Ordering::Equal => panic!(),
75 Ordering::Greater => self.numerator -= self.denominator,
76 }
77 } else {
78 self.set_zero();
79 }
80 }
81 }
82 }
83 }
84
85 impl Sub<One> for $name {
86 type Output = Self;
87
88 #[must_use]
89 #[inline]
90 fn sub(mut self, _: One) -> Self::Output {
91 SubAssign::sub_assign(&mut self, One);
92 self
93 }
94 }
95
96 impl Sub<&One> for $name {
97 type Output = Self;
98
99 #[must_use]
100 #[inline]
101 fn sub(mut self, _: &One) -> Self::Output {
102 SubAssign::sub_assign(&mut self, One);
103 self
104 }
105 }
106
107 impl SubAssign<One> for $name {
108 #[inline]
109 fn sub_assign(&mut self, _: One) {
110 SubAssign::sub_assign(self, &One);
111 }
112 }
113
114 impl SubAssign<&One> for $name {
115 #[inline]
116 fn sub_assign(&mut self, _: &One) {
117 match self.sign {
118 Sign::Positive => {
119 if self.numerator != 1 || self.denominator != 1 {
120 match self.numerator.cmp(&self.denominator) {
121 Ordering::Less => {
122 self.numerator = self.denominator - self.numerator;
123 self.sign = Sign::Negative;
124 }
125 Ordering::Equal => panic!(),
126 Ordering::Greater => self.numerator -= self.denominator,
127 }
128 } else {
129 self.set_zero();
130 }
131 }
132 Sign::Zero => {
133 self.sign = Sign::Negative;
134 debug_assert_eq!(self.numerator, 0);
135 self.numerator = 1;
136 debug_assert_eq!(self.denominator, 1);
137 }
138 Sign::Negative => self.numerator += self.denominator,
139 }
140 }
141 }
142
143 impl Mul<One> for $name {
144 type Output = Self;
145
146 #[inline]
147 #[must_use]
148 fn mul(self, _: One) -> Self::Output {
149 self
150 }
151 }
152
153 impl Mul<&One> for $name {
154 type Output = Self;
155
156 #[inline]
157 #[must_use]
158 fn mul(self, _: &One) -> Self::Output {
159 self
160 }
161 }
162
163 impl Mul<&One> for &$name {
164 type Output = $name;
165
166 #[inline]
167 #[must_use]
168 fn mul(self, _: &One) -> Self::Output {
169 self.clone()
170 }
171 }
172
173 impl Mul<One> for &$name {
174 type Output = $name;
175
176 #[inline]
177 #[must_use]
178 fn mul(self, _: One) -> Self::Output {
179 self.clone()
180 }
181 }
182
183 impl MulAssign<One> for $name {
184 #[inline]
185 fn mul_assign(&mut self, _: One) {
186 MulAssign::mul_assign(self, &One);
187 }
188 }
189
190 impl MulAssign<&One> for $name {
191 #[inline]
192 fn mul_assign(&mut self, _: &One) {
193 }
194 }
195
196 impl Div<One> for $name {
197 type Output = Self;
198
199 #[inline]
200 #[must_use]
201 fn div(self, _: One) -> Self::Output {
202 self
203 }
204 }
205
206 impl Div<&One> for $name {
207 type Output = Self;
208
209 #[inline]
210 #[must_use]
211 fn div(self, _: &One) -> Self::Output {
212 self
213 }
214 }
215
216 impl Div<&One> for &$name {
217 type Output = $name;
218
219 #[inline]
220 #[must_use]
221 fn div(self, _: &One) -> Self::Output {
222 self.clone()
223 }
224 }
225
226 impl Div<One> for &$name {
227 type Output = $name;
228
229 #[inline]
230 #[must_use]
231 fn div(self, _: One) -> Self::Output {
232 self.clone()
233 }
234 }
235
236 impl DivAssign<One> for $name {
237 #[inline]
238 fn div_assign(&mut self, _: One) {
239 DivAssign::div_assign(self, &One);
240 }
241 }
242
243 impl DivAssign<&One> for $name {
244 #[inline]
245 fn div_assign(&mut self, _: &One) {
246 }
247 }
248 }
249}
250
251impls!(Rational8);
252impls!(Rational16);
253impls!(Rational32);
254impls!(Rational64);
255impls!(Rational128);
256
257#[cfg(test)]
258mod test {
259 use crate::{One, R8};
260
261 #[test]
262 fn test_add_sub() {
263 assert_eq!(R8!(1) + One, R8!(2));
264 assert_eq!(R8!(0) + One, R8!(1));
265 assert_eq!(R8!(0) - One, R8!(-1));
266 assert_eq!(R8!(1) - One, R8!(0));
267 assert_eq!(R8!(1, 2) - One, R8!(-1, 2));
268 assert_eq!(R8!(-1, 2) + One, R8!(1, 2));
269 assert_eq!(R8!(-1, 2) - One, R8!(-3, 2));
270
271 assert_eq!(R8!(1) * &One, R8!(1));
272 assert_eq!(R8!(1) / &One, R8!(1));
273 }
274}