Merge pull request #40 from gifnksm/master

update to latest rustc
This commit is contained in:
Alex Crichton 2014-12-16 10:37:52 -05:00
commit 9428f0f100
7 changed files with 414 additions and 206 deletions

View File

@ -70,24 +70,24 @@ impl Context {
fn extract_digit(&self) -> int { fn extract_digit(&self) -> int {
if self.numer > self.accum {return -1;} if self.numer > self.accum {return -1;}
let (q, r) = let (q, r) =
(self.numer * Context::from_int(3) + self.accum) (&self.numer * Context::from_int(3) + &self.accum)
.div_rem(&self.denom); .div_rem(&self.denom);
if r + self.numer >= self.denom {return -1;} if r + &self.numer >= self.denom {return -1;}
q.to_int().unwrap() q.to_int().unwrap()
} }
fn next_term(&mut self, k: int) { fn next_term(&mut self, k: int) {
let y2 = Context::from_int(k * 2 + 1); let y2 = Context::from_int(k * 2 + 1);
self.accum = (self.accum + (self.numer << 1)) * y2; self.accum = (&self.accum + (&self.numer << 1)) * &y2;
self.numer = self.numer * Context::from_int(k); self.numer = &self.numer * Context::from_int(k);
self.denom = self.denom * y2; self.denom = &self.denom * y2;
} }
fn eliminate_digit(&mut self, d: int) { fn eliminate_digit(&mut self, d: int) {
let d = Context::from_int(d); let d = Context::from_int(d);
let ten = Context::from_int(10); let ten = Context::from_int(10);
self.accum = (self.accum - self.denom * d) * ten; self.accum = (&self.accum - &self.denom * d) * &ten;
self.numer = self.numer * ten; self.numer = &self.numer * ten;
} }
} }

View File

@ -27,7 +27,7 @@
//! let mut f0: BigUint = Zero::zero(); //! let mut f0: BigUint = Zero::zero();
//! let mut f1: BigUint = One::one(); //! let mut f1: BigUint = One::one();
//! for _ in range(0, n) { //! for _ in range(0, n) {
//! let f2 = f0 + f1; //! let f2 = f0 + &f1;
//! // This is a low cost way of swapping f0 with f1 and f1 with f2. //! // This is a low cost way of swapping f0 with f1 and f1 with f2.
//! f0 = replace(&mut f1, f2); //! f0 = replace(&mut f1, f2);
//! } //! }
@ -183,14 +183,60 @@ impl FromStr for BigUint {
impl Num for BigUint {} impl Num for BigUint {}
impl BitAnd<BigUint, BigUint> for BigUint { macro_rules! forward_val_val_binop {
fn bitand(&self, other: &BigUint) -> BigUint { (impl $imp:ident for $res:ty, $method:ident) => {
impl $imp<$res, $res> for $res {
#[inline]
fn $method(self, other: $res) -> $res {
(&self).$method(&other)
}
}
}
}
macro_rules! forward_ref_val_binop {
(impl $imp:ident for $res:ty, $method:ident) => {
impl<'a> $imp<$res, $res> for &'a $res {
#[inline]
fn $method(self, other: $res) -> $res {
self.$method(&other)
}
}
}
}
macro_rules! forward_val_ref_binop {
(impl $imp:ident for $res:ty, $method:ident) => {
impl<'a> $imp<&'a $res, $res> for $res {
#[inline]
fn $method(self, other: &$res) -> $res {
(&self).$method(other)
}
}
}
}
macro_rules! forward_all_binop {
(impl $imp:ident for $res:ty, $method:ident) => {
forward_val_val_binop!(impl $imp for $res, $method)
forward_ref_val_binop!(impl $imp for $res, $method)
forward_val_ref_binop!(impl $imp for $res, $method)
};
}
forward_all_binop!(impl BitAnd for BigUint, bitand)
impl<'a, 'b> BitAnd<&'b BigUint, BigUint> for &'a BigUint {
#[inline]
fn bitand(self, other: &BigUint) -> BigUint {
BigUint::new(self.data.iter().zip(other.data.iter()).map(|(ai, bi)| *ai & *bi).collect()) BigUint::new(self.data.iter().zip(other.data.iter()).map(|(ai, bi)| *ai & *bi).collect())
} }
} }
impl BitOr<BigUint, BigUint> for BigUint { forward_all_binop!(impl BitOr for BigUint, bitor)
fn bitor(&self, other: &BigUint) -> BigUint {
impl<'a, 'b> BitOr<&'b BigUint, BigUint> for &'a BigUint {
fn bitor(self, other: &BigUint) -> BigUint {
let zeros = ZERO_VEC.iter().cycle(); let zeros = ZERO_VEC.iter().cycle();
let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) }; let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
let ored = a.data.iter().zip(b.data.iter().chain(zeros)).map( let ored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
@ -200,8 +246,10 @@ impl BitOr<BigUint, BigUint> for BigUint {
} }
} }
impl BitXor<BigUint, BigUint> for BigUint { forward_all_binop!(impl BitXor for BigUint, bitxor)
fn bitxor(&self, other: &BigUint) -> BigUint {
impl<'a, 'b> BitXor<&'b BigUint, BigUint> for &'a BigUint {
fn bitxor(self, other: &BigUint) -> BigUint {
let zeros = ZERO_VEC.iter().cycle(); let zeros = ZERO_VEC.iter().cycle();
let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) }; let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
let xored = a.data.iter().zip(b.data.iter().chain(zeros)).map( let xored = a.data.iter().zip(b.data.iter().chain(zeros)).map(
@ -213,18 +261,28 @@ impl BitXor<BigUint, BigUint> for BigUint {
impl Shl<uint, BigUint> for BigUint { impl Shl<uint, BigUint> for BigUint {
#[inline] #[inline]
fn shl(&self, rhs: &uint) -> BigUint { fn shl(self, rhs: uint) -> BigUint { (&self) << rhs }
let n_unit = *rhs / BigDigit::BITS; }
let n_bits = *rhs % BigDigit::BITS;
impl<'a> Shl<uint, BigUint> for &'a BigUint {
#[inline]
fn shl(self, rhs: uint) -> BigUint {
let n_unit = rhs / BigDigit::BITS;
let n_bits = rhs % BigDigit::BITS;
return self.shl_unit(n_unit).shl_bits(n_bits); return self.shl_unit(n_unit).shl_bits(n_bits);
} }
} }
impl Shr<uint, BigUint> for BigUint { impl Shr<uint, BigUint> for BigUint {
#[inline] #[inline]
fn shr(&self, rhs: &uint) -> BigUint { fn shr(self, rhs: uint) -> BigUint { (&self) >> rhs }
let n_unit = *rhs / BigDigit::BITS; }
let n_bits = *rhs % BigDigit::BITS;
impl<'a> Shr<uint, BigUint> for &'a BigUint {
#[inline]
fn shr(self, rhs: uint) -> BigUint {
let n_unit = rhs / BigDigit::BITS;
let n_bits = rhs % BigDigit::BITS;
return self.shr_unit(n_unit).shr_bits(n_bits); return self.shr_unit(n_unit).shr_bits(n_bits);
} }
} }
@ -244,8 +302,10 @@ impl One for BigUint {
impl Unsigned for BigUint {} impl Unsigned for BigUint {}
impl Add<BigUint, BigUint> for BigUint { forward_all_binop!(impl Add for BigUint, add)
fn add(&self, other: &BigUint) -> BigUint {
impl<'a, 'b> Add<&'b BigUint, BigUint> for &'a BigUint {
fn add(self, other: &BigUint) -> BigUint {
let zeros = ZERO_VEC.iter().cycle(); let zeros = ZERO_VEC.iter().cycle();
let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) }; let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) };
@ -261,8 +321,10 @@ impl Add<BigUint, BigUint> for BigUint {
} }
} }
impl Sub<BigUint, BigUint> for BigUint { forward_all_binop!(impl Sub for BigUint, sub)
fn sub(&self, other: &BigUint) -> BigUint {
impl<'a, 'b> Sub<&'b BigUint, BigUint> for &'a BigUint {
fn sub(self, other: &BigUint) -> BigUint {
let new_len = cmp::max(self.data.len(), other.data.len()); let new_len = cmp::max(self.data.len(), other.data.len());
let zeros = ZERO_VEC.iter().cycle(); let zeros = ZERO_VEC.iter().cycle();
let (a, b) = (self.data.iter().chain(zeros.clone()), other.data.iter().chain(zeros)); let (a, b) = (self.data.iter().chain(zeros.clone()), other.data.iter().chain(zeros));
@ -289,8 +351,11 @@ impl Sub<BigUint, BigUint> for BigUint {
} }
} }
impl Mul<BigUint, BigUint> for BigUint {
fn mul(&self, other: &BigUint) -> BigUint { forward_all_binop!(impl Mul for BigUint, mul)
impl<'a, 'b> Mul<&'b BigUint, BigUint> for &'a BigUint {
fn mul(self, other: &BigUint) -> BigUint {
if self.is_zero() || other.is_zero() { return Zero::zero(); } if self.is_zero() || other.is_zero() { return Zero::zero(); }
let (s_len, o_len) = (self.data.len(), other.data.len()); let (s_len, o_len) = (self.data.len(), other.data.len());
@ -306,15 +371,15 @@ impl Mul<BigUint, BigUint> for BigUint {
let (s_hi, s_lo) = cut_at(self, half_len); let (s_hi, s_lo) = cut_at(self, half_len);
let (o_hi, o_lo) = cut_at(other, half_len); let (o_hi, o_lo) = cut_at(other, half_len);
let ll = s_lo * o_lo; let ll = &s_lo * &o_lo;
let hh = s_hi * o_hi; let hh = &s_hi * &o_hi;
let mm = { let mm = {
let (s1, n1) = sub_sign(s_hi, s_lo); let (s1, n1) = sub_sign(s_hi, s_lo);
let (s2, n2) = sub_sign(o_hi, o_lo); let (s2, n2) = sub_sign(o_hi, o_lo);
match (s1, s2) { match (s1, s2) {
(Equal, _) | (_, Equal) => hh + ll, (Equal, _) | (_, Equal) => &hh + &ll,
(Less, Greater) | (Greater, Less) => hh + ll + (n1 * n2), (Less, Greater) | (Greater, Less) => &hh + &ll + (n1 * n2),
(Less, Less) | (Greater, Greater) => hh + ll - (n1 * n2) (Less, Less) | (Greater, Greater) => &hh + &ll - (n1 * n2)
} }
}; };
@ -323,7 +388,7 @@ impl Mul<BigUint, BigUint> for BigUint {
fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint { fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint {
if n == 0 { return Zero::zero(); } if n == 0 { return Zero::zero(); }
if n == 1 { return (*a).clone(); } if n == 1 { return a.clone(); }
let mut carry = 0; let mut carry = 0;
let mut prod: Vec<BigDigit> = a.data.iter().map(|ai| { let mut prod: Vec<BigDigit> = a.data.iter().map(|ai| {
@ -355,17 +420,22 @@ impl Mul<BigUint, BigUint> for BigUint {
} }
} }
impl Div<BigUint, BigUint> for BigUint {
forward_all_binop!(impl Div for BigUint, div)
impl<'a, 'b> Div<&'b BigUint, BigUint> for &'a BigUint {
#[inline] #[inline]
fn div(&self, other: &BigUint) -> BigUint { fn div(self, other: &BigUint) -> BigUint {
let (q, _) = self.div_rem(other); let (q, _) = self.div_rem(other);
return q; return q;
} }
} }
impl Rem<BigUint, BigUint> for BigUint { forward_all_binop!(impl Rem for BigUint, rem)
impl<'a, 'b> Rem<&'b BigUint, BigUint> for &'a BigUint {
#[inline] #[inline]
fn rem(&self, other: &BigUint) -> BigUint { fn rem(self, other: &BigUint) -> BigUint {
let (_, r) = self.div_rem(other); let (_, r) = self.div_rem(other);
return r; return r;
} }
@ -446,7 +516,7 @@ impl Integer for BigUint {
shift += 1; shift += 1;
} }
assert!(shift < BigDigit::BITS); assert!(shift < BigDigit::BITS);
let (d, m) = div_mod_floor_inner(*self << shift, *other << shift); let (d, m) = div_mod_floor_inner(self << shift, other << shift);
return (d, m >> shift); return (d, m >> shift);
@ -457,14 +527,14 @@ impl Integer for BigUint {
while m >= b { while m >= b {
let (d0, d_unit, b_unit) = div_estimate(&m, &b, n); let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
let mut d0 = d0; let mut d0 = d0;
let mut prod = b * d0; let mut prod = &b * &d0;
while prod > m { while prod > m {
// FIXME(#5992): assignment operator overloads // FIXME(#5992): assignment operator overloads
// d0 -= d_unit // d0 -= &d_unit
d0 = d0 - d_unit; d0 = d0 - &d_unit;
// FIXME(#5992): assignment operator overloads // FIXME(#5992): assignment operator overloads
// prod -= b_unit; // prod -= &b_unit;
prod = prod - b_unit prod = prod - &b_unit
} }
if d0.is_zero() { if d0.is_zero() {
n = 2; n = 2;
@ -522,7 +592,7 @@ impl Integer for BigUint {
let mut n = (*other).clone(); let mut n = (*other).clone();
while !m.is_zero() { while !m.is_zero() {
let temp = m; let temp = m;
m = n % temp; m = n % &temp;
n = temp; n = temp;
} }
return n; return n;
@ -530,16 +600,16 @@ impl Integer for BigUint {
/// Calculates the Lowest Common Multiple (LCM) of the number and `other`. /// Calculates the Lowest Common Multiple (LCM) of the number and `other`.
#[inline] #[inline]
fn lcm(&self, other: &BigUint) -> BigUint { ((*self * *other) / self.gcd(other)) } fn lcm(&self, other: &BigUint) -> BigUint { ((self * other) / self.gcd(other)) }
/// Deprecated, use `is_multiple_of` instead. /// Deprecated, use `is_multiple_of` instead.
#[deprecated = "function renamed to `is_multiple_of`"] #[deprecated = "function renamed to `is_multiple_of`"]
#[inline] #[inline]
fn divides(&self, other: &BigUint) -> bool { return self.is_multiple_of(other); } fn divides(&self, other: &BigUint) -> bool { self.is_multiple_of(other) }
/// Returns `true` if the number is a multiple of `other`. /// Returns `true` if the number is a multiple of `other`.
#[inline] #[inline]
fn is_multiple_of(&self, other: &BigUint) -> bool { (*self % *other).is_zero() } fn is_multiple_of(&self, other: &BigUint) -> bool { (self % other).is_zero() }
/// Returns `true` if the number is divisible by `2`. /// Returns `true` if the number is divisible by `2`.
#[inline] #[inline]
@ -720,8 +790,8 @@ impl FromStrRadix for BigUint {
match d { match d {
Some(d) => { Some(d) => {
// FIXME(#5992): assignment operator overloads // FIXME(#5992): assignment operator overloads
// n += d * power; // n += d * &power;
n = n + d * power; n = n + d * &power;
} }
None => { return None; } None => { return None; }
} }
@ -733,8 +803,8 @@ impl FromStrRadix for BigUint {
} }
end -= unit_len; end -= unit_len;
// FIXME(#5992): assignment operator overloads // FIXME(#5992): assignment operator overloads
// power *= base_num; // power *= &base_num;
power = power * base_num; power = power * &base_num;
} }
} }
} }
@ -938,15 +1008,25 @@ impl Num for BigInt {}
impl Shl<uint, BigInt> for BigInt { impl Shl<uint, BigInt> for BigInt {
#[inline] #[inline]
fn shl(&self, rhs: &uint) -> BigInt { fn shl(self, rhs: uint) -> BigInt { (&self) << rhs }
BigInt::from_biguint(self.sign, self.data << *rhs) }
impl<'a> Shl<uint, BigInt> for &'a BigInt {
#[inline]
fn shl(self, rhs: uint) -> BigInt {
BigInt::from_biguint(self.sign, &self.data << rhs)
} }
} }
impl Shr<uint, BigInt> for BigInt { impl Shr<uint, BigInt> for BigInt {
#[inline] #[inline]
fn shr(&self, rhs: &uint) -> BigInt { fn shr(self, rhs: uint) -> BigInt { (&self) >> rhs }
BigInt::from_biguint(self.sign, self.data >> *rhs) }
impl<'a> Shr<uint, BigInt> for &'a BigInt {
#[inline]
fn shr(self, rhs: uint) -> BigInt {
BigInt::from_biguint(self.sign, &self.data >> rhs)
} }
} }
@ -978,7 +1058,7 @@ impl Signed for BigInt {
#[inline] #[inline]
fn abs_sub(&self, other: &BigInt) -> BigInt { fn abs_sub(&self, other: &BigInt) -> BigInt {
if *self <= *other { Zero::zero() } else { *self - *other } if *self <= *other { Zero::zero() } else { self - other }
} }
#[inline] #[inline]
@ -997,64 +1077,74 @@ impl Signed for BigInt {
fn is_negative(&self) -> bool { self.sign == Minus } fn is_negative(&self) -> bool { self.sign == Minus }
} }
impl Add<BigInt, BigInt> for BigInt { forward_all_binop!(impl Add for BigInt, add)
impl<'a, 'b> Add<&'b BigInt, BigInt> for &'a BigInt {
#[inline] #[inline]
fn add(&self, other: &BigInt) -> BigInt { fn add(self, other: &BigInt) -> BigInt {
match (self.sign, other.sign) { match (self.sign, other.sign) {
(NoSign, _) => other.clone(), (NoSign, _) => other.clone(),
(_, NoSign) => self.clone(), (_, NoSign) => self.clone(),
(Plus, Plus) => BigInt::from_biguint(Plus, self.data + other.data), (Plus, Plus) => BigInt::from_biguint(Plus, &self.data + &other.data),
(Plus, Minus) => *self - (-*other), (Plus, Minus) => self - (-*other),
(Minus, Plus) => *other - (-*self), (Minus, Plus) => other - (-*self),
(Minus, Minus) => -((-*self) + (-*other)) (Minus, Minus) => -((-*self) + (-*other))
} }
} }
} }
impl Sub<BigInt, BigInt> for BigInt { forward_all_binop!(impl Sub for BigInt, sub)
impl<'a, 'b> Sub<&'b BigInt, BigInt> for &'a BigInt {
#[inline] #[inline]
fn sub(&self, other: &BigInt) -> BigInt { fn sub(self, other: &BigInt) -> BigInt {
match (self.sign, other.sign) { match (self.sign, other.sign) {
(NoSign, _) => -*other, (NoSign, _) => -*other,
(_, NoSign) => self.clone(), (_, NoSign) => self.clone(),
(Plus, Plus) => match self.data.cmp(&other.data) { (Plus, Plus) => match self.data.cmp(&other.data) {
Less => BigInt::from_biguint(Minus, other.data - self.data), Less => BigInt::from_biguint(Minus, &other.data - &self.data),
Greater => BigInt::from_biguint(Plus, self.data - other.data), Greater => BigInt::from_biguint(Plus, &self.data - &other.data),
Equal => Zero::zero() Equal => Zero::zero()
}, },
(Plus, Minus) => *self + (-*other), (Plus, Minus) => self + (-*other),
(Minus, Plus) => -((-*self) + *other), (Minus, Plus) => -((-*self) + other),
(Minus, Minus) => (-*other) - (-*self) (Minus, Minus) => (-*other) - (-*self)
} }
} }
} }
impl Mul<BigInt, BigInt> for BigInt { forward_all_binop!(impl Mul for BigInt, mul)
impl<'a, 'b> Mul<&'b BigInt, BigInt> for &'a BigInt {
#[inline] #[inline]
fn mul(&self, other: &BigInt) -> BigInt { fn mul(self, other: &BigInt) -> BigInt {
match (self.sign, other.sign) { match (self.sign, other.sign) {
(NoSign, _) | (_, NoSign) => Zero::zero(), (NoSign, _) | (_, NoSign) => Zero::zero(),
(Plus, Plus) | (Minus, Minus) => { (Plus, Plus) | (Minus, Minus) => {
BigInt::from_biguint(Plus, self.data * other.data) BigInt::from_biguint(Plus, &self.data * &other.data)
}, },
(Plus, Minus) | (Minus, Plus) => { (Plus, Minus) | (Minus, Plus) => {
BigInt::from_biguint(Minus, self.data * other.data) BigInt::from_biguint(Minus, &self.data * &other.data)
} }
} }
} }
} }
impl Div<BigInt, BigInt> for BigInt { forward_all_binop!(impl Div for BigInt, div)
impl<'a, 'b> Div<&'b BigInt, BigInt> for &'a BigInt {
#[inline] #[inline]
fn div(&self, other: &BigInt) -> BigInt { fn div(self, other: &BigInt) -> BigInt {
let (q, _) = self.div_rem(other); let (q, _) = self.div_rem(other);
q q
} }
} }
impl Rem<BigInt, BigInt> for BigInt { forward_all_binop!(impl Rem for BigInt, rem)
impl<'a, 'b> Rem<&'b BigInt, BigInt> for &'a BigInt {
#[inline] #[inline]
fn rem(&self, other: &BigInt) -> BigInt { fn rem(self, other: &BigInt) -> BigInt {
let (_, r) = self.div_rem(other); let (_, r) = self.div_rem(other);
r r
} }
@ -1131,19 +1221,24 @@ impl Integer for BigInt {
let (d_ui, m_ui) = self.data.div_rem(&other.data); let (d_ui, m_ui) = self.data.div_rem(&other.data);
let d = BigInt::from_biguint(Plus, d_ui); let d = BigInt::from_biguint(Plus, d_ui);
let m = BigInt::from_biguint(Plus, m_ui); let m = BigInt::from_biguint(Plus, m_ui);
let one: BigInt = One::one();
match (self.sign, other.sign) { match (self.sign, other.sign) {
(_, NoSign) => panic!(), (_, NoSign) => panic!(),
(Plus, Plus) | (NoSign, Plus) => (d, m), (Plus, Plus) | (NoSign, Plus) => (d, m),
(Plus, Minus) | (NoSign, Minus) => if m.is_zero() { (Plus, Minus) | (NoSign, Minus) => {
if m.is_zero() {
(-d, Zero::zero()) (-d, Zero::zero())
} else { } else {
(-d - One::one(), m + *other) (-d - one, m + other)
}
}, },
(Minus, Plus) => if m.is_zero() { (Minus, Plus) => {
if m.is_zero() {
(-d, Zero::zero()) (-d, Zero::zero())
} else { } else {
(-d - One::one(), *other - m) (-d - one, other - m)
}, }
}
(Minus, Minus) => (d, -m) (Minus, Minus) => (d, -m)
} }
} }
@ -1374,7 +1469,7 @@ impl<R: Rng> RandBigInt for R {
ubound: &BigUint) ubound: &BigUint)
-> BigUint { -> BigUint {
assert!(*lbound < *ubound); assert!(*lbound < *ubound);
return *lbound + self.gen_biguint_below(&(*ubound - *lbound)); return lbound + self.gen_biguint_below(&(ubound - lbound));
} }
fn gen_bigint_range(&mut self, fn gen_bigint_range(&mut self,
@ -1382,8 +1477,8 @@ impl<R: Rng> RandBigInt for R {
ubound: &BigInt) ubound: &BigInt)
-> BigInt { -> BigInt {
assert!(*lbound < *ubound); assert!(*lbound < *ubound);
let delta = (*ubound - *lbound).to_biguint().unwrap(); let delta = (ubound - lbound).to_biguint().unwrap();
return *lbound + self.gen_biguint_below(&delta).to_bigint().unwrap(); return lbound + self.gen_biguint_below(&delta).to_bigint().unwrap();
} }
} }
@ -1912,8 +2007,8 @@ mod biguint_tests {
let b = BigUint::from_slice(b_vec); let b = BigUint::from_slice(b_vec);
let c = BigUint::from_slice(c_vec); let c = BigUint::from_slice(c_vec);
assert!(a + b == c); assert!(&a + &b == c);
assert!(b + a == c); assert!(&b + &a == c);
} }
} }
@ -1925,8 +2020,8 @@ mod biguint_tests {
let b = BigUint::from_slice(b_vec); let b = BigUint::from_slice(b_vec);
let c = BigUint::from_slice(c_vec); let c = BigUint::from_slice(c_vec);
assert!(c - a == b); assert!(&c - &a == b);
assert!(c - b == a); assert!(&c - &b == a);
} }
} }
@ -1983,8 +2078,8 @@ mod biguint_tests {
let b = BigUint::from_slice(b_vec); let b = BigUint::from_slice(b_vec);
let c = BigUint::from_slice(c_vec); let c = BigUint::from_slice(c_vec);
assert!(a * b == c); assert!(&a * &b == c);
assert!(b * a == c); assert!(&b * &a == c);
} }
for elm in DIV_REM_QUADRUPLES.iter() { for elm in DIV_REM_QUADRUPLES.iter() {
@ -1994,8 +2089,8 @@ mod biguint_tests {
let c = BigUint::from_slice(c_vec); let c = BigUint::from_slice(c_vec);
let d = BigUint::from_slice(d_vec); let d = BigUint::from_slice(d_vec);
assert!(a == b * c + d); assert!(a == &b * &c + &d);
assert!(a == c * b + d); assert!(a == &c * &b + &d);
} }
} }
@ -2078,8 +2173,8 @@ mod biguint_tests {
let c = BigUint::from_slice(c_vec); let c = BigUint::from_slice(c_vec);
let d = BigUint::from_slice(d_vec); let d = BigUint::from_slice(d_vec);
assert!(a == b.checked_mul(&c).unwrap() + d); assert!(a == b.checked_mul(&c).unwrap() + &d);
assert!(a == c.checked_mul(&b).unwrap() + d); assert!(a == c.checked_mul(&b).unwrap() + &d);
} }
} }
@ -2149,8 +2244,8 @@ mod biguint_tests {
assert!(thousand.is_even()); assert!(thousand.is_even());
assert!(big.is_even()); assert!(big.is_even());
assert!(bigger.is_odd()); assert!(bigger.is_odd());
assert!((one << 64).is_even()); assert!((&one << 64).is_even());
assert!(((one << 64) + one).is_odd()); assert!(((&one << 64) + one).is_odd());
} }
fn to_str_pairs() -> Vec<(BigUint, Vec<(uint, String)>)> { fn to_str_pairs() -> Vec<(BigUint, Vec<(uint, String)>)> {
@ -2252,7 +2347,8 @@ mod biguint_tests {
for i in range(2, n + 1) { for i in range(2, n + 1) {
// FIXME(#5992): assignment operator overloads // FIXME(#5992): assignment operator overloads
// f *= FromPrimitive::from_uint(i); // f *= FromPrimitive::from_uint(i);
f = f * FromPrimitive::from_uint(i).unwrap(); let bu: BigUint = FromPrimitive::from_uint(i).unwrap();
f = f * bu;
} }
return f; return f;
} }
@ -2513,14 +2609,14 @@ mod bigint_tests {
let b = BigInt::from_slice(Plus, b_vec); let b = BigInt::from_slice(Plus, b_vec);
let c = BigInt::from_slice(Plus, c_vec); let c = BigInt::from_slice(Plus, c_vec);
assert!(a + b == c); assert!(&a + &b == c);
assert!(b + a == c); assert!(&b + &a == c);
assert!(c + (-a) == b); assert!(&c + (-a) == b);
assert!(c + (-b) == a); assert!(&c + (-b) == a);
assert!(a + (-c) == (-b)); assert!(&a + (-c) == (-b));
assert!(b + (-c) == (-a)); assert!(&b + (-c) == (-a));
assert!((-a) + (-b) == (-c)) assert!((-a) + (-b) == (-c))
assert!(a + (-a) == Zero::zero()); assert!(&a + (-a) == Zero::zero());
} }
} }
@ -2532,14 +2628,14 @@ mod bigint_tests {
let b = BigInt::from_slice(Plus, b_vec); let b = BigInt::from_slice(Plus, b_vec);
let c = BigInt::from_slice(Plus, c_vec); let c = BigInt::from_slice(Plus, c_vec);
assert!(c - a == b); assert!(&c - &a == b);
assert!(c - b == a); assert!(&c - &b == a);
assert!((-b) - a == (-c)) assert!((-b) - &a == (-c))
assert!((-a) - b == (-c)) assert!((-a) - &b == (-c))
assert!(b - (-a) == c); assert!(&b - (-a) == c);
assert!(a - (-b) == c); assert!(&a - (-b) == c);
assert!((-c) - (-a) == (-b)); assert!((-c) - (-a) == (-b));
assert!(a - a == Zero::zero()); assert!(&a - &a == Zero::zero());
} }
} }
@ -2589,11 +2685,11 @@ mod bigint_tests {
let b = BigInt::from_slice(Plus, b_vec); let b = BigInt::from_slice(Plus, b_vec);
let c = BigInt::from_slice(Plus, c_vec); let c = BigInt::from_slice(Plus, c_vec);
assert!(a * b == c); assert!(&a * &b == c);
assert!(b * a == c); assert!(&b * &a == c);
assert!((-a) * b == -c); assert!((-a) * &b == -c);
assert!((-b) * a == -c); assert!((-b) * &a == -c);
} }
for elm in DIV_REM_QUADRUPLES.iter() { for elm in DIV_REM_QUADRUPLES.iter() {
@ -2603,8 +2699,8 @@ mod bigint_tests {
let c = BigInt::from_slice(Plus, c_vec); let c = BigInt::from_slice(Plus, c_vec);
let d = BigInt::from_slice(Plus, d_vec); let d = BigInt::from_slice(Plus, d_vec);
assert!(a == b * c + d); assert!(a == &b * &c + &d);
assert!(a == c * b + d); assert!(a == &c * &b + &d);
} }
} }
@ -2616,7 +2712,7 @@ mod bigint_tests {
assert_eq!(m.sign, b.sign); assert_eq!(m.sign, b.sign);
} }
assert!(m.abs() <= b.abs()); assert!(m.abs() <= b.abs());
assert!(*a == (*b) * d + m); assert!(*a == b * &d + &m);
assert!(d == *ans_d); assert!(d == *ans_d);
assert!(m == *ans_m); assert!(m == *ans_m);
} }
@ -2628,9 +2724,10 @@ mod bigint_tests {
check_sub(&a.neg(), b, &d.neg(), m); check_sub(&a.neg(), b, &d.neg(), m);
check_sub(&a.neg(), &b.neg(), d, m); check_sub(&a.neg(), &b.neg(), d, m);
} else { } else {
let one: BigInt = One::one();
check_sub(a, b, d, m); check_sub(a, b, d, m);
check_sub(a, &b.neg(), &(d.neg() - One::one()), &(*m - *b)); check_sub(a, &b.neg(), &(d.neg() - &one), &(m - b));
check_sub(&a.neg(), b, &(d.neg() - One::one()), &(*b - *m)); check_sub(&a.neg(), b, &(d.neg() - &one), &(b - m));
check_sub(&a.neg(), &b.neg(), d, &m.neg()); check_sub(&a.neg(), &b.neg(), d, &m.neg());
} }
} }
@ -2667,7 +2764,7 @@ mod bigint_tests {
assert_eq!(r.sign, a.sign); assert_eq!(r.sign, a.sign);
} }
assert!(r.abs() <= b.abs()); assert!(r.abs() <= b.abs());
assert!(*a == (*b) * q + r); assert!(*a == b * &q + &r);
assert!(q == *ans_q); assert!(q == *ans_q);
assert!(r == *ans_r); assert!(r == *ans_r);
} }
@ -2761,8 +2858,8 @@ mod bigint_tests {
let c = BigInt::from_slice(Plus, c_vec); let c = BigInt::from_slice(Plus, c_vec);
let d = BigInt::from_slice(Plus, d_vec); let d = BigInt::from_slice(Plus, d_vec);
assert!(a == b.checked_mul(&c).unwrap() + d); assert!(a == b.checked_mul(&c).unwrap() + &d);
assert!(a == c.checked_mul(&b).unwrap() + d); assert!(a == c.checked_mul(&b).unwrap() + &d);
} }
} }
#[test] #[test]
@ -2943,7 +3040,8 @@ mod bench {
fn factorial(n: uint) -> BigUint { fn factorial(n: uint) -> BigUint {
let mut f: BigUint = One::one(); let mut f: BigUint = One::one();
for i in iter::range_inclusive(1, n) { for i in iter::range_inclusive(1, n) {
f = f * FromPrimitive::from_uint(i).unwrap(); let bu: BigUint = FromPrimitive::from_uint(i).unwrap();
f = f * bu;
} }
f f
} }
@ -2952,7 +3050,7 @@ mod bench {
let mut f0: BigUint = Zero::zero(); let mut f0: BigUint = Zero::zero();
let mut f1: BigUint = One::one(); let mut f1: BigUint = One::one();
for _ in range(0, n) { for _ in range(0, n) {
let f2 = f0 + f1; let f2 = f0 + &f1;
f0 = replace(&mut f1, f2); f0 = replace(&mut f1, f2);
} }
f0 f0

View File

@ -43,7 +43,7 @@ impl<T: Clone + Num> Complex<T> {
/// have a sqrt function), i.e. `re^2 + im^2`. /// have a sqrt function), i.e. `re^2 + im^2`.
#[inline] #[inline]
pub fn norm_sqr(&self) -> T { pub fn norm_sqr(&self) -> T {
self.re * self.re + self.im * self.im self.re.clone() * self.re.clone() + self.im.clone() * self.im.clone()
} }
@ -57,21 +57,21 @@ impl<T: Clone + Num> Complex<T> {
/// Multiplies `self` by the scalar `t`. /// Multiplies `self` by the scalar `t`.
#[inline] #[inline]
pub fn scale(&self, t: T) -> Complex<T> { pub fn scale(&self, t: T) -> Complex<T> {
Complex::new(self.re * t, self.im * t) Complex::new(self.re.clone() * t.clone(), self.im.clone() * t)
} }
/// Divides `self` by the scalar `t`. /// Divides `self` by the scalar `t`.
#[inline] #[inline]
pub fn unscale(&self, t: T) -> Complex<T> { pub fn unscale(&self, t: T) -> Complex<T> {
Complex::new(self.re / t, self.im / t) Complex::new(self.re.clone() / t.clone(), self.im.clone() / t)
} }
/// Returns `1/self` /// Returns `1/self`
#[inline] #[inline]
pub fn inv(&self) -> Complex<T> { pub fn inv(&self) -> Complex<T> {
let norm_sqr = self.norm_sqr(); let norm_sqr = self.norm_sqr();
Complex::new(self.re / norm_sqr, Complex::new(self.re.clone() / norm_sqr.clone(),
-self.im / norm_sqr) -self.im.clone() / norm_sqr)
} }
} }
@ -79,7 +79,7 @@ impl<T: Clone + FloatMath> Complex<T> {
/// Calculate |self| /// Calculate |self|
#[inline] #[inline]
pub fn norm(&self) -> T { pub fn norm(&self) -> T {
self.re.hypot(self.im) self.re.clone().hypot(self.im.clone())
} }
} }
@ -87,7 +87,7 @@ impl<T: Clone + FloatMath + Num> Complex<T> {
/// Calculate the principal Arg of self. /// Calculate the principal Arg of self.
#[inline] #[inline]
pub fn arg(&self) -> T { pub fn arg(&self) -> T {
self.im.atan2(self.re) self.im.clone().atan2(self.re.clone())
} }
/// Convert to polar form (r, theta), such that `self = r * exp(i /// Convert to polar form (r, theta), such that `self = r * exp(i
/// * theta)` /// * theta)`
@ -102,38 +102,91 @@ impl<T: Clone + FloatMath + Num> Complex<T> {
} }
} }
/* arithmetic */ macro_rules! forward_val_val_binop {
// (a + i b) + (c + i d) == (a + c) + i (b + d) (impl $imp:ident, $method:ident) => {
impl<T: Clone + Num> Add<Complex<T>, Complex<T>> for Complex<T> { impl<T: Clone + Num> $imp<Complex<T>, Complex<T>> for Complex<T> {
#[inline] #[inline]
fn add(&self, other: &Complex<T>) -> Complex<T> { fn $method(self, other: Complex<T>) -> Complex<T> {
Complex::new(self.re + other.re, self.im + other.im) (&self).$method(&other)
} }
}
// (a + i b) - (c + i d) == (a - c) + i (b - d)
impl<T: Clone + Num> Sub<Complex<T>, Complex<T>> for Complex<T> {
#[inline]
fn sub(&self, other: &Complex<T>) -> Complex<T> {
Complex::new(self.re - other.re, self.im - other.im)
} }
}
// (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
impl<T: Clone + Num> Mul<Complex<T>, Complex<T>> for Complex<T> {
#[inline]
fn mul(&self, other: &Complex<T>) -> Complex<T> {
Complex::new(self.re*other.re - self.im*other.im,
self.re*other.im + self.im*other.re)
} }
} }
macro_rules! forward_ref_val_binop {
(impl $imp:ident, $method:ident) => {
impl<'a, T: Clone + Num> $imp<Complex<T>, Complex<T>> for &'a Complex<T> {
#[inline]
fn $method(self, other: Complex<T>) -> Complex<T> {
self.$method(&other)
}
}
}
}
macro_rules! forward_val_ref_binop {
(impl $imp:ident, $method:ident) => {
impl<'a, T: Clone + Num> $imp<&'a Complex<T>, Complex<T>> for Complex<T> {
#[inline]
fn $method(self, other: &Complex<T>) -> Complex<T> {
(&self).$method(other)
}
}
}
}
macro_rules! forward_all_binop {
(impl $imp:ident, $method:ident) => {
forward_val_val_binop!(impl $imp, $method)
forward_ref_val_binop!(impl $imp, $method)
forward_val_ref_binop!(impl $imp, $method)
};
}
/* arithmetic */
forward_all_binop!(impl Add, add)
// (a + i b) + (c + i d) == (a + c) + i (b + d)
impl<'a, 'b, T: Clone + Num> Add<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
#[inline]
fn add(self, other: &Complex<T>) -> Complex<T> {
Complex::new(self.re.clone() + other.re.clone(),
self.im.clone() + other.im.clone())
}
}
forward_all_binop!(impl Sub, sub)
// (a + i b) - (c + i d) == (a - c) + i (b - d)
impl<'a, 'b, T: Clone + Num> Sub<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
#[inline]
fn sub(self, other: &Complex<T>) -> Complex<T> {
Complex::new(self.re.clone() - other.re.clone(),
self.im.clone() - other.im.clone())
}
}
forward_all_binop!(impl Mul, mul)
// (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
impl<'a, 'b, T: Clone + Num> Mul<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
#[inline]
fn mul(self, other: &Complex<T>) -> Complex<T> {
Complex::new(self.re.clone() * other.re.clone() - self.im.clone() * other.im.clone(),
self.re.clone() * other.im.clone() + self.im.clone() * other.re.clone())
}
}
forward_all_binop!(impl Div, div)
// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d) // (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
// == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)] // == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
impl<T: Clone + Num> Div<Complex<T>, Complex<T>> for Complex<T> { impl<'a, 'b, T: Clone + Num> Div<&'b Complex<T>, Complex<T>> for &'a Complex<T> {
#[inline] #[inline]
fn div(&self, other: &Complex<T>) -> Complex<T> { fn div(self, other: &Complex<T>) -> Complex<T> {
let norm_sqr = other.norm_sqr(); let norm_sqr = other.norm_sqr();
Complex::new((self.re*other.re + self.im*other.im) / norm_sqr, Complex::new((self.re.clone() * other.re.clone() + self.im.clone() * other.im.clone()) / norm_sqr.clone(),
(self.im*other.re - self.re*other.im) / norm_sqr) (self.im.clone() * other.re.clone() - self.re.clone() * other.im.clone()) / norm_sqr)
} }
} }

View File

@ -134,9 +134,7 @@ pub trait Integer: Num + PartialOrd
/// assert_eq!((-1i).div_rem(&-2), ( 0, -1)); /// assert_eq!((-1i).div_rem(&-2), ( 0, -1));
/// ~~~ /// ~~~
#[inline] #[inline]
fn div_rem(&self, other: &Self) -> (Self, Self) { fn div_rem(&self, other: &Self) -> (Self, Self);
(*self / *other, *self % *other)
}
/// Simultaneous floored integer division and modulus. /// Simultaneous floored integer division and modulus.
/// Returns `(quotient, remainder)`. /// Returns `(quotient, remainder)`.
@ -253,6 +251,12 @@ macro_rules! impl_integer_for_int {
/// Returns `true` if the number is not divisible by `2` /// Returns `true` if the number is not divisible by `2`
#[inline] #[inline]
fn is_odd(&self) -> bool { !self.is_even() } fn is_odd(&self) -> bool { !self.is_even() }
/// Simultaneous truncated integer division and modulus.
#[inline]
fn div_rem(&self, other: &$T) -> ($T, $T) {
(*self / *other, *self % *other)
}
} }
#[cfg(test)] #[cfg(test)]
@ -425,6 +429,12 @@ macro_rules! impl_integer_for_uint {
/// Returns `true` if the number is not divisible by `2`. /// Returns `true` if the number is not divisible by `2`.
#[inline] #[inline]
fn is_odd(&self) -> bool { !(*self).is_even() } fn is_odd(&self) -> bool { !(*self).is_even() }
/// Simultaneous truncated integer division and modulus.
#[inline]
fn div_rem(&self, other: &$T) -> ($T, $T) {
(*self / *other, *self % *other)
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -45,7 +45,7 @@ impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for Range<A> {
fn next(&mut self) -> Option<A> { fn next(&mut self) -> Option<A> {
if self.state < self.stop { if self.state < self.stop {
let result = self.state.clone(); let result = self.state.clone();
self.state = self.state + self.one; self.state = self.state.clone() + self.one.clone();
Some(result) Some(result)
} else { } else {
None None
@ -91,7 +91,7 @@ impl<A: Integer + PartialOrd + Clone + ToPrimitive> DoubleEndedIterator<A> for R
#[inline] #[inline]
fn next_back(&mut self) -> Option<A> { fn next_back(&mut self) -> Option<A> {
if self.stop > self.state { if self.stop > self.state {
self.stop = self.stop - self.one; self.stop = self.stop.clone() - self.one.clone();
Some(self.stop.clone()) Some(self.stop.clone())
} else { } else {
None None
@ -151,7 +151,7 @@ impl<A: Sub<A, A> + Integer + PartialOrd + Clone + ToPrimitive> DoubleEndedItera
fn next_back(&mut self) -> Option<A> { fn next_back(&mut self) -> Option<A> {
if self.range.stop > self.range.state { if self.range.stop > self.range.state {
let result = self.range.stop.clone(); let result = self.range.stop.clone();
self.range.stop = self.range.stop - self.range.one; self.range.stop = self.range.stop.clone() - self.range.one.clone();
Some(result) Some(result)
} else if !self.done && self.range.state == self.range.stop { } else if !self.done && self.range.state == self.range.stop {
self.done = true; self.done = true;
@ -246,7 +246,7 @@ mod tests {
} }
impl Add<Foo, Foo> for Foo { impl Add<Foo, Foo> for Foo {
fn add(&self, _: &Foo) -> Foo { fn add(self, _: Foo) -> Foo {
Foo Foo
} }
} }
@ -270,7 +270,7 @@ mod tests {
} }
impl Mul<Foo, Foo> for Foo { impl Mul<Foo, Foo> for Foo {
fn mul(&self, _: &Foo) -> Foo { fn mul(self, _: Foo) -> Foo {
Foo Foo
} }
} }

View File

@ -28,7 +28,7 @@
//! let mut approx = start.clone(); //! let mut approx = start.clone();
//! //!
//! for _ in range(0, iterations) { //! for _ in range(0, iterations) {
//! approx = (approx + (start / approx)) / //! approx = (&approx + (&start / &approx)) /
//! Ratio::from_integer(FromPrimitive::from_u64(2).unwrap()); //! Ratio::from_integer(FromPrimitive::from_u64(2).unwrap());
//! } //! }
//! //!
@ -123,15 +123,15 @@ pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
/// assert_eq!(num::pow(2i, 4), 16); /// assert_eq!(num::pow(2i, 4), 16);
/// ``` /// ```
#[inline] #[inline]
pub fn pow<T: One + Mul<T, T>>(mut base: T, mut exp: uint) -> T { pub fn pow<T: Clone + One + Mul<T, T>>(mut base: T, mut exp: uint) -> T {
if exp == 1 { base } if exp == 1 { base }
else { else {
let mut acc = one::<T>(); let mut acc = one::<T>();
while exp > 0 { while exp > 0 {
if (exp & 1) == 1 { if (exp & 1) == 1 {
acc = acc * base; acc = acc * base.clone();
} }
base = base * base; base = base.clone() * base;
exp = exp >> 1; exp = exp >> 1;
} }
acc acc

View File

@ -92,10 +92,10 @@ impl<T: Clone + Integer + PartialOrd>
// FIXME(#5992): assignment operator overloads // FIXME(#5992): assignment operator overloads
// self.numer /= g; // self.numer /= g;
self.numer = self.numer / g; self.numer = self.numer.clone() / g.clone();
// FIXME(#5992): assignment operator overloads // FIXME(#5992): assignment operator overloads
// self.denom /= g; // self.denom /= g;
self.denom = self.denom / g; self.denom = self.denom.clone() / g;
// keep denom positive! // keep denom positive!
if self.denom < Zero::zero() { if self.denom < Zero::zero() {
@ -121,9 +121,10 @@ impl<T: Clone + Integer + PartialOrd>
#[inline] #[inline]
pub fn floor(&self) -> Ratio<T> { pub fn floor(&self) -> Ratio<T> {
if *self < Zero::zero() { if *self < Zero::zero() {
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom) let one: T = One::one();
Ratio::from_integer((self.numer.clone() - self.denom.clone() + one) / self.denom.clone())
} else { } else {
Ratio::from_integer(self.numer / self.denom) Ratio::from_integer(self.numer.clone() / self.denom.clone())
} }
} }
@ -131,9 +132,10 @@ impl<T: Clone + Integer + PartialOrd>
#[inline] #[inline]
pub fn ceil(&self) -> Ratio<T> { pub fn ceil(&self) -> Ratio<T> {
if *self < Zero::zero() { if *self < Zero::zero() {
Ratio::from_integer(self.numer / self.denom) Ratio::from_integer(self.numer.clone() / self.denom.clone())
} else { } else {
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom) let one: T = One::one();
Ratio::from_integer((self.numer.clone() + self.denom.clone() - one) / self.denom.clone())
} }
} }
@ -141,7 +143,7 @@ impl<T: Clone + Integer + PartialOrd>
#[inline] #[inline]
pub fn round(&self) -> Ratio<T> { pub fn round(&self) -> Ratio<T> {
let one: T = One::one(); let one: T = One::one();
let two: T = one + one; let two: T = one.clone() + one.clone();
// Find unsigned fractional part of rational number // Find unsigned fractional part of rational number
let fractional = self.fract().abs(); let fractional = self.fract().abs();
@ -150,16 +152,17 @@ impl<T: Clone + Integer + PartialOrd>
// is, a/b >= 1/2, or a >= b/2. For odd denominators, we use // is, a/b >= 1/2, or a >= b/2. For odd denominators, we use
// a >= (b/2)+1. This avoids overflow issues. // a >= (b/2)+1. This avoids overflow issues.
let half_or_larger = if fractional.denom().is_even() { let half_or_larger = if fractional.denom().is_even() {
*fractional.numer() >= *fractional.denom() / two *fractional.numer() >= fractional.denom().clone() / two.clone()
} else { } else {
*fractional.numer() >= (*fractional.denom() / two) + one *fractional.numer() >= (fractional.denom().clone() / two.clone()) + one.clone()
}; };
if half_or_larger { if half_or_larger {
let one: Ratio<T> = One::one();
if *self >= Zero::zero() { if *self >= Zero::zero() {
self.trunc() + One::one() self.trunc() + one
} else { } else {
self.trunc() - One::one() self.trunc() - one
} }
} else { } else {
self.trunc() self.trunc()
@ -169,13 +172,13 @@ impl<T: Clone + Integer + PartialOrd>
/// Rounds towards zero. /// Rounds towards zero.
#[inline] #[inline]
pub fn trunc(&self) -> Ratio<T> { pub fn trunc(&self) -> Ratio<T> {
Ratio::from_integer(self.numer / self.denom) Ratio::from_integer(self.numer.clone() / self.denom.clone())
} }
/// Returns the fractional part of a number. /// Returns the fractional part of a number.
#[inline] #[inline]
pub fn fract(&self) -> Ratio<T> { pub fn fract(&self) -> Ratio<T> {
Ratio::new_raw(self.numer % self.denom, self.denom.clone()) Ratio::new_raw(self.numer.clone() % self.denom.clone(), self.denom.clone())
} }
} }
@ -212,11 +215,11 @@ macro_rules! cmp_impl {
}; };
// return something other than a Ratio<T> // return something other than a Ratio<T>
(impl $imp:ident, $($method:ident -> $res:ty),*) => { (impl $imp:ident, $($method:ident -> $res:ty),*) => {
impl<T: Mul<T,T> + $imp> $imp for Ratio<T> { impl<T: Clone + Mul<T,T> + $imp> $imp for Ratio<T> {
$( $(
#[inline] #[inline]
fn $method(&self, other: &Ratio<T>) -> $res { fn $method(&self, other: &Ratio<T>) -> $res {
(self.numer * other.denom). $method (&(self.denom*other.numer)) (self.numer.clone() * other.denom.clone()). $method (&(self.denom.clone()*other.numer.clone()))
} }
)* )*
} }
@ -228,34 +231,78 @@ cmp_impl!(impl PartialOrd, lt -> bool, gt -> bool, le -> bool, ge -> bool,
cmp_impl!(impl Eq, ) cmp_impl!(impl Eq, )
cmp_impl!(impl Ord, cmp -> cmp::Ordering) cmp_impl!(impl Ord, cmp -> cmp::Ordering)
/* Arithmetic */ macro_rules! forward_val_val_binop {
// a/b * c/d = (a*c)/(b*d) (impl $imp:ident, $method:ident) => {
impl<T: Clone + Integer + PartialOrd> impl<T: Clone + Integer + PartialOrd> $imp<Ratio<T>, Ratio<T>> for Ratio<T> {
Mul<Ratio<T>,Ratio<T>> for Ratio<T> {
#[inline] #[inline]
fn mul(&self, rhs: &Ratio<T>) -> Ratio<T> { fn $method(self, other: Ratio<T>) -> Ratio<T> {
Ratio::new(self.numer * rhs.numer, self.denom * rhs.denom) (&self).$method(&other)
}
}
} }
} }
// (a/b) / (c/d) = (a*d)/(b*c) macro_rules! forward_ref_val_binop {
impl<T: Clone + Integer + PartialOrd> (impl $imp:ident, $method:ident) => {
Div<Ratio<T>,Ratio<T>> for Ratio<T> { impl<'a, T: Clone + Integer + PartialOrd> $imp<Ratio<T>, Ratio<T>> for &'a Ratio<T> {
#[inline] #[inline]
fn div(&self, rhs: &Ratio<T>) -> Ratio<T> { fn $method(self, other: Ratio<T>) -> Ratio<T> {
Ratio::new(self.numer * rhs.denom, self.denom * rhs.numer) self.$method(&other)
}
}
}
}
macro_rules! forward_val_ref_binop {
(impl $imp:ident, $method:ident) => {
impl<'a, T: Clone + Integer + PartialOrd> $imp<&'a Ratio<T>, Ratio<T>> for Ratio<T> {
#[inline]
fn $method(self, other: &Ratio<T>) -> Ratio<T> {
(&self).$method(other)
}
}
}
}
macro_rules! forward_all_binop {
(impl $imp:ident, $method:ident) => {
forward_val_val_binop!(impl $imp, $method)
forward_ref_val_binop!(impl $imp, $method)
forward_val_ref_binop!(impl $imp, $method)
};
}
/* Arithmetic */
forward_all_binop!(impl Mul, mul)
// a/b * c/d = (a*c)/(b*d)
impl<'a, 'b, T: Clone + Integer + PartialOrd>
Mul<&'b Ratio<T>, Ratio<T>> for &'a Ratio<T> {
#[inline]
fn mul(self, rhs: &Ratio<T>) -> Ratio<T> {
Ratio::new(self.numer.clone() * rhs.numer.clone(), self.denom.clone() * rhs.denom.clone())
}
}
forward_all_binop!(impl Div, div)
// (a/b) / (c/d) = (a*d)/(b*c)
impl<'a, 'b, T: Clone + Integer + PartialOrd>
Div<&'b Ratio<T>, Ratio<T>> for &'a Ratio<T> {
#[inline]
fn div(self, rhs: &Ratio<T>) -> Ratio<T> {
Ratio::new(self.numer.clone() * rhs.denom.clone(), self.denom.clone() * rhs.numer.clone())
} }
} }
// Abstracts the a/b `op` c/d = (a*d `op` b*d) / (b*d) pattern // Abstracts the a/b `op` c/d = (a*d `op` b*d) / (b*d) pattern
macro_rules! arith_impl { macro_rules! arith_impl {
(impl $imp:ident, $method:ident) => { (impl $imp:ident, $method:ident) => {
impl<T: Clone + Integer + PartialOrd> forward_all_binop!(impl $imp, $method)
$imp<Ratio<T>,Ratio<T>> for Ratio<T> { impl<'a, 'b, T: Clone + Integer + PartialOrd>
$imp<&'b Ratio<T>,Ratio<T>> for &'a Ratio<T> {
#[inline] #[inline]
fn $method(&self, rhs: &Ratio<T>) -> Ratio<T> { fn $method(self, rhs: &Ratio<T>) -> Ratio<T> {
Ratio::new((self.numer * rhs.denom).$method(&(self.denom * rhs.numer)), Ratio::new((self.numer.clone() * rhs.denom.clone()).$method(self.denom.clone() * rhs.numer.clone()),
self.denom * rhs.denom) self.denom.clone() * rhs.denom.clone())
} }
} }
} }
@ -312,7 +359,7 @@ impl<T: Clone + Integer + PartialOrd>
#[inline] #[inline]
fn abs_sub(&self, other: &Ratio<T>) -> Ratio<T> { fn abs_sub(&self, other: &Ratio<T>) -> Ratio<T> {
if *self <= *other { Zero::zero() } else { *self - *other } if *self <= *other { Zero::zero() } else { self - other }
} }
#[inline] #[inline]