about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-06-07 16:08:38 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-06-07 16:08:38 -0700
commit3d7400f3accfc3da6f1e699770c69884bee1c664 (patch)
tree356d7103fed6f494da8ce2bcee344e93e230f88c /src
parentd542e67827e0ad1a3df5fd248d9c09997b5dcbba (diff)
Add a Num typeclass
Diffstat (limited to 'src')
-rw-r--r--src/libcore/core.rc2
-rw-r--r--src/libcore/int-template.rs33
-rw-r--r--src/libcore/uint-template.rs14
3 files changed, 47 insertions, 2 deletions
diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 668eb3c82b9..cfeda406411 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -46,6 +46,7 @@ export to_str;
 export swappable;
 export dvec, dvec_iter;
 export cmp;
+export num;
 
 // NDM seems to be necessary for resolve to work
 export option_iter;
@@ -155,6 +156,7 @@ mod tuple;
 // Ubiquitous-utility-type modules
 
 mod cmp;
+mod num;
 mod either;
 mod iter;
 mod logging;
diff --git a/src/libcore/int-template.rs b/src/libcore/int-template.rs
index 4011ac1a18a..8d9225b05a8 100644
--- a/src/libcore/int-template.rs
+++ b/src/libcore/int-template.rs
@@ -1,5 +1,6 @@
 import T = inst::T;
 import cmp::{eq, ord};
+import num::num;
 
 export min_value, max_value;
 export min, max;
@@ -11,7 +12,7 @@ export range;
 export compl;
 export abs;
 export parse_buf, from_str, to_str, to_str_bytes, str;
-export ord, eq;
+export ord, eq, num;
 
 const min_value: T = -1 as T << (inst::bits - 1 as T);
 const max_value: T = min_value - 1 as T;
@@ -122,6 +123,17 @@ impl eq of eq for T {
     }
 }
 
+impl num of num for T {
+    fn add(&&other: T)    -> T { ret self + other; }
+    fn sub(&&other: T)    -> T { ret self - other; }
+    fn mul(&&other: T)    -> T { ret self * other; }
+    fn div(&&other: T)    -> T { ret self / other; }
+    fn modulo(&&other: T) -> T { ret self % other; }
+
+    fn to_int()         -> int { ret self as int; }
+    fn from_int(n: int) -> T   { ret n as T;      }
+}
+
 
 // FIXME: Has alignment issues on windows and 32-bit linux
 #[test]
@@ -179,3 +191,22 @@ fn test_to_str() {
     assert (eq(to_str(127 as T, 16u), "7f"));
     assert (eq(to_str(100 as T, 10u), "100"));
 }
+
+#[test]
+fn test_ifaces() {
+    fn test<U:num>(ten: U) {
+        assert (ten.to_int() == 10);
+
+        let two = ten.from_int(2);
+        assert (two.to_int() == 2);
+
+        assert (ten.add(two) == ten.from_int(12));
+        assert (ten.sub(two) == ten.from_int(8));
+        assert (ten.mul(two) == ten.from_int(20));
+        assert (ten.div(two) == ten.from_int(5));
+        assert (ten.modulo(two) == ten.from_int(0));
+    }
+
+    test(10 as T);
+}
+
diff --git a/src/libcore/uint-template.rs b/src/libcore/uint-template.rs
index 7126fb3d007..9d658605f5a 100644
--- a/src/libcore/uint-template.rs
+++ b/src/libcore/uint-template.rs
@@ -1,5 +1,6 @@
 import T = inst::T;
 import cmp::{eq, ord};
+import num::num;
 
 export min_value, max_value;
 export min, max;
@@ -11,7 +12,7 @@ export range;
 export compl;
 export to_str, to_str_bytes;
 export from_str, from_str_radix, str, parse_buf;
-export ord, eq;
+export ord, eq, num;
 
 const min_value: T = 0 as T;
 const max_value: T = 0 as T - 1 as T;
@@ -63,6 +64,17 @@ impl eq of eq for T {
     }
 }
 
+impl num of num for T {
+    fn add(&&other: T)    -> T { ret self + other; }
+    fn sub(&&other: T)    -> T { ret self - other; }
+    fn mul(&&other: T)    -> T { ret self * other; }
+    fn div(&&other: T)    -> T { ret self / other; }
+    fn modulo(&&other: T) -> T { ret self % other; }
+
+    fn to_int()         -> int { ret self as int; }
+    fn from_int(n: int) -> T   { ret n as T;      }
+}
+
 #[doc = "
 Parse a buffer of bytes