about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorBrendan Zabarauskas <bjzaba@yahoo.com.au>2013-04-27 01:01:53 +1000
committerBrendan Zabarauskas <bjzaba@yahoo.com.au>2013-04-27 01:01:53 +1000
commit6cc7107aa6ca78093cb81aed44170099b8fad68a (patch)
tree79d6adbe48a7de966c1a15c24a6859a71cc67170 /src/libcore
parent6efbbf2e1481c3f42d7bd1cd7008fdc54939d9d3 (diff)
downloadrust-6cc7107aa6ca78093cb81aed44170099b8fad68a.tar.gz
rust-6cc7107aa6ca78093cb81aed44170099b8fad68a.zip
Add Orderable trait
This is a temporary trait until we have default methods. We don't want to encumber all implementors of Ord by requiring them to implement these functions, but at the same time we want to be able to take advantage of the speed of the specific numeric functions (like the `fmin` and `fmax` intrinsics).
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/core.rc3
-rw-r--r--src/libcore/num/f32.rs25
-rw-r--r--src/libcore/num/f64.rs25
-rw-r--r--src/libcore/num/float.rs29
-rw-r--r--src/libcore/num/int-template.rs29
-rw-r--r--src/libcore/num/num.rs17
-rw-r--r--src/libcore/num/uint-template.rs29
-rw-r--r--src/libcore/prelude.rs2
8 files changed, 155 insertions, 4 deletions
diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 47f83103b79..158da9a12fc 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -104,10 +104,11 @@ pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
 pub use iter::{ExtendedMutableIter};
 
 pub use num::{Num, NumCast};
-pub use num::{Signed, Unsigned, Integer};
+pub use num::{Orderable, Signed, Unsigned, Integer};
 pub use num::{Round, Fractional, Real, RealExt};
 pub use num::{Bitwise, BitCount, Bounded};
 pub use num::{Primitive, Int, Float};
+
 pub use ptr::Ptr;
 pub use to_str::ToStr;
 pub use clone::Clone;
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index f6330df9f9e..1e08979d796 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -224,6 +224,20 @@ impl Ord for f32 {
     fn gt(&self, other: &f32) -> bool { (*self) > (*other) }
 }
 
+impl Orderable for f32 {
+    #[inline(always)]
+    fn min(&self, other: &f32) -> f32 { fmin(*self, *other) }
+
+    #[inline(always)]
+    fn max(&self, other: &f32) -> f32 { fmax(*self, *other) }
+
+    #[inline(always)]
+    fn clamp(&self, mn: &f32, mx: &f32) -> f32 {
+        if *self > *mx { *mx } else
+        if *self < *mn { *mn } else { *self }
+    }
+}
+
 impl Zero for f32 {
     #[inline(always)]
     fn zero() -> f32 { 0.0 }
@@ -769,6 +783,17 @@ mod tests {
     }
 
     #[test]
+    fn test_orderable() {
+        assert_eq!(1f32.min(&2f32), 1f32);
+        assert_eq!(2f32.min(&1f32), 1f32);
+        assert_eq!(1f32.max(&2f32), 2f32);
+        assert_eq!(2f32.max(&1f32), 2f32);
+        assert_eq!(1f32.clamp(&2f32, &4f32), 2f32);
+        assert_eq!(8f32.clamp(&2f32, &4f32), 4f32);
+        assert_eq!(3f32.clamp(&2f32, &4f32), 3f32);
+    }
+
+    #[test]
     fn test_floor() {
         assert_fuzzy_eq!(1.0f32.floor(), 1.0f32);
         assert_fuzzy_eq!(1.3f32.floor(), 1.0f32);
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index d40c402b464..a42084336bf 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -245,6 +245,20 @@ impl Ord for f64 {
     fn gt(&self, other: &f64) -> bool { (*self) > (*other) }
 }
 
+impl Orderable for f64 {
+    #[inline(always)]
+    fn min(&self, other: &f64) -> f64 { fmin(*self, *other) }
+
+    #[inline(always)]
+    fn max(&self, other: &f64) -> f64 { fmax(*self, *other) }
+
+    #[inline(always)]
+    fn clamp(&self, mn: &f64, mx: &f64) -> f64 {
+        if *self > *mx { *mx } else
+        if *self < *mn { *mn } else { *self }
+    }
+}
+
 impl Zero for f64 {
     #[inline(always)]
     fn zero() -> f64 { 0.0 }
@@ -810,6 +824,17 @@ mod tests {
     }
 
     #[test]
+    fn test_orderable() {
+        assert_eq!(1f64.min(&2f64), 1f64);
+        assert_eq!(2f64.min(&1f64), 1f64);
+        assert_eq!(1f64.max(&2f64), 2f64);
+        assert_eq!(2f64.max(&1f64), 2f64);
+        assert_eq!(1f64.clamp(&2f64, &4f64), 2f64);
+        assert_eq!(8f64.clamp(&2f64, &4f64), 4f64);
+        assert_eq!(3f64.clamp(&2f64, &4f64), 3f64);
+    }
+
+    #[test]
     fn test_floor() {
         assert_fuzzy_eq!(1.0f64.floor(), 1.0f64);
         assert_fuzzy_eq!(1.3f64.floor(), 1.0f64);
diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs
index 9852e05c0b8..8661e7f0574 100644
--- a/src/libcore/num/float.rs
+++ b/src/libcore/num/float.rs
@@ -384,6 +384,24 @@ impl Ord for float {
     fn gt(&self, other: &float) -> bool { (*self) > (*other) }
 }
 
+impl Orderable for float {
+    #[inline(always)]
+    fn min(&self, other: &float) -> float {
+        fmin(*self as f64, *other as f64) as float
+    }
+
+    #[inline(always)]
+    fn max(&self, other: &float) -> float {
+        fmax(*self as f64, *other as f64) as float
+    }
+
+    #[inline(always)]
+    fn clamp(&self, mn: &float, mx: &float) -> float {
+        if *self > *mx { *mx } else
+        if *self < *mn { *mn } else { *self }
+    }
+}
+
 impl Zero for float {
     #[inline(always)]
     fn zero() -> float { 0.0 }
@@ -739,6 +757,17 @@ mod tests {
     }
 
     #[test]
+    fn test_orderable() {
+        assert_eq!(1f.min(&2f), 1f);
+        assert_eq!(2f.min(&1f), 1f);
+        assert_eq!(1f.max(&2f), 2f);
+        assert_eq!(2f.max(&1f), 2f);
+        assert_eq!(1f.clamp(&2f, &4f), 2f);
+        assert_eq!(8f.clamp(&2f, &4f), 4f);
+        assert_eq!(3f.clamp(&2f, &4f), 3f);
+    }
+
+    #[test]
     fn test_floor() {
         assert_fuzzy_eq!(1.0f.floor(), 1.0f);
         assert_fuzzy_eq!(1.3f.floor(), 1.0f);
diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs
index 0c126bd1de5..08df820a73d 100644
--- a/src/libcore/num/int-template.rs
+++ b/src/libcore/num/int-template.rs
@@ -152,6 +152,24 @@ impl Eq for T {
     fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
 }
 
+impl Orderable for T {
+    #[inline(always)]
+    fn min(&self, other: &T) -> T {
+        if *self < *other { *self } else { *other }
+    }
+
+    #[inline(always)]
+    fn max(&self, other: &T) -> T {
+        if *self > *other { *self } else { *other }
+    }
+
+    #[inline(always)]
+    fn clamp(&self, mn: &T, mx: &T) -> T {
+        if *self > *mx { *mx } else
+        if *self < *mn { *mn } else { *self }
+    }
+}
+
 impl Zero for T {
     #[inline(always)]
     fn zero() -> T { 0 }
@@ -536,6 +554,17 @@ mod tests {
     }
 
     #[test]
+    fn test_orderable() {
+        assert_eq!((1 as T).min(&(2 as T)), 1 as T);
+        assert_eq!((2 as T).min(&(1 as T)), 1 as T);
+        assert_eq!((1 as T).max(&(2 as T)), 2 as T);
+        assert_eq!((2 as T).max(&(1 as T)), 2 as T);
+        assert_eq!((1 as T).clamp(&(2 as T), &(4 as T)), 2 as T);
+        assert_eq!((8 as T).clamp(&(2 as T), &(4 as T)), 4 as T);
+        assert_eq!((3 as T).clamp(&(2 as T), &(4 as T)), 3 as T);
+    }
+
+    #[test]
     pub fn test_signed() {
         assert_eq!((1 as T).abs(), 1 as T);
         assert_eq!((0 as T).abs(), 0 as T);
diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs
index f1a77a4ed59..759f3e9872f 100644
--- a/src/libcore/num/num.rs
+++ b/src/libcore/num/num.rs
@@ -24,6 +24,9 @@ use kinds::Copy;
 
 pub mod strconv;
 
+///
+/// The base trait for numeric types
+///
 pub trait Num: Eq + Zero + One
              + Neg<Self>
              + Add<Self,Self>
@@ -37,6 +40,16 @@ pub trait IntConvertible {
     fn from_int(n: int) -> Self;
 }
 
+pub trait Orderable: Ord {
+    // These should be methods on `Ord`, with overridable default implementations. We don't want
+    // to encumber all implementors of Ord by requiring them to implement these functions, but at
+    // the same time we want to be able to take advantage of the speed of the specific numeric
+    // functions (like the `fmin` and `fmax` intrinsics).
+    fn min(&self, other: &Self) -> Self;
+    fn max(&self, other: &Self) -> Self;
+    fn clamp(&self, mn: &Self, mx: &Self) -> Self;
+}
+
 pub trait Zero {
     fn zero() -> Self;      // FIXME (#5527): This should be an associated constant
     fn is_zero(&self) -> bool;
@@ -62,7 +75,7 @@ pub fn abs<T:Ord + Zero + Neg<T>>(v: T) -> T {
 }
 
 pub trait Integer: Num
-                 + Ord
+                 + Orderable
                  + Quot<Self,Self>
                  + Rem<Self,Self> {
     fn div(&self, other: &Self) -> Self;
@@ -86,7 +99,7 @@ pub trait Round {
 }
 
 pub trait Fractional: Num
-                    + Ord
+                    + Orderable
                     + Round
                     + Quot<Self,Self> {
     fn recip(&self) -> Self;
diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs
index d84f4a99d53..af64660ad0c 100644
--- a/src/libcore/num/uint-template.rs
+++ b/src/libcore/num/uint-template.rs
@@ -117,6 +117,24 @@ impl Eq for T {
     fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
 }
 
+impl Orderable for T {
+    #[inline(always)]
+    fn min(&self, other: &T) -> T {
+        if *self < *other { *self } else { *other }
+    }
+
+    #[inline(always)]
+    fn max(&self, other: &T) -> T {
+        if *self > *other { *self } else { *other }
+    }
+
+    #[inline(always)]
+    fn clamp(&self, mn: &T, mx: &T) -> T {
+        if *self > *mx { *mx } else
+        if *self < *mn { *mn } else { *self }
+    }
+}
+
 impl Zero for T {
     #[inline(always)]
     fn zero() -> T { 0 }
@@ -368,6 +386,17 @@ mod tests {
     }
 
     #[test]
+    fn test_orderable() {
+        assert_eq!((1 as T).min(&(2 as T)), 1 as T);
+        assert_eq!((2 as T).min(&(1 as T)), 1 as T);
+        assert_eq!((1 as T).max(&(2 as T)), 2 as T);
+        assert_eq!((2 as T).max(&(1 as T)), 2 as T);
+        assert_eq!((1 as T).clamp(&(2 as T), &(4 as T)), 2 as T);
+        assert_eq!((8 as T).clamp(&(2 as T), &(4 as T)), 4 as T);
+        assert_eq!((3 as T).clamp(&(2 as T), &(4 as T)), 3 as T);
+    }
+
+    #[test]
     fn test_gcd() {
         assert_eq!((10 as T).gcd(&2), 2 as T);
         assert_eq!((10 as T).gcd(&3), 1 as T);
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
index 2711399c483..7e41f1b5b34 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude.rs
@@ -38,7 +38,7 @@ pub use iter::{BaseIter, ReverseIter, MutableIter, ExtendedIter, EqIter};
 pub use iter::{CopyableIter, CopyableOrderedIter, CopyableNonstrictIter};
 pub use iter::{Times, ExtendedMutableIter};
 pub use num::{Num, NumCast};
-pub use num::{Signed, Unsigned, Integer};
+pub use num::{Orderable, Signed, Unsigned, Integer};
 pub use num::{Round, Fractional, Real, RealExt};
 pub use num::{Bitwise, BitCount, Bounded};
 pub use num::{Primitive, Int, Float};