Skip to content

Commit 76ecce0

Browse files
committed
libstd: Ratio requires Clone instead of Copy
This allows creating `Ratio<T>` which `T` is non-implicitly copyable types such as `BigInt`.
1 parent 41eaa97 commit 76ecce0

File tree

1 file changed

+28
-23
lines changed

1 file changed

+28
-23
lines changed

src/libstd/num/rational.rs

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub type Rational64 = Ratio<i64>;
3030
/// Alias for arbitrary precision rationals.
3131
pub type BigRational = Ratio<BigInt>;
3232

33-
impl<T: Copy + Integer + Ord>
33+
impl<T: Clone + Integer + Ord>
3434
Ratio<T> {
3535
/// Create a ratio representing the integer `t`.
3636
#[inline(always)]
@@ -59,18 +59,23 @@ impl<T: Copy + Integer + Ord>
5959
fn reduce(&mut self) {
6060
let g : T = self.numer.gcd(&self.denom);
6161
62-
self.numer /= g;
63-
self.denom /= g;
62+
// FIXME(#6050): overloaded operators force moves with generic types
63+
// self.numer /= g;
64+
self.numer = self.numer / g;
65+
// FIXME(#6050): overloaded operators force moves with generic types
66+
// self.denom /= g;
67+
self.denom = self.denom / g;
6468
6569
// keep denom positive!
6670
if self.denom < Zero::zero() {
6771
self.numer = -self.numer;
6872
self.denom = -self.denom;
6973
}
7074
}
75+
7176
/// Return a `reduce`d copy of self.
7277
fn reduced(&self) -> Ratio<T> {
73-
let mut ret = copy *self;
78+
let mut ret = self.clone();
7479
ret.reduce();
7580
ret
7681
}
@@ -105,7 +110,7 @@ cmp_impl!(impl TotalOrd, cmp -> cmp::Ordering)
105110
106111
/* Arithmetic */
107112
// a/b * c/d = (a*c)/(b*d)
108-
impl<T: Copy + Integer + Ord>
113+
impl<T: Clone + Integer + Ord>
109114
Mul<Ratio<T>,Ratio<T>> for Ratio<T> {
110115
#[inline]
111116
fn mul(&self, rhs: &Ratio<T>) -> Ratio<T> {
@@ -114,7 +119,7 @@ impl<T: Copy + Integer + Ord>
114119
}
115120
116121
// (a/b) / (c/d) = (a*d)/(b*c)
117-
impl<T: Copy + Integer + Ord>
122+
impl<T: Clone + Integer + Ord>
118123
Div<Ratio<T>,Ratio<T>> for Ratio<T> {
119124
#[inline]
120125
fn div(&self, rhs: &Ratio<T>) -> Ratio<T> {
@@ -125,7 +130,7 @@ impl<T: Copy + Integer + Ord>
125130
// Abstracts the a/b `op` c/d = (a*d `op` b*d) / (b*d) pattern
126131
macro_rules! arith_impl {
127132
(impl $imp:ident, $method:ident) => {
128-
impl<T: Copy + Integer + Ord>
133+
impl<T: Clone + Integer + Ord>
129134
$imp<Ratio<T>,Ratio<T>> for Ratio<T> {
130135
#[inline]
131136
fn $method(&self, rhs: &Ratio<T>) -> Ratio<T> {
@@ -145,7 +150,7 @@ arith_impl!(impl Sub, sub)
145150
// a/b % c/d = (a*d % b*c)/(b*d)
146151
arith_impl!(impl Rem, rem)
147152
148-
impl<T: Copy + Integer + Ord>
153+
impl<T: Clone + Integer + Ord>
149154
Neg<Ratio<T>> for Ratio<T> {
150155
#[inline]
151156
fn neg(&self) -> Ratio<T> {
@@ -154,7 +159,7 @@ impl<T: Copy + Integer + Ord>
154159
}
155160
156161
/* Constants */
157-
impl<T: Copy + Integer + Ord>
162+
impl<T: Clone + Integer + Ord>
158163
Zero for Ratio<T> {
159164
#[inline]
160165
fn zero() -> Ratio<T> {
@@ -167,19 +172,19 @@ impl<T: Copy + Integer + Ord>
167172
}
168173
}
169174
170-
impl<T: Copy + Integer + Ord>
175+
impl<T: Clone + Integer + Ord>
171176
One for Ratio<T> {
172177
#[inline]
173178
fn one() -> Ratio<T> {
174179
Ratio::new_raw(One::one(), One::one())
175180
}
176181
}
177182
178-
impl<T: Copy + Integer + Ord>
183+
impl<T: Clone + Integer + Ord>
179184
Num for Ratio<T> {}
180185
181186
/* Utils */
182-
impl<T: Copy + Integer + Ord>
187+
impl<T: Clone + Integer + Ord>
183188
Round for Ratio<T> {
184189
185190
fn floor(&self) -> Ratio<T> {
@@ -213,14 +218,14 @@ impl<T: Copy + Integer + Ord>
213218
}
214219
215220
fn fract(&self) -> Ratio<T> {
216-
Ratio::new_raw(self.numer % self.denom, self.denom)
221+
Ratio::new_raw(self.numer % self.denom, self.denom.clone())
217222
}
218223
}
219224
220-
impl<T: Copy + Integer + Ord> Fractional for Ratio<T> {
225+
impl<T: Clone + Integer + Ord> Fractional for Ratio<T> {
221226
#[inline]
222227
fn recip(&self) -> Ratio<T> {
223-
Ratio::new_raw(self.denom, self.numer)
228+
Ratio::new_raw(self.denom.clone(), self.numer.clone())
224229
}
225230
}
226231
@@ -238,7 +243,7 @@ impl<T: ToStrRadix> ToStrRadix for Ratio<T> {
238243
}
239244
}
240245
241-
impl<T: FromStr + Copy + Integer + Ord>
246+
impl<T: FromStr + Clone + Integer + Ord>
242247
FromStr for Ratio<T> {
243248
/// Parses `numer/denom`.
244249
fn from_str(s: &str) -> Option<Ratio<T>> {
@@ -248,14 +253,14 @@ impl<T: FromStr + Copy + Integer + Ord>
248253
}
249254
});
250255
if split.len() < 2 { return None; }
251-
do FromStr::from_str(split[0]).chain |a| {
252-
do FromStr::from_str(split[1]).chain |b| {
253-
Some(Ratio::new(a,b))
256+
do FromStr::from_str::<T>(split[0]).chain |a| {
257+
do FromStr::from_str::<T>(split[1]).chain |b| {
258+
Some(Ratio::new(a.clone(), b.clone()))
254259
}
255260
}
256261
}
257262
}
258-
impl<T: FromStrRadix + Copy + Integer + Ord>
263+
impl<T: FromStrRadix + Clone + Integer + Ord>
259264
FromStrRadix for Ratio<T> {
260265
/// Parses `numer/denom` where the numbers are in base `radix`.
261266
fn from_str_radix(s: &str, radix: uint) -> Option<Ratio<T>> {
@@ -266,9 +271,9 @@ impl<T: FromStrRadix + Copy + Integer + Ord>
266271
});
267272
if split.len() < 2 { None }
268273
else {
269-
do FromStrRadix::from_str_radix(split[0], radix).chain |a| {
270-
do FromStrRadix::from_str_radix(split[1], radix).chain |b| {
271-
Some(Ratio::new(a,b))
274+
do FromStrRadix::from_str_radix::<T>(split[0], radix).chain |a| {
275+
do FromStrRadix::from_str_radix::<T>(split[1], radix).chain |b| {
276+
Some(Ratio::new(a.clone(), b.clone()))
272277
}
273278
}
274279
}

0 commit comments

Comments
 (0)