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