Skip to content

Commit 1a15987

Browse files
committed
Reorganize and expand impl_ops_add.rs
1 parent 6eeb387 commit 1a15987

File tree

1 file changed

+177
-31
lines changed

1 file changed

+177
-31
lines changed

src/impl_ops_add.rs

+177-31
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ impl Add<BigDecimal> for BigDecimal {
99

1010
#[inline]
1111
fn add(self, rhs: BigDecimal) -> BigDecimal {
12-
let mut lhs = self;
12+
if rhs.is_zero() {
13+
return self;
14+
}
15+
if self.is_zero() {
16+
return rhs;
17+
}
1318

19+
let mut lhs = self;
1420
match lhs.scale.cmp(&rhs.scale) {
1521
Ordering::Equal => {
1622
lhs.int_val += rhs.int_val;
@@ -31,35 +37,41 @@ impl<'a, T: Into<BigDecimalRef<'a>>> Add<T> for BigDecimal {
3137
}
3238
}
3339

34-
impl Add<BigDecimal> for &'_ BigDecimal {
40+
impl Add<BigInt> for BigDecimal {
3541
type Output = BigDecimal;
3642

3743
#[inline]
38-
fn add(self, rhs: BigDecimal) -> BigDecimal {
39-
rhs + self
44+
fn add(self, rhs: BigInt) -> BigDecimal {
45+
self + BigDecimal::from(rhs)
4046
}
4147
}
4248

43-
impl<'a> Add<&'a BigDecimal> for &'_ BigDecimal {
49+
50+
51+
impl Add<BigDecimal> for &'_ BigDecimal {
4452
type Output = BigDecimal;
4553

4654
#[inline]
47-
fn add(self, rhs: &BigDecimal) -> BigDecimal {
48-
let lhs = self;
49-
match self.scale.cmp(&rhs.scale) {
50-
Ordering::Less => lhs.with_scale(rhs.scale) + rhs,
51-
Ordering::Greater => rhs.with_scale(lhs.scale) + lhs,
52-
Ordering::Equal => BigDecimal::new(lhs.int_val.clone() + &rhs.int_val, lhs.scale),
53-
}
55+
fn add(self, rhs: BigDecimal) -> BigDecimal {
56+
rhs + self
5457
}
5558
}
5659

57-
impl Add<BigInt> for BigDecimal {
60+
impl<'a, T: Into<BigDecimalRef<'a>>> Add<T> for &'_ BigDecimal {
5861
type Output = BigDecimal;
59-
60-
#[inline]
61-
fn add(self, rhs: BigInt) -> BigDecimal {
62-
self + BigDecimal::from(rhs)
62+
fn add(self, rhs: T) -> BigDecimal {
63+
let rhs = rhs.into();
64+
if rhs.is_zero() {
65+
return self.clone();
66+
}
67+
if self.is_zero() {
68+
return rhs.to_owned();
69+
}
70+
if self.scale >= rhs.scale {
71+
self.to_owned() + rhs
72+
} else {
73+
rhs.to_owned() + self
74+
}
6375
}
6476
}
6577

@@ -72,12 +84,13 @@ impl Add<BigInt> for &'_ BigDecimal {
7284
}
7385
}
7486

75-
impl<'a> Add<&'a BigInt> for &'_ BigDecimal {
87+
88+
impl Add<BigDecimal> for BigDecimalRef<'_> {
7689
type Output = BigDecimal;
7790

7891
#[inline]
79-
fn add(self, rhs: &BigInt) -> BigDecimal {
80-
self.to_ref() + rhs
92+
fn add(self, rhs: BigDecimal) -> BigDecimal {
93+
rhs + self
8194
}
8295
}
8396

@@ -102,7 +115,34 @@ impl Add<BigInt> for BigDecimalRef<'_> {
102115
}
103116
}
104117

105-
impl Add<BigDecimal> for BigDecimalRef<'_> {
118+
119+
impl Add<BigDecimal> for BigInt {
120+
type Output = BigDecimal;
121+
122+
#[inline]
123+
fn add(self, rhs: BigDecimal) -> BigDecimal {
124+
rhs + self
125+
}
126+
}
127+
128+
impl<'a> Add<&'a BigDecimal> for BigInt {
129+
type Output = BigDecimal;
130+
131+
fn add(self, rhs: &BigDecimal) -> BigDecimal {
132+
rhs.to_ref().add(self)
133+
}
134+
}
135+
136+
impl<'a> Add<BigDecimalRef<'a>> for BigInt {
137+
type Output = BigDecimal;
138+
139+
fn add(self, rhs: BigDecimalRef<'_>) -> BigDecimal {
140+
rhs.add(self)
141+
}
142+
}
143+
144+
145+
impl Add<BigDecimal> for &BigInt {
106146
type Output = BigDecimal;
107147

108148
#[inline]
@@ -111,7 +151,37 @@ impl Add<BigDecimal> for BigDecimalRef<'_> {
111151
}
112152
}
113153

114-
forward_val_assignop!(impl AddAssign for BigDecimal, add_assign);
154+
impl<'a> Add<&'a BigDecimal> for &BigInt {
155+
type Output = BigDecimal;
156+
157+
#[inline]
158+
fn add(self, rhs: &BigDecimal) -> BigDecimal {
159+
rhs + self
160+
}
161+
}
162+
163+
impl<'a> Add<BigDecimalRef<'a>> for &BigInt {
164+
type Output = BigDecimal;
165+
166+
#[inline]
167+
fn add(self, rhs: BigDecimalRef<'_>) -> BigDecimal {
168+
rhs + self
169+
}
170+
}
171+
172+
173+
impl AddAssign<BigDecimal> for BigDecimal {
174+
fn add_assign(&mut self, rhs: BigDecimal) {
175+
if rhs.is_zero() {
176+
return;
177+
}
178+
if self.is_zero() {
179+
*self = rhs;
180+
return;
181+
}
182+
self.add_assign(rhs.to_ref());
183+
}
184+
}
115185

116186
impl<'a, N: Into<BigDecimalRef<'a>>> AddAssign<N> for BigDecimal {
117187
#[inline]
@@ -157,21 +227,92 @@ mod test {
157227
use paste::paste;
158228

159229
macro_rules! impl_case {
160-
($name:ident: $a:literal + $b:literal => $c:literal ) => {
230+
( $name:ident: $a:literal + $b:literal => $c:literal ) => {
161231
#[test]
162232
fn $name() {
163-
let mut a: BigDecimal = $a.parse().unwrap();
233+
let a: BigDecimal = $a.parse().unwrap();
164234
let b: BigDecimal = $b.parse().unwrap();
165235
let c: BigDecimal = $c.parse().unwrap();
166236

167-
assert_eq!(a.clone() + b.clone(), c);
237+
assert_eq!(c, a.clone() + b.clone());
238+
assert_eq!(c, a.clone() + b.to_ref());
239+
assert_eq!(c, a.clone() + &b);
240+
241+
assert_eq!(c, &a + b.clone());
242+
assert_eq!(c, &a + b.to_ref());
243+
assert_eq!(c, &a + &b);
244+
245+
assert_eq!(c, a.to_ref() + b.clone());
246+
assert_eq!(c, a.to_ref() + b.to_ref());
247+
assert_eq!(c, a.to_ref() + &b);
248+
249+
// Reversed
250+
251+
assert_eq!(c, b.clone() + a.clone());
252+
assert_eq!(c, b.clone() + a.to_ref());
253+
assert_eq!(c, b.clone() + &a);
254+
255+
assert_eq!(c, &b + a.clone());
256+
assert_eq!(c, &b + a.to_ref());
257+
assert_eq!(c, &b + &a);
258+
259+
assert_eq!(c, b.to_ref() + a.clone());
260+
assert_eq!(c, b.to_ref() + a.to_ref());
261+
assert_eq!(c, b.to_ref() + &a);
262+
263+
let mut n = a.clone();
264+
n += b.clone();
265+
assert_eq!(c, n);
266+
267+
let mut n = a.clone();
268+
n += &b;
269+
assert_eq!(c, n);
270+
271+
let mut n = a.clone();
272+
n += b.to_ref();
273+
assert_eq!(c, n);
168274

169-
assert_eq!(a.clone() + &b, c);
170-
assert_eq!(&a + b.clone(), c);
171-
assert_eq!(&a + &b, c);
275+
let mut n = b.clone();
276+
n += a.clone();
277+
assert_eq!(c, n);
172278

173-
a += b;
174-
assert_eq!(a, c);
279+
let mut n = b.clone();
280+
n += &a;
281+
assert_eq!(c, n);
282+
283+
let mut n = b.clone();
284+
n += a.to_ref();
285+
assert_eq!(c, n);
286+
}
287+
};
288+
( $name:ident: $a:literal + (int) $b:literal => $c:literal ) => {
289+
#[test]
290+
fn $name() {
291+
let a: BigDecimal = $a.parse().unwrap();
292+
let b: BigInt = $b.parse().unwrap();
293+
let c: BigDecimal = $c.parse().unwrap();
294+
295+
assert_eq!(c, a.clone() + b.clone());
296+
assert_eq!(c, a.clone() + &b);
297+
assert_eq!(c, &a + &b);
298+
assert_eq!(c, &a + b.clone());
299+
assert_eq!(c, a.to_ref() + &b);
300+
301+
assert_eq!(c, b.clone() + a.clone());
302+
assert_eq!(c, b.clone() + a.to_ref());
303+
assert_eq!(c, b.clone() + &a);
304+
305+
assert_eq!(c, &b + a.clone());
306+
assert_eq!(c, &b + a.to_ref());
307+
assert_eq!(c, &b + &a);
308+
309+
let mut n = a.clone();
310+
n += b.clone();
311+
assert_eq!(c, n);
312+
313+
let mut n = a.clone();
314+
n += &b;
315+
assert_eq!(c, n);
175316
}
176317
};
177318
}
@@ -182,7 +323,12 @@ mod test {
182323
impl_case!(case_1234e6_1234en6: "1234e6" + "1234e-6" => "1234000000.001234");
183324
impl_case!(case_1234en6_1234e6: "1234e6" + "1234e-6" => "1234000000.001234");
184325
impl_case!(case_18446744073709551616_1: "18446744073709551616.0" + "1" => "18446744073709551617");
185-
impl_case!(case_184467440737e3380_1: "184467440737e3380" + "0" => "184467440737e3380");
326+
impl_case!(case_184467440737e3380_0: "184467440737e3380" + "0" => "184467440737e3380");
327+
impl_case!(case_0_776en1: "0" + "77.6" => "77.6");
328+
329+
impl_case!(case_80802295e5_int0: "80802295e5" + (int)"0" => "80802295e5");
330+
impl_case!(case_239200en4_intneg101: "23.9200" + (int)"-101" => "-77.0800");
331+
impl_case!(case_46636423395767125en15_int0: "46.636423395767125" + (int)"123" => "169.636423395767125");
186332

187333

188334
#[cfg(property_tests)]

0 commit comments

Comments
 (0)