summary refs log tree commit diff
path: root/src/libcore/num
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-02-12 17:07:26 -0800
committerPatrick Walton <pcwalton@mimiga.net>2013-02-14 08:14:01 -0800
commit216e85fadf465c25fe7bc4a9f06f8162ec12b552 (patch)
tree82efe48c8a559af32567e7c2faa57e017ef69e49 /src/libcore/num
parent6efa3543a8b38f0dcbe89e7bf6d14f571bad46ac (diff)
downloadrust-216e85fadf465c25fe7bc4a9f06f8162ec12b552.tar.gz
rust-216e85fadf465c25fe7bc4a9f06f8162ec12b552.zip
libcore: Move the numeric operations out of Num. r=brson
Sadly I could not use trait inheritance due to a type parameter substitution
bug.
Diffstat (limited to 'src/libcore/num')
-rw-r--r--src/libcore/num/f32.rs43
-rw-r--r--src/libcore/num/f64.rs43
-rw-r--r--src/libcore/num/float.rs43
-rw-r--r--src/libcore/num/int-template.rs40
-rw-r--r--src/libcore/num/num.rs44
-rw-r--r--src/libcore/num/uint-template.rs40
6 files changed, 151 insertions, 102 deletions
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index eaed597dff7..d27393fe507 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -13,8 +13,9 @@
 use cmath;
 use cmp;
 use libc::{c_float, c_int};
-use num;
 use num::NumCast;
+use num;
+use ops;
 use option::Option;
 use from_str;
 use to_str;
@@ -271,21 +272,6 @@ impl f32 : cmp::Ord {
     pure fn gt(&self, other: &f32) -> bool { (*self) > (*other) }
 }
 
-impl f32: num::Num {
-    #[inline(always)]
-    pure fn add(&self, other: &f32) -> f32 { return *self + *other; }
-    #[inline(always)]
-    pure fn sub(&self, other: &f32) -> f32 { return *self - *other; }
-    #[inline(always)]
-    pure fn mul(&self, other: &f32) -> f32 { return *self * *other; }
-    #[inline(always)]
-    pure fn div(&self, other: &f32) -> f32 { return *self / *other; }
-    #[inline(always)]
-    pure fn modulo(&self, other: &f32) -> f32 { return *self % *other; }
-    #[inline(always)]
-    pure fn neg(&self)                -> f32 { return -*self;        }
-}
-
 impl f32: num::Zero {
     #[inline(always)]
     static pure fn zero() -> f32 { 0.0 }
@@ -320,6 +306,31 @@ pub impl f32: NumCast {
     #[inline(always)] pure fn to_float(&self) -> float { *self as float }
 }
 
+#[cfg(notest)]
+impl ops::Add<f32,f32> for f32 {
+    pure fn add(&self, other: &f32) -> f32 { *self + *other }
+}
+#[cfg(notest)]
+impl ops::Sub<f32,f32> for f32 {
+    pure fn sub(&self, other: &f32) -> f32 { *self - *other }
+}
+#[cfg(notest)]
+impl ops::Mul<f32,f32> for f32 {
+    pure fn mul(&self, other: &f32) -> f32 { *self * *other }
+}
+#[cfg(notest)]
+impl ops::Div<f32,f32> for f32 {
+    pure fn div(&self, other: &f32) -> f32 { *self / *other }
+}
+#[cfg(notest)]
+impl ops::Modulo<f32,f32> for f32 {
+    pure fn modulo(&self, other: &f32) -> f32 { *self % *other }
+}
+#[cfg(notest)]
+impl ops::Neg<f32> for f32 {
+    pure fn neg(&self) -> f32 { -*self }
+}
+
 #[abi="rust-intrinsic"]
 pub extern {
     fn floorf32(val: f32) -> f32;
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 8aaa48524e2..d189a0254eb 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -14,8 +14,9 @@ use cmath;
 use cmp;
 use libc::{c_double, c_int};
 use libc;
-use num;
 use num::NumCast;
+use num;
+use ops;
 use option::Option;
 use to_str;
 use from_str;
@@ -296,21 +297,6 @@ impl f64 : cmp::Ord {
     pure fn gt(&self, other: &f64) -> bool { (*self) > (*other) }
 }
 
-impl f64: num::Num {
-    #[inline(always)]
-    pure fn add(&self, other: &f64)    -> f64 { return *self + *other; }
-    #[inline(always)]
-    pure fn sub(&self, other: &f64)    -> f64 { return *self - *other; }
-    #[inline(always)]
-    pure fn mul(&self, other: &f64)    -> f64 { return *self * *other; }
-    #[inline(always)]
-    pure fn div(&self, other: &f64)    -> f64 { return *self / *other; }
-    #[inline(always)]
-    pure fn modulo(&self, other: &f64) -> f64 { return *self % *other; }
-    #[inline(always)]
-    pure fn neg(&self)                -> f64 { return -*self;        }
-}
-
 pub impl f64: NumCast {
     /**
      * Cast `n` to an `f64`
@@ -345,6 +331,31 @@ impl f64: num::One {
     static pure fn one() -> f64 { 1.0 }
 }
 
+#[cfg(notest)]
+impl ops::Add<f64,f64> for f64 {
+    pure fn add(&self, other: &f64) -> f64 { *self + *other }
+}
+#[cfg(notest)]
+impl ops::Sub<f64,f64> for f64 {
+    pure fn sub(&self, other: &f64) -> f64 { *self - *other }
+}
+#[cfg(notest)]
+impl ops::Mul<f64,f64> for f64 {
+    pure fn mul(&self, other: &f64) -> f64 { *self * *other }
+}
+#[cfg(notest)]
+impl ops::Div<f64,f64> for f64 {
+    pure fn div(&self, other: &f64) -> f64 { *self / *other }
+}
+#[cfg(notest)]
+impl ops::Modulo<f64,f64> for f64 {
+    pure fn modulo(&self, other: &f64) -> f64 { *self % *other }
+}
+#[cfg(notest)]
+impl ops::Neg<f64> for f64 {
+    pure fn neg(&self) -> f64 { -*self }
+}
+
 #[abi="rust-intrinsic"]
 pub extern {
     fn floorf64(val: f64) -> f64;
diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs
index c7d391bab08..bbea58f5cf5 100644
--- a/src/libcore/num/float.rs
+++ b/src/libcore/num/float.rs
@@ -25,8 +25,9 @@ use m_float = f64;
 use cmp::{Eq, Ord};
 use cmp;
 use f64;
-use num;
 use num::NumCast;
+use num;
+use ops;
 use option::{None, Option, Some};
 use str;
 use uint;
@@ -404,21 +405,6 @@ impl float : Ord {
     pure fn gt(&self, other: &float) -> bool { (*self) > (*other) }
 }
 
-impl float: num::Num {
-    #[inline(always)]
-    pub pure fn add(&self, other: &float) -> float { return *self + *other; }
-    #[inline(always)]
-    pub pure fn sub(&self, other: &float) -> float { return *self - *other; }
-    #[inline(always)]
-    pub pure fn mul(&self, other: &float) -> float { return *self * *other; }
-    #[inline(always)]
-    pub pure fn div(&self, other: &float) -> float { return *self / *other; }
-    #[inline(always)]
-    pure fn modulo(&self, other: &float) -> float { return *self % *other; }
-    #[inline(always)]
-    pure fn neg(&self)                  -> float { return -*self;        }
-}
-
 impl float: num::Zero {
     #[inline(always)]
     static pure fn zero() -> float { 0.0 }
@@ -486,6 +472,31 @@ impl float: num::Round {
     }
 }
 
+#[cfg(notest)]
+impl ops::Add<float,float> for float {
+    pure fn add(&self, other: &float) -> float { *self + *other }
+}
+#[cfg(notest)]
+impl ops::Sub<float,float> for float {
+    pure fn sub(&self, other: &float) -> float { *self - *other }
+}
+#[cfg(notest)]
+impl ops::Mul<float,float> for float {
+    pure fn mul(&self, other: &float) -> float { *self * *other }
+}
+#[cfg(notest)]
+impl ops::Div<float,float> for float {
+    pure fn div(&self, other: &float) -> float { *self / *other }
+}
+#[cfg(notest)]
+impl ops::Modulo<float,float> for float {
+    pure fn modulo(&self, other: &float) -> float { *self % *other }
+}
+#[cfg(notest)]
+impl ops::Neg<float> for float {
+    pure fn neg(&self) -> float { -*self }
+}
+
 #[test]
 pub fn test_from_str() {
    assert from_str(~"3") == Some(3.);
diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs
index 71c06bc9d24..c25938a187f 100644
--- a/src/libcore/num/int-template.rs
+++ b/src/libcore/num/int-template.rs
@@ -166,21 +166,6 @@ impl T : Eq {
     pure fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
 }
 
-impl T: num::Num {
-    #[inline(always)]
-    pure fn add(&self, other: &T)    -> T { return *self + *other; }
-    #[inline(always)]
-    pure fn sub(&self, other: &T)    -> T { return *self - *other; }
-    #[inline(always)]
-    pure fn mul(&self, other: &T)    -> T { return *self * *other; }
-    #[inline(always)]
-    pure fn div(&self, other: &T)    -> T { return *self / *other; }
-    #[inline(always)]
-    pure fn modulo(&self, other: &T) -> T { return *self % *other; }
-    #[inline(always)]
-    pure fn neg(&self)              -> T { return -*self;        }
-}
-
 impl T: num::Zero {
     #[inline(always)]
     static pure fn zero() -> T { 0 }
@@ -203,6 +188,31 @@ impl T: num::Round {
     pure fn fract(&self) -> T { 0 }
 }
 
+#[cfg(notest)]
+impl ops::Add<T,T> for T {
+    pure fn add(&self, other: &T) -> T { *self + *other }
+}
+#[cfg(notest)]
+impl ops::Sub<T,T> for T {
+    pure fn sub(&self, other: &T) -> T { *self - *other }
+}
+#[cfg(notest)]
+impl ops::Mul<T,T> for T {
+    pure fn mul(&self, other: &T) -> T { *self * *other }
+}
+#[cfg(notest)]
+impl ops::Div<T,T> for T {
+    pure fn div(&self, other: &T) -> T { *self / *other }
+}
+#[cfg(notest)]
+impl ops::Modulo<T,T> for T {
+    pure fn modulo(&self, other: &T) -> T { *self % *other }
+}
+#[cfg(notest)]
+impl ops::Neg<T> for T {
+    pure fn neg(&self) -> T { -*self }
+}
+
 // String conversion functions and impl str -> num
 
 /// Parse a string as a number in base 10.
diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs
index 8435a7b8ea2..44cd66363fb 100644
--- a/src/libcore/num/num.rs
+++ b/src/libcore/num/num.rs
@@ -10,22 +10,13 @@
 
 //! An interface for numeric types
 use core::cmp::{Ord, Eq};
+use ops::{Add, Div, Modulo, Mul, Neg, Sub};
 use option::{None, Option, Some};
 use char;
 use str;
 use kinds::Copy;
 use vec;
 
-pub trait Num {
-    // FIXME: Trait composition. (#2616)
-    pure fn add(&self, other: &Self) -> Self;
-    pure fn sub(&self, other: &Self) -> Self;
-    pure fn mul(&self, other: &Self) -> Self;
-    pure fn div(&self, other: &Self) -> Self;
-    pure fn modulo(&self, other: &Self) -> Self;
-    pure fn neg(&self) -> Self;
-}
-
 pub trait IntConvertible {
     pure fn to_int(&self) -> int;
     static pure fn from_int(n: int) -> Self;
@@ -39,7 +30,7 @@ pub trait One {
     static pure fn one() -> Self;
 }
 
-pub pure fn abs<T: Ord Num Zero>(v: T) -> T {
+pub pure fn abs<T:Ord + Zero + Neg<T>>(v: T) -> T {
     if v < Zero::zero() { v.neg() } else { v }
 }
 
@@ -109,7 +100,7 @@ pub trait FromStrRadix {
 /// Dynamically calculates the value `inf` (`1/0`).
 /// Can fail on integer types.
 #[inline(always)]
-pub pure fn infinity<T: Num One Zero>() -> T {
+pub pure fn infinity<T:One+Zero+Div<T,T>>() -> T {
     let _0: T = Zero::zero();
     let _1: T = One::one();
     _1 / _0
@@ -118,7 +109,7 @@ pub pure fn infinity<T: Num One Zero>() -> T {
 /// Dynamically calculates the value `-inf` (`-1/0`).
 /// Can fail on integer types.
 #[inline(always)]
-pub pure fn neg_infinity<T: Num One Zero>() -> T {
+pub pure fn neg_infinity<T:One+Zero+Div<T,T>+Neg<T>>() -> T {
     let _0: T = Zero::zero();
     let _1: T = One::one();
     - _1 / _0
@@ -127,7 +118,7 @@ pub pure fn neg_infinity<T: Num One Zero>() -> T {
 /// Dynamically calculates the value `NaN` (`0/0`).
 /// Can fail on integer types.
 #[inline(always)]
-pub pure fn NaN<T: Num Zero>() -> T {
+pub pure fn NaN<T:Zero+Div<T,T>>() -> T {
     let _0: T = Zero::zero();
     _0 / _0
 }
@@ -135,27 +126,28 @@ pub pure fn NaN<T: Num Zero>() -> T {
 /// Returns `true` if `num` has the value `inf` (`1/0`).
 /// Can fail on integer types.
 #[inline(always)]
-pub pure fn is_infinity<T: Num One Zero Eq>(num: &T) -> bool {
+pub pure fn is_infinity<T:One+Zero+Eq+Div<T,T>>(num: &T) -> bool {
     (*num) == (infinity::<T>())
 }
 
 /// Returns `true` if `num` has the value `-inf` (`-1/0`).
 /// Can fail on integer types.
 #[inline(always)]
-pub pure fn is_neg_infinity<T: Num One Zero Eq>(num: &T) -> bool {
+pub pure fn is_neg_infinity<T:One+Zero+Eq+Div<T,T>+Neg<T>>(num: &T)
+                                                            -> bool {
     (*num) == (neg_infinity::<T>())
 }
 
 /// Returns `true` if `num` has the value `NaN` (is not equal to itself).
 #[inline(always)]
-pub pure fn is_NaN<T: Num Eq>(num: &T) -> bool {
+pub pure fn is_NaN<T:Eq>(num: &T) -> bool {
     (*num) != (*num)
 }
 
 /// Returns `true` if `num` has the value `-0` (`1/num == -1/0`).
 /// Can fail on integer types.
 #[inline(always)]
-pub pure fn is_neg_zero<T: Num One Zero Eq>(num: &T) -> bool {
+pub pure fn is_neg_zero<T:One+Zero+Eq+Div<T,T>+Neg<T>>(num: &T) -> bool {
     let _1: T = One::one();
     let _0: T = Zero::zero();
     *num == _0 && is_neg_infinity(&(_1 / *num))
@@ -174,8 +166,8 @@ pub pure fn is_neg_zero<T: Num One Zero Eq>(num: &T) -> bool {
  * - If code written to use this function doesn't care about it, it's
  *   probably assuming that `x^0` always equals `1`.
  */
-pub pure fn pow_with_uint<T: Num NumCast One Zero Copy>(radix: uint,
-                                                        pow: uint) -> T {
+pub pure fn pow_with_uint<T:NumCast+One+Zero+Copy+Div<T,T>+Mul<T,T>>(
+    radix: uint, pow: uint) -> T {
     let _0: T = Zero::zero();
     let _1: T = One::one();
 
@@ -256,7 +248,8 @@ pub enum SignFormat {
  * those special values, and `special` is `false`, because then the
  * algorithm just does normal calculations on them.
  */
-pub pure fn to_str_bytes_common<T: Num NumCast Zero One Eq Ord Round Copy>(
+pub pure fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Round+Copy+Div<T,T>+
+                                  Neg<T>+Modulo<T,T>+Mul<T,T>>(
         num: &T, radix: uint, special: bool, negative_zero: bool,
         sign: SignFormat, digits: SignificantDigits) -> (~[u8], bool) {
     if radix as int <  2 {
@@ -478,7 +471,8 @@ pub pure fn to_str_bytes_common<T: Num NumCast Zero One Eq Ord Round Copy>(
  * `to_str_bytes_common()`, for details see there.
  */
 #[inline(always)]
-pub pure fn to_str_common<T: Num NumCast Zero One Eq Ord Round Copy>(
+pub pure fn to_str_common<T:NumCast+Zero+One+Eq+Ord+Round+Copy+Div<T,T>+Neg<T>
+                            +Modulo<T,T>+Mul<T,T>>(
         num: &T, radix: uint, special: bool, negative_zero: bool,
         sign: SignFormat, digits: SignificantDigits) -> (~str, bool) {
     let (bytes, special) = to_str_bytes_common(num, radix, special,
@@ -533,7 +527,8 @@ priv const DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
  * - Could accept option to allow ignoring underscores, allowing for numbers
  *   formated like `FF_AE_FF_FF`.
  */
-pub pure fn from_str_bytes_common<T: Num NumCast Zero One Ord Copy>(
+pub pure fn from_str_bytes_common<T:NumCast+Zero+One+Ord+Copy+Div<T,T>+
+                                    Mul<T,T>+Sub<T,T>+Neg<T>+Add<T,T>>(
         buf: &[u8], radix: uint, negative: bool, fractional: bool,
         special: bool, exponent: ExponentFormat, empty_zero: bool
         ) -> Option<T> {
@@ -720,7 +715,8 @@ pub pure fn from_str_bytes_common<T: Num NumCast Zero One Ord Copy>(
  * `from_str_bytes_common()`, for details see there.
  */
 #[inline(always)]
-pub pure fn from_str_common<T: Num NumCast Zero One Ord Copy>(
+pub pure fn from_str_common<T:NumCast+Zero+One+Ord+Copy+Div<T,T>+Mul<T,T>+
+                              Sub<T,T>+Neg<T>+Add<T,T>>(
         buf: &str, radix: uint, negative: bool, fractional: bool,
         special: bool, exponent: ExponentFormat, empty_zero: bool
         ) -> Option<T> {
diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs
index 0f74b73e1c5..adfd50e20e7 100644
--- a/src/libcore/num/uint-template.rs
+++ b/src/libcore/num/uint-template.rs
@@ -130,21 +130,6 @@ impl T : Eq {
     pure fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
 }
 
-impl T: num::Num {
-    #[inline(always)]
-    pure fn add(&self, other: &T)    -> T { return *self + *other; }
-    #[inline(always)]
-    pure fn sub(&self, other: &T)    -> T { return *self - *other; }
-    #[inline(always)]
-    pure fn mul(&self, other: &T)    -> T { return *self * *other; }
-    #[inline(always)]
-    pure fn div(&self, other: &T)    -> T { return *self / *other; }
-    #[inline(always)]
-    pure fn modulo(&self, other: &T) -> T { return *self % *other; }
-    #[inline(always)]
-    pure fn neg(&self)              -> T { return -*self;        }
-}
-
 impl T: num::Zero {
     #[inline(always)]
     static pure fn zero() -> T { 0 }
@@ -167,6 +152,31 @@ impl T: num::Round {
     pure fn fract(&self) -> T { 0 }
 }
 
+#[cfg(notest)]
+impl ops::Add<T,T> for T {
+    pure fn add(&self, other: &T) -> T { *self + *other }
+}
+#[cfg(notest)]
+impl ops::Sub<T,T> for T {
+    pure fn sub(&self, other: &T) -> T { *self - *other }
+}
+#[cfg(notest)]
+impl ops::Mul<T,T> for T {
+    pure fn mul(&self, other: &T) -> T { *self * *other }
+}
+#[cfg(notest)]
+impl ops::Div<T,T> for T {
+    pure fn div(&self, other: &T) -> T { *self / *other }
+}
+#[cfg(notest)]
+impl ops::Modulo<T,T> for T {
+    pure fn modulo(&self, other: &T) -> T { *self % *other }
+}
+#[cfg(notest)]
+impl ops::Neg<T> for T {
+    pure fn neg(&self) -> T { -*self }
+}
+
 // String conversion functions and impl str -> num
 
 /// Parse a string as a number in base 10.