Skip to content

Commit 72810a5

Browse files
bors[bot]cuviper
andauthored
Merge #193
193: Split into more modules r=cuviper a=cuviper There should be no functional change in this. Co-authored-by: Josh Stone <[email protected]>
2 parents d9287a4 + a6e88c5 commit 72810a5

25 files changed

+6198
-6021
lines changed

src/algorithms.rs

Lines changed: 0 additions & 936 deletions
This file was deleted.

src/bigint.rs

Lines changed: 70 additions & 2450 deletions
Large diffs are not rendered by default.

src/bigint/addition.rs

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
use super::CheckedUnsignedAbs::{Negative, Positive};
2+
use super::Sign::{Minus, NoSign, Plus};
3+
use super::{BigInt, UnsignedAbs};
4+
5+
use crate::{IsizePromotion, UsizePromotion};
6+
7+
use core::cmp::Ordering::{Equal, Greater, Less};
8+
use core::iter::Sum;
9+
use core::mem;
10+
use core::ops::{Add, AddAssign};
11+
use num_traits::{CheckedAdd, Zero};
12+
13+
// We want to forward to BigUint::add, but it's not clear how that will go until
14+
// we compare both sign and magnitude. So we duplicate this body for every
15+
// val/ref combination, deferring that decision to BigUint's own forwarding.
16+
macro_rules! bigint_add {
17+
($a:expr, $a_owned:expr, $a_data:expr, $b:expr, $b_owned:expr, $b_data:expr) => {
18+
match ($a.sign, $b.sign) {
19+
(_, NoSign) => $a_owned,
20+
(NoSign, _) => $b_owned,
21+
// same sign => keep the sign with the sum of magnitudes
22+
(Plus, Plus) | (Minus, Minus) => BigInt::from_biguint($a.sign, $a_data + $b_data),
23+
// opposite signs => keep the sign of the larger with the difference of magnitudes
24+
(Plus, Minus) | (Minus, Plus) => match $a.data.cmp(&$b.data) {
25+
Less => BigInt::from_biguint($b.sign, $b_data - $a_data),
26+
Greater => BigInt::from_biguint($a.sign, $a_data - $b_data),
27+
Equal => Zero::zero(),
28+
},
29+
}
30+
};
31+
}
32+
33+
impl<'a, 'b> Add<&'b BigInt> for &'a BigInt {
34+
type Output = BigInt;
35+
36+
#[inline]
37+
fn add(self, other: &BigInt) -> BigInt {
38+
bigint_add!(
39+
self,
40+
self.clone(),
41+
&self.data,
42+
other,
43+
other.clone(),
44+
&other.data
45+
)
46+
}
47+
}
48+
49+
impl<'a> Add<BigInt> for &'a BigInt {
50+
type Output = BigInt;
51+
52+
#[inline]
53+
fn add(self, other: BigInt) -> BigInt {
54+
bigint_add!(self, self.clone(), &self.data, other, other, other.data)
55+
}
56+
}
57+
58+
impl<'a> Add<&'a BigInt> for BigInt {
59+
type Output = BigInt;
60+
61+
#[inline]
62+
fn add(self, other: &BigInt) -> BigInt {
63+
bigint_add!(self, self, self.data, other, other.clone(), &other.data)
64+
}
65+
}
66+
67+
impl Add<BigInt> for BigInt {
68+
type Output = BigInt;
69+
70+
#[inline]
71+
fn add(self, other: BigInt) -> BigInt {
72+
bigint_add!(self, self, self.data, other, other, other.data)
73+
}
74+
}
75+
76+
impl<'a> AddAssign<&'a BigInt> for BigInt {
77+
#[inline]
78+
fn add_assign(&mut self, other: &BigInt) {
79+
let n = mem::replace(self, BigInt::zero());
80+
*self = n + other;
81+
}
82+
}
83+
forward_val_assign!(impl AddAssign for BigInt, add_assign);
84+
85+
promote_all_scalars!(impl Add for BigInt, add);
86+
promote_all_scalars_assign!(impl AddAssign for BigInt, add_assign);
87+
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u32> for BigInt, add);
88+
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u64> for BigInt, add);
89+
forward_all_scalar_binop_to_val_val_commutative!(impl Add<u128> for BigInt, add);
90+
91+
impl Add<u32> for BigInt {
92+
type Output = BigInt;
93+
94+
#[inline]
95+
fn add(self, other: u32) -> BigInt {
96+
match self.sign {
97+
NoSign => From::from(other),
98+
Plus => BigInt::from(self.data + other),
99+
Minus => match self.data.cmp(&From::from(other)) {
100+
Equal => Zero::zero(),
101+
Less => BigInt::from(other - self.data),
102+
Greater => -BigInt::from(self.data - other),
103+
},
104+
}
105+
}
106+
}
107+
108+
impl AddAssign<u32> for BigInt {
109+
#[inline]
110+
fn add_assign(&mut self, other: u32) {
111+
let n = mem::replace(self, BigInt::zero());
112+
*self = n + other;
113+
}
114+
}
115+
116+
impl Add<u64> for BigInt {
117+
type Output = BigInt;
118+
119+
#[inline]
120+
fn add(self, other: u64) -> BigInt {
121+
match self.sign {
122+
NoSign => From::from(other),
123+
Plus => BigInt::from(self.data + other),
124+
Minus => match self.data.cmp(&From::from(other)) {
125+
Equal => Zero::zero(),
126+
Less => BigInt::from(other - self.data),
127+
Greater => -BigInt::from(self.data - other),
128+
},
129+
}
130+
}
131+
}
132+
133+
impl AddAssign<u64> for BigInt {
134+
#[inline]
135+
fn add_assign(&mut self, other: u64) {
136+
let n = mem::replace(self, BigInt::zero());
137+
*self = n + other;
138+
}
139+
}
140+
141+
impl Add<u128> for BigInt {
142+
type Output = BigInt;
143+
144+
#[inline]
145+
fn add(self, other: u128) -> BigInt {
146+
match self.sign {
147+
NoSign => BigInt::from(other),
148+
Plus => BigInt::from(self.data + other),
149+
Minus => match self.data.cmp(&From::from(other)) {
150+
Equal => BigInt::zero(),
151+
Less => BigInt::from(other - self.data),
152+
Greater => -BigInt::from(self.data - other),
153+
},
154+
}
155+
}
156+
}
157+
impl AddAssign<u128> for BigInt {
158+
#[inline]
159+
fn add_assign(&mut self, other: u128) {
160+
let n = mem::replace(self, BigInt::zero());
161+
*self = n + other;
162+
}
163+
}
164+
165+
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i32> for BigInt, add);
166+
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i64> for BigInt, add);
167+
forward_all_scalar_binop_to_val_val_commutative!(impl Add<i128> for BigInt, add);
168+
169+
impl Add<i32> for BigInt {
170+
type Output = BigInt;
171+
172+
#[inline]
173+
fn add(self, other: i32) -> BigInt {
174+
match other.checked_uabs() {
175+
Positive(u) => self + u,
176+
Negative(u) => self - u,
177+
}
178+
}
179+
}
180+
impl AddAssign<i32> for BigInt {
181+
#[inline]
182+
fn add_assign(&mut self, other: i32) {
183+
match other.checked_uabs() {
184+
Positive(u) => *self += u,
185+
Negative(u) => *self -= u,
186+
}
187+
}
188+
}
189+
190+
impl Add<i64> for BigInt {
191+
type Output = BigInt;
192+
193+
#[inline]
194+
fn add(self, other: i64) -> BigInt {
195+
match other.checked_uabs() {
196+
Positive(u) => self + u,
197+
Negative(u) => self - u,
198+
}
199+
}
200+
}
201+
impl AddAssign<i64> for BigInt {
202+
#[inline]
203+
fn add_assign(&mut self, other: i64) {
204+
match other.checked_uabs() {
205+
Positive(u) => *self += u,
206+
Negative(u) => *self -= u,
207+
}
208+
}
209+
}
210+
211+
impl Add<i128> for BigInt {
212+
type Output = BigInt;
213+
214+
#[inline]
215+
fn add(self, other: i128) -> BigInt {
216+
match other.checked_uabs() {
217+
Positive(u) => self + u,
218+
Negative(u) => self - u,
219+
}
220+
}
221+
}
222+
impl AddAssign<i128> for BigInt {
223+
#[inline]
224+
fn add_assign(&mut self, other: i128) {
225+
match other.checked_uabs() {
226+
Positive(u) => *self += u,
227+
Negative(u) => *self -= u,
228+
}
229+
}
230+
}
231+
232+
impl CheckedAdd for BigInt {
233+
#[inline]
234+
fn checked_add(&self, v: &BigInt) -> Option<BigInt> {
235+
Some(self.add(v))
236+
}
237+
}
238+
239+
impl_sum_iter_type!(BigInt);

src/bigint/arbitrary.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use super::{BigInt, Sign};
2+
3+
use crate::std_alloc::Box;
4+
use crate::BigUint;
5+
6+
#[cfg(feature = "quickcheck")]
7+
impl quickcheck::Arbitrary for BigInt {
8+
fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self {
9+
let positive = bool::arbitrary(g);
10+
let sign = if positive { Sign::Plus } else { Sign::Minus };
11+
Self::from_biguint(sign, BigUint::arbitrary(g))
12+
}
13+
14+
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
15+
let sign = self.sign();
16+
let unsigned_shrink = self.data.shrink();
17+
Box::new(unsigned_shrink.map(move |x| BigInt::from_biguint(sign, x)))
18+
}
19+
}
20+
21+
#[cfg(feature = "arbitrary")]
22+
impl arbitrary::Arbitrary for BigInt {
23+
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
24+
let positive = bool::arbitrary(u)?;
25+
let sign = if positive { Sign::Plus } else { Sign::Minus };
26+
Ok(Self::from_biguint(sign, BigUint::arbitrary(u)?))
27+
}
28+
29+
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
30+
let sign = self.sign();
31+
let unsigned_shrink = self.data.shrink();
32+
Box::new(unsigned_shrink.map(move |x| BigInt::from_biguint(sign, x)))
33+
}
34+
}

0 commit comments

Comments
 (0)