From a325a566c6a8a254377e072bddd5b347b6ace1df Mon Sep 17 00:00:00 2001 From: gifnksm Date: Tue, 16 Dec 2014 23:38:35 +0900 Subject: [PATCH] update to latest rustc Now, arithmetic binary operator traits take operands by value, but non-copyable types such as `BigUint` should not always moved out when applying operators. This commit implements these operators not only for bare structs also these references. By-value implementations are forwarded to by-reference implementations for now. In the future, by-value implementations may be replaced with more efficient implementations (for example, the implementation that reuses moved buffers.) --- benches/shootout-pidigits.rs | 14 +- src/bigint.rs | 342 ++++++++++++++++++++++------------- src/complex.rs | 117 ++++++++---- src/integer.rs | 16 +- src/iter.rs | 10 +- src/lib.rs | 8 +- src/rational.rs | 113 ++++++++---- 7 files changed, 414 insertions(+), 206 deletions(-) diff --git a/benches/shootout-pidigits.rs b/benches/shootout-pidigits.rs index 5ea3147..0090db8 100644 --- a/benches/shootout-pidigits.rs +++ b/benches/shootout-pidigits.rs @@ -70,24 +70,24 @@ impl Context { fn extract_digit(&self) -> int { if self.numer > self.accum {return -1;} let (q, r) = - (self.numer * Context::from_int(3) + self.accum) + (&self.numer * Context::from_int(3) + &self.accum) .div_rem(&self.denom); - if r + self.numer >= self.denom {return -1;} + if r + &self.numer >= self.denom {return -1;} q.to_int().unwrap() } fn next_term(&mut self, k: int) { let y2 = Context::from_int(k * 2 + 1); - self.accum = (self.accum + (self.numer << 1)) * y2; - self.numer = self.numer * Context::from_int(k); - self.denom = self.denom * y2; + self.accum = (&self.accum + (&self.numer << 1)) * &y2; + self.numer = &self.numer * Context::from_int(k); + self.denom = &self.denom * y2; } fn eliminate_digit(&mut self, d: int) { let d = Context::from_int(d); let ten = Context::from_int(10); - self.accum = (self.accum - self.denom * d) * ten; - self.numer = self.numer * ten; + self.accum = (&self.accum - &self.denom * d) * &ten; + self.numer = &self.numer * ten; } } diff --git a/src/bigint.rs b/src/bigint.rs index f89df3f..7f97126 100644 --- a/src/bigint.rs +++ b/src/bigint.rs @@ -27,7 +27,7 @@ //! let mut f0: BigUint = Zero::zero(); //! let mut f1: BigUint = One::one(); //! 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. //! f0 = replace(&mut f1, f2); //! } @@ -183,14 +183,60 @@ impl FromStr for BigUint { impl Num for BigUint {} -impl BitAnd for BigUint { - fn bitand(&self, other: &BigUint) -> BigUint { +macro_rules! forward_val_val_binop { + (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()) } } -impl BitOr for BigUint { - fn bitor(&self, other: &BigUint) -> BigUint { +forward_all_binop!(impl BitOr for BigUint, bitor) + +impl<'a, 'b> BitOr<&'b BigUint, BigUint> for &'a BigUint { + fn bitor(self, other: &BigUint) -> BigUint { let zeros = ZERO_VEC.iter().cycle(); 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( @@ -200,8 +246,10 @@ impl BitOr for BigUint { } } -impl BitXor for BigUint { - fn bitxor(&self, other: &BigUint) -> BigUint { +forward_all_binop!(impl BitXor for BigUint, bitxor) + +impl<'a, 'b> BitXor<&'b BigUint, BigUint> for &'a BigUint { + fn bitxor(self, other: &BigUint) -> BigUint { let zeros = ZERO_VEC.iter().cycle(); 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( @@ -213,18 +261,28 @@ impl BitXor for BigUint { impl Shl for BigUint { #[inline] - fn shl(&self, rhs: &uint) -> BigUint { - let n_unit = *rhs / BigDigit::BITS; - let n_bits = *rhs % BigDigit::BITS; + fn shl(self, rhs: uint) -> BigUint { (&self) << rhs } +} + +impl<'a> Shl 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); } } impl Shr for BigUint { #[inline] - fn shr(&self, rhs: &uint) -> BigUint { - let n_unit = *rhs / BigDigit::BITS; - let n_bits = *rhs % BigDigit::BITS; + fn shr(self, rhs: uint) -> BigUint { (&self) >> rhs } +} + +impl<'a> Shr 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); } } @@ -244,8 +302,10 @@ impl One for BigUint { impl Unsigned for BigUint {} -impl Add for BigUint { - fn add(&self, other: &BigUint) -> BigUint { +forward_all_binop!(impl Add for BigUint, add) + +impl<'a, 'b> Add<&'b BigUint, BigUint> for &'a BigUint { + fn add(self, other: &BigUint) -> BigUint { let zeros = ZERO_VEC.iter().cycle(); let (a, b) = if self.data.len() > other.data.len() { (self, other) } else { (other, self) }; @@ -261,8 +321,10 @@ impl Add for BigUint { } } -impl Sub for BigUint { - fn sub(&self, other: &BigUint) -> BigUint { +forward_all_binop!(impl Sub for BigUint, sub) + +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 zeros = ZERO_VEC.iter().cycle(); let (a, b) = (self.data.iter().chain(zeros.clone()), other.data.iter().chain(zeros)); @@ -289,8 +351,11 @@ impl Sub for BigUint { } } -impl Mul 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(); } let (s_len, o_len) = (self.data.len(), other.data.len()); @@ -306,15 +371,15 @@ impl Mul for BigUint { let (s_hi, s_lo) = cut_at(self, half_len); let (o_hi, o_lo) = cut_at(other, half_len); - let ll = s_lo * o_lo; - let hh = s_hi * o_hi; + let ll = &s_lo * &o_lo; + let hh = &s_hi * &o_hi; let mm = { let (s1, n1) = sub_sign(s_hi, s_lo); let (s2, n2) = sub_sign(o_hi, o_lo); match (s1, s2) { - (Equal, _) | (_, Equal) => hh + ll, - (Less, Greater) | (Greater, Less) => hh + ll + (n1 * n2), - (Less, Less) | (Greater, Greater) => hh + ll - (n1 * n2) + (Equal, _) | (_, Equal) => &hh + &ll, + (Less, Greater) | (Greater, Less) => &hh + &ll + (n1 * n2), + (Less, Less) | (Greater, Greater) => &hh + &ll - (n1 * n2) } }; @@ -323,7 +388,7 @@ impl Mul for BigUint { fn mul_digit(a: &BigUint, n: BigDigit) -> BigUint { if n == 0 { return Zero::zero(); } - if n == 1 { return (*a).clone(); } + if n == 1 { return a.clone(); } let mut carry = 0; let mut prod: Vec = a.data.iter().map(|ai| { @@ -355,17 +420,22 @@ impl Mul for BigUint { } } -impl Div for BigUint { + +forward_all_binop!(impl Div for BigUint, div) + +impl<'a, 'b> Div<&'b BigUint, BigUint> for &'a BigUint { #[inline] - fn div(&self, other: &BigUint) -> BigUint { + fn div(self, other: &BigUint) -> BigUint { let (q, _) = self.div_rem(other); return q; } } -impl Rem for BigUint { +forward_all_binop!(impl Rem for BigUint, rem) + +impl<'a, 'b> Rem<&'b BigUint, BigUint> for &'a BigUint { #[inline] - fn rem(&self, other: &BigUint) -> BigUint { + fn rem(self, other: &BigUint) -> BigUint { let (_, r) = self.div_rem(other); return r; } @@ -446,7 +516,7 @@ impl Integer for BigUint { shift += 1; } 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); @@ -457,14 +527,14 @@ impl Integer for BigUint { while m >= b { let (d0, d_unit, b_unit) = div_estimate(&m, &b, n); let mut d0 = d0; - let mut prod = b * d0; + let mut prod = &b * &d0; while prod > m { // FIXME(#5992): assignment operator overloads - // d0 -= d_unit - d0 = d0 - d_unit; + // d0 -= &d_unit + d0 = d0 - &d_unit; // FIXME(#5992): assignment operator overloads - // prod -= b_unit; - prod = prod - b_unit + // prod -= &b_unit; + prod = prod - &b_unit } if d0.is_zero() { n = 2; @@ -522,7 +592,7 @@ impl Integer for BigUint { let mut n = (*other).clone(); while !m.is_zero() { let temp = m; - m = n % temp; + m = n % &temp; n = temp; } return n; @@ -530,16 +600,16 @@ impl Integer for BigUint { /// Calculates the Lowest Common Multiple (LCM) of the number and `other`. #[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 = "function renamed to `is_multiple_of`"] #[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`. #[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`. #[inline] @@ -720,8 +790,8 @@ impl FromStrRadix for BigUint { match d { Some(d) => { // FIXME(#5992): assignment operator overloads - // n += d * power; - n = n + d * power; + // n += d * &power; + n = n + d * &power; } None => { return None; } } @@ -733,8 +803,8 @@ impl FromStrRadix for BigUint { } end -= unit_len; // FIXME(#5992): assignment operator overloads - // power *= base_num; - power = power * base_num; + // power *= &base_num; + power = power * &base_num; } } } @@ -938,15 +1008,25 @@ impl Num for BigInt {} impl Shl for BigInt { #[inline] - fn shl(&self, rhs: &uint) -> BigInt { - BigInt::from_biguint(self.sign, self.data << *rhs) + fn shl(self, rhs: uint) -> BigInt { (&self) << rhs } +} + +impl<'a> Shl for &'a BigInt { + #[inline] + fn shl(self, rhs: uint) -> BigInt { + BigInt::from_biguint(self.sign, &self.data << rhs) } } impl Shr for BigInt { #[inline] - fn shr(&self, rhs: &uint) -> BigInt { - BigInt::from_biguint(self.sign, self.data >> *rhs) + fn shr(self, rhs: uint) -> BigInt { (&self) >> rhs } +} + +impl<'a> Shr 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] fn abs_sub(&self, other: &BigInt) -> BigInt { - if *self <= *other { Zero::zero() } else { *self - *other } + if *self <= *other { Zero::zero() } else { self - other } } #[inline] @@ -997,64 +1077,74 @@ impl Signed for BigInt { fn is_negative(&self) -> bool { self.sign == Minus } } -impl Add for BigInt { +forward_all_binop!(impl Add for BigInt, add) + +impl<'a, 'b> Add<&'b BigInt, BigInt> for &'a BigInt { #[inline] - fn add(&self, other: &BigInt) -> BigInt { + fn add(self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { - (NoSign, _) => other.clone(), - (_, NoSign) => self.clone(), - (Plus, Plus) => BigInt::from_biguint(Plus, self.data + other.data), - (Plus, Minus) => *self - (-*other), - (Minus, Plus) => *other - (-*self), + (NoSign, _) => other.clone(), + (_, NoSign) => self.clone(), + (Plus, Plus) => BigInt::from_biguint(Plus, &self.data + &other.data), + (Plus, Minus) => self - (-*other), + (Minus, Plus) => other - (-*self), (Minus, Minus) => -((-*self) + (-*other)) } } } -impl Sub for BigInt { +forward_all_binop!(impl Sub for BigInt, sub) + +impl<'a, 'b> Sub<&'b BigInt, BigInt> for &'a BigInt { #[inline] - fn sub(&self, other: &BigInt) -> BigInt { + fn sub(self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { (NoSign, _) => -*other, (_, NoSign) => self.clone(), (Plus, Plus) => match self.data.cmp(&other.data) { - Less => BigInt::from_biguint(Minus, other.data - self.data), - Greater => BigInt::from_biguint(Plus, self.data - other.data), + Less => BigInt::from_biguint(Minus, &other.data - &self.data), + Greater => BigInt::from_biguint(Plus, &self.data - &other.data), Equal => Zero::zero() }, - (Plus, Minus) => *self + (-*other), - (Minus, Plus) => -((-*self) + *other), + (Plus, Minus) => self + (-*other), + (Minus, Plus) => -((-*self) + other), (Minus, Minus) => (-*other) - (-*self) } } } -impl Mul for BigInt { +forward_all_binop!(impl Mul for BigInt, mul) + +impl<'a, 'b> Mul<&'b BigInt, BigInt> for &'a BigInt { #[inline] - fn mul(&self, other: &BigInt) -> BigInt { + fn mul(self, other: &BigInt) -> BigInt { match (self.sign, other.sign) { (NoSign, _) | (_, NoSign) => Zero::zero(), (Plus, Plus) | (Minus, Minus) => { - BigInt::from_biguint(Plus, self.data * other.data) + BigInt::from_biguint(Plus, &self.data * &other.data) }, (Plus, Minus) | (Minus, Plus) => { - BigInt::from_biguint(Minus, self.data * other.data) + BigInt::from_biguint(Minus, &self.data * &other.data) } } } } -impl Div for BigInt { +forward_all_binop!(impl Div for BigInt, div) + +impl<'a, 'b> Div<&'b BigInt, BigInt> for &'a BigInt { #[inline] - fn div(&self, other: &BigInt) -> BigInt { + fn div(self, other: &BigInt) -> BigInt { let (q, _) = self.div_rem(other); q } } -impl Rem for BigInt { +forward_all_binop!(impl Rem for BigInt, rem) + +impl<'a, 'b> Rem<&'b BigInt, BigInt> for &'a BigInt { #[inline] - fn rem(&self, other: &BigInt) -> BigInt { + fn rem(self, other: &BigInt) -> BigInt { let (_, r) = self.div_rem(other); r } @@ -1131,19 +1221,24 @@ impl Integer for BigInt { let (d_ui, m_ui) = self.data.div_rem(&other.data); let d = BigInt::from_biguint(Plus, d_ui); let m = BigInt::from_biguint(Plus, m_ui); + let one: BigInt = One::one(); match (self.sign, other.sign) { (_, NoSign) => panic!(), (Plus, Plus) | (NoSign, Plus) => (d, m), - (Plus, Minus) | (NoSign, Minus) => if m.is_zero() { - (-d, Zero::zero()) - } else { - (-d - One::one(), m + *other) - }, - (Minus, Plus) => if m.is_zero() { - (-d, Zero::zero()) - } else { - (-d - One::one(), *other - m) + (Plus, Minus) | (NoSign, Minus) => { + if m.is_zero() { + (-d, Zero::zero()) + } else { + (-d - one, m + other) + } }, + (Minus, Plus) => { + if m.is_zero() { + (-d, Zero::zero()) + } else { + (-d - one, other - m) + } + } (Minus, Minus) => (d, -m) } } @@ -1374,7 +1469,7 @@ impl RandBigInt for R { ubound: &BigUint) -> BigUint { 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, @@ -1382,8 +1477,8 @@ impl RandBigInt for R { ubound: &BigInt) -> BigInt { assert!(*lbound < *ubound); - let delta = (*ubound - *lbound).to_biguint().unwrap(); - return *lbound + self.gen_biguint_below(&delta).to_bigint().unwrap(); + let delta = (ubound - lbound).to_biguint().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 c = BigUint::from_slice(c_vec); - assert!(a + b == c); - assert!(b + a == c); + assert!(&a + &b == c); + assert!(&b + &a == c); } } @@ -1925,8 +2020,8 @@ mod biguint_tests { let b = BigUint::from_slice(b_vec); let c = BigUint::from_slice(c_vec); - assert!(c - a == b); - assert!(c - b == a); + assert!(&c - &a == b); + assert!(&c - &b == a); } } @@ -1983,8 +2078,8 @@ mod biguint_tests { let b = BigUint::from_slice(b_vec); let c = BigUint::from_slice(c_vec); - assert!(a * b == c); - assert!(b * a == c); + assert!(&a * &b == c); + assert!(&b * &a == c); } for elm in DIV_REM_QUADRUPLES.iter() { @@ -1994,8 +2089,8 @@ mod biguint_tests { let c = BigUint::from_slice(c_vec); let d = BigUint::from_slice(d_vec); - assert!(a == b * c + d); - assert!(a == c * b + d); + assert!(a == &b * &c + &d); + assert!(a == &c * &b + &d); } } @@ -2078,8 +2173,8 @@ mod biguint_tests { let c = BigUint::from_slice(c_vec); let d = BigUint::from_slice(d_vec); - assert!(a == b.checked_mul(&c).unwrap() + d); - assert!(a == c.checked_mul(&b).unwrap() + d); + assert!(a == b.checked_mul(&c).unwrap() + &d); + assert!(a == c.checked_mul(&b).unwrap() + &d); } } @@ -2149,8 +2244,8 @@ mod biguint_tests { assert!(thousand.is_even()); assert!(big.is_even()); assert!(bigger.is_odd()); - assert!((one << 64).is_even()); - assert!(((one << 64) + one).is_odd()); + assert!((&one << 64).is_even()); + assert!(((&one << 64) + one).is_odd()); } fn to_str_pairs() -> Vec<(BigUint, Vec<(uint, String)>)> { @@ -2252,7 +2347,8 @@ mod biguint_tests { for i in range(2, n + 1) { // FIXME(#5992): assignment operator overloads // 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; } @@ -2513,14 +2609,14 @@ mod bigint_tests { let b = BigInt::from_slice(Plus, b_vec); let c = BigInt::from_slice(Plus, c_vec); - assert!(a + b == c); - assert!(b + a == c); - assert!(c + (-a) == b); - assert!(c + (-b) == a); - assert!(a + (-c) == (-b)); - assert!(b + (-c) == (-a)); + assert!(&a + &b == c); + assert!(&b + &a == c); + assert!(&c + (-a) == b); + assert!(&c + (-b) == a); + assert!(&a + (-c) == (-b)); + assert!(&b + (-c) == (-a)); 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 c = BigInt::from_slice(Plus, c_vec); - assert!(c - a == b); - assert!(c - b == a); - assert!((-b) - a == (-c)) - assert!((-a) - b == (-c)) - assert!(b - (-a) == c); - assert!(a - (-b) == c); + assert!(&c - &a == b); + assert!(&c - &b == a); + assert!((-b) - &a == (-c)) + assert!((-a) - &b == (-c)) + assert!(&b - (-a) == c); + assert!(&a - (-b) == c); 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 c = BigInt::from_slice(Plus, c_vec); - assert!(a * b == c); - assert!(b * a == c); + assert!(&a * &b == c); + assert!(&b * &a == c); - assert!((-a) * b == -c); - assert!((-b) * a == -c); + assert!((-a) * &b == -c); + assert!((-b) * &a == -c); } for elm in DIV_REM_QUADRUPLES.iter() { @@ -2603,8 +2699,8 @@ mod bigint_tests { let c = BigInt::from_slice(Plus, c_vec); let d = BigInt::from_slice(Plus, d_vec); - assert!(a == b * c + d); - assert!(a == c * b + d); + assert!(a == &b * &c + &d); + assert!(a == &c * &b + &d); } } @@ -2616,7 +2712,7 @@ mod bigint_tests { assert_eq!(m.sign, b.sign); } assert!(m.abs() <= b.abs()); - assert!(*a == (*b) * d + m); + assert!(*a == b * &d + &m); assert!(d == *ans_d); assert!(m == *ans_m); } @@ -2628,9 +2724,10 @@ mod bigint_tests { check_sub(&a.neg(), b, &d.neg(), m); check_sub(&a.neg(), &b.neg(), d, m); } else { + let one: BigInt = One::one(); check_sub(a, b, d, m); - check_sub(a, &b.neg(), &(d.neg() - One::one()), &(*m - *b)); - check_sub(&a.neg(), b, &(d.neg() - One::one()), &(*b - *m)); + check_sub(a, &b.neg(), &(d.neg() - &one), &(m - b)); + check_sub(&a.neg(), b, &(d.neg() - &one), &(b - m)); check_sub(&a.neg(), &b.neg(), d, &m.neg()); } } @@ -2667,7 +2764,7 @@ mod bigint_tests { assert_eq!(r.sign, a.sign); } assert!(r.abs() <= b.abs()); - assert!(*a == (*b) * q + r); + assert!(*a == b * &q + &r); assert!(q == *ans_q); assert!(r == *ans_r); } @@ -2761,8 +2858,8 @@ mod bigint_tests { let c = BigInt::from_slice(Plus, c_vec); let d = BigInt::from_slice(Plus, d_vec); - assert!(a == b.checked_mul(&c).unwrap() + d); - assert!(a == c.checked_mul(&b).unwrap() + d); + assert!(a == b.checked_mul(&c).unwrap() + &d); + assert!(a == c.checked_mul(&b).unwrap() + &d); } } #[test] @@ -2943,7 +3040,8 @@ mod bench { fn factorial(n: uint) -> BigUint { let mut f: BigUint = One::one(); 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 } @@ -2952,7 +3050,7 @@ mod bench { let mut f0: BigUint = Zero::zero(); let mut f1: BigUint = One::one(); for _ in range(0, n) { - let f2 = f0 + f1; + let f2 = f0 + &f1; f0 = replace(&mut f1, f2); } f0 diff --git a/src/complex.rs b/src/complex.rs index 11e36cf..7b2a544 100644 --- a/src/complex.rs +++ b/src/complex.rs @@ -43,7 +43,7 @@ impl Complex { /// have a sqrt function), i.e. `re^2 + im^2`. #[inline] 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 Complex { /// Multiplies `self` by the scalar `t`. #[inline] pub fn scale(&self, t: T) -> Complex { - 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`. #[inline] pub fn unscale(&self, t: T) -> Complex { - Complex::new(self.re / t, self.im / t) + Complex::new(self.re.clone() / t.clone(), self.im.clone() / t) } /// Returns `1/self` #[inline] pub fn inv(&self) -> Complex { let norm_sqr = self.norm_sqr(); - Complex::new(self.re / norm_sqr, - -self.im / norm_sqr) + Complex::new(self.re.clone() / norm_sqr.clone(), + -self.im.clone() / norm_sqr) } } @@ -79,7 +79,7 @@ impl Complex { /// Calculate |self| #[inline] pub fn norm(&self) -> T { - self.re.hypot(self.im) + self.re.clone().hypot(self.im.clone()) } } @@ -87,7 +87,7 @@ impl Complex { /// Calculate the principal Arg of self. #[inline] 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 /// * theta)` @@ -102,38 +102,91 @@ impl Complex { } } -/* arithmetic */ -// (a + i b) + (c + i d) == (a + c) + i (b + d) -impl Add, Complex> for Complex { - #[inline] - fn add(&self, other: &Complex) -> Complex { - Complex::new(self.re + other.re, self.im + other.im) - } -} -// (a + i b) - (c + i d) == (a - c) + i (b - d) -impl Sub, Complex> for Complex { - #[inline] - fn sub(&self, other: &Complex) -> Complex { - 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 Mul, Complex> for Complex { - #[inline] - fn mul(&self, other: &Complex) -> Complex { - Complex::new(self.re*other.re - self.im*other.im, - self.re*other.im + self.im*other.re) +macro_rules! forward_val_val_binop { + (impl $imp:ident, $method:ident) => { + impl $imp, Complex> for Complex { + #[inline] + fn $method(self, other: Complex) -> Complex { + (&self).$method(&other) + } + } } } +macro_rules! forward_ref_val_binop { + (impl $imp:ident, $method:ident) => { + impl<'a, T: Clone + Num> $imp, Complex> for &'a Complex { + #[inline] + fn $method(self, other: Complex) -> Complex { + self.$method(&other) + } + } + } +} + +macro_rules! forward_val_ref_binop { + (impl $imp:ident, $method:ident) => { + impl<'a, T: Clone + Num> $imp<&'a Complex, Complex> for Complex { + #[inline] + fn $method(self, other: &Complex) -> Complex { + (&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, Complex> for &'a Complex { + #[inline] + fn add(self, other: &Complex) -> Complex { + 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, Complex> for &'a Complex { + #[inline] + fn sub(self, other: &Complex) -> Complex { + 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, Complex> for &'a Complex { + #[inline] + fn mul(self, other: &Complex) -> Complex { + 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*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)] -impl Div, Complex> for Complex { +impl<'a, 'b, T: Clone + Num> Div<&'b Complex, Complex> for &'a Complex { #[inline] - fn div(&self, other: &Complex) -> Complex { + fn div(self, other: &Complex) -> Complex { let norm_sqr = other.norm_sqr(); - Complex::new((self.re*other.re + self.im*other.im) / norm_sqr, - (self.im*other.re - self.re*other.im) / norm_sqr) + Complex::new((self.re.clone() * other.re.clone() + self.im.clone() * other.im.clone()) / norm_sqr.clone(), + (self.im.clone() * other.re.clone() - self.re.clone() * other.im.clone()) / norm_sqr) } } diff --git a/src/integer.rs b/src/integer.rs index 90c2302..ee2d95e 100644 --- a/src/integer.rs +++ b/src/integer.rs @@ -134,9 +134,7 @@ pub trait Integer: Num + PartialOrd /// assert_eq!((-1i).div_rem(&-2), ( 0, -1)); /// ~~~ #[inline] - fn div_rem(&self, other: &Self) -> (Self, Self) { - (*self / *other, *self % *other) - } + fn div_rem(&self, other: &Self) -> (Self, Self); /// Simultaneous floored integer division and modulus. /// Returns `(quotient, remainder)`. @@ -253,6 +251,12 @@ macro_rules! impl_integer_for_int { /// Returns `true` if the number is not divisible by `2` #[inline] 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)] @@ -425,6 +429,12 @@ macro_rules! impl_integer_for_uint { /// Returns `true` if the number is not divisible by `2`. #[inline] 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)] diff --git a/src/iter.rs b/src/iter.rs index 9bb86ad..7e4a04a 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -45,7 +45,7 @@ impl + PartialOrd + Clone + ToPrimitive> Iterator for Range { fn next(&mut self) -> Option { if self.state < self.stop { let result = self.state.clone(); - self.state = self.state + self.one; + self.state = self.state.clone() + self.one.clone(); Some(result) } else { None @@ -91,7 +91,7 @@ impl DoubleEndedIterator for R #[inline] fn next_back(&mut self) -> Option { if self.stop > self.state { - self.stop = self.stop - self.one; + self.stop = self.stop.clone() - self.one.clone(); Some(self.stop.clone()) } else { None @@ -151,7 +151,7 @@ impl + Integer + PartialOrd + Clone + ToPrimitive> DoubleEndedItera fn next_back(&mut self) -> Option { if self.range.stop > self.range.state { 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) } else if !self.done && self.range.state == self.range.stop { self.done = true; @@ -246,7 +246,7 @@ mod tests { } impl Add for Foo { - fn add(&self, _: &Foo) -> Foo { + fn add(self, _: Foo) -> Foo { Foo } } @@ -270,7 +270,7 @@ mod tests { } impl Mul for Foo { - fn mul(&self, _: &Foo) -> Foo { + fn mul(self, _: Foo) -> Foo { Foo } } diff --git a/src/lib.rs b/src/lib.rs index f693c60..9523fc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,7 @@ //! let mut approx = start.clone(); //! //! for _ in range(0, iterations) { -//! approx = (approx + (start / approx)) / +//! approx = (&approx + (&start / &approx)) / //! Ratio::from_integer(FromPrimitive::from_u64(2).unwrap()); //! } //! @@ -123,15 +123,15 @@ pub fn abs_sub(x: T, y: T) -> T { /// assert_eq!(num::pow(2i, 4), 16); /// ``` #[inline] -pub fn pow>(mut base: T, mut exp: uint) -> T { +pub fn pow>(mut base: T, mut exp: uint) -> T { if exp == 1 { base } else { let mut acc = one::(); while exp > 0 { if (exp & 1) == 1 { - acc = acc * base; + acc = acc * base.clone(); } - base = base * base; + base = base.clone() * base; exp = exp >> 1; } acc diff --git a/src/rational.rs b/src/rational.rs index 9769805..4523f18 100644 --- a/src/rational.rs +++ b/src/rational.rs @@ -92,10 +92,10 @@ impl // FIXME(#5992): assignment operator overloads // self.numer /= g; - self.numer = self.numer / g; + self.numer = self.numer.clone() / g.clone(); // FIXME(#5992): assignment operator overloads // self.denom /= g; - self.denom = self.denom / g; + self.denom = self.denom.clone() / g; // keep denom positive! if self.denom < Zero::zero() { @@ -121,9 +121,10 @@ impl #[inline] pub fn floor(&self) -> Ratio { 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 { - Ratio::from_integer(self.numer / self.denom) + Ratio::from_integer(self.numer.clone() / self.denom.clone()) } } @@ -131,9 +132,10 @@ impl #[inline] pub fn ceil(&self) -> Ratio { if *self < Zero::zero() { - Ratio::from_integer(self.numer / self.denom) + Ratio::from_integer(self.numer.clone() / self.denom.clone()) } 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 #[inline] pub fn round(&self) -> Ratio { let one: T = One::one(); - let two: T = one + one; + let two: T = one.clone() + one.clone(); // Find unsigned fractional part of rational number let fractional = self.fract().abs(); @@ -150,16 +152,17 @@ impl // is, a/b >= 1/2, or a >= b/2. For odd denominators, we use // a >= (b/2)+1. This avoids overflow issues. let half_or_larger = if fractional.denom().is_even() { - *fractional.numer() >= *fractional.denom() / two + *fractional.numer() >= fractional.denom().clone() / two.clone() } else { - *fractional.numer() >= (*fractional.denom() / two) + one + *fractional.numer() >= (fractional.denom().clone() / two.clone()) + one.clone() }; if half_or_larger { + let one: Ratio = One::one(); if *self >= Zero::zero() { - self.trunc() + One::one() + self.trunc() + one } else { - self.trunc() - One::one() + self.trunc() - one } } else { self.trunc() @@ -169,13 +172,13 @@ impl /// Rounds towards zero. #[inline] pub fn trunc(&self) -> Ratio { - Ratio::from_integer(self.numer / self.denom) + Ratio::from_integer(self.numer.clone() / self.denom.clone()) } /// Returns the fractional part of a number. #[inline] pub fn fract(&self) -> Ratio { - 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 (impl $imp:ident, $($method:ident -> $res:ty),*) => { - impl + $imp> $imp for Ratio { + impl + $imp> $imp for Ratio { $( #[inline] fn $method(&self, other: &Ratio) -> $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 Ord, cmp -> cmp::Ordering) -/* Arithmetic */ -// a/b * c/d = (a*c)/(b*d) -impl - Mul,Ratio> for Ratio { - #[inline] - fn mul(&self, rhs: &Ratio) -> Ratio { - Ratio::new(self.numer * rhs.numer, self.denom * rhs.denom) +macro_rules! forward_val_val_binop { + (impl $imp:ident, $method:ident) => { + impl $imp, Ratio> for Ratio { + #[inline] + fn $method(self, other: Ratio) -> Ratio { + (&self).$method(&other) + } + } } } -// (a/b) / (c/d) = (a*d)/(b*c) -impl - Div,Ratio> for Ratio { +macro_rules! forward_ref_val_binop { + (impl $imp:ident, $method:ident) => { + impl<'a, T: Clone + Integer + PartialOrd> $imp, Ratio> for &'a Ratio { + #[inline] + fn $method(self, other: Ratio) -> Ratio { + self.$method(&other) + } + } + } +} + +macro_rules! forward_val_ref_binop { + (impl $imp:ident, $method:ident) => { + impl<'a, T: Clone + Integer + PartialOrd> $imp<&'a Ratio, Ratio> for Ratio { + #[inline] + fn $method(self, other: &Ratio) -> Ratio { + (&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, Ratio> for &'a Ratio { #[inline] - fn div(&self, rhs: &Ratio) -> Ratio { - Ratio::new(self.numer * rhs.denom, self.denom * rhs.numer) + fn mul(self, rhs: &Ratio) -> Ratio { + 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, Ratio> for &'a Ratio { + #[inline] + fn div(self, rhs: &Ratio) -> Ratio { + 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 macro_rules! arith_impl { (impl $imp:ident, $method:ident) => { - impl - $imp,Ratio> for Ratio { + forward_all_binop!(impl $imp, $method) + impl<'a, 'b, T: Clone + Integer + PartialOrd> + $imp<&'b Ratio,Ratio> for &'a Ratio { #[inline] - fn $method(&self, rhs: &Ratio) -> Ratio { - Ratio::new((self.numer * rhs.denom).$method(&(self.denom * rhs.numer)), - self.denom * rhs.denom) + fn $method(self, rhs: &Ratio) -> Ratio { + Ratio::new((self.numer.clone() * rhs.denom.clone()).$method(self.denom.clone() * rhs.numer.clone()), + self.denom.clone() * rhs.denom.clone()) } } } @@ -312,7 +359,7 @@ impl #[inline] fn abs_sub(&self, other: &Ratio) -> Ratio { - if *self <= *other { Zero::zero() } else { *self - *other } + if *self <= *other { Zero::zero() } else { self - other } } #[inline]