about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrendan Zabarauskas <bjzaba@yahoo.com.au>2013-05-19 01:11:50 +1000
committerBrendan Zabarauskas <bjzaba@yahoo.com.au>2013-05-19 02:35:36 +1000
commitd9eec664fd812dda88c349d092f327c9be8a7558 (patch)
tree8f4a4c0b329de0546ef377fe1695e9e3ca0d26f1 /src
parentdb453ec0e507382b4ac1bb9eae4654957b8a7e76 (diff)
downloadrust-d9eec664fd812dda88c349d092f327c9be8a7558.tar.gz
rust-d9eec664fd812dda88c349d092f327c9be8a7558.zip
Fix Ord implementation to use lexical ordering
Diffstat (limited to 'src')
-rw-r--r--src/libcore/tuple.rs28
1 files changed, 14 insertions, 14 deletions
diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs
index dd42afe646d..b07bb2bb1e6 100644
--- a/src/libcore/tuple.rs
+++ b/src/libcore/tuple.rs
@@ -165,7 +165,6 @@ macro_rules! tuple_impls(
                     fn eq(&self, other: &($($T),+)) -> bool {
                         $(*self.$get_ref_fn() == *other.$get_ref_fn())&&+
                     }
-
                     #[inline(always)]
                     fn ne(&self, other: &($($T),+)) -> bool {
                         !(*self == *other)
@@ -176,29 +175,30 @@ macro_rules! tuple_impls(
                 impl<$($T:Ord),+> Ord for ($($T),+) {
                     #[inline(always)]
                     fn lt(&self, other: &($($T),+)) -> bool {
-                        $(*self.$get_ref_fn() < *other.$get_ref_fn())&&+
+                        lexical_lt!($(*self.$get_ref_fn(), *other.$get_ref_fn()),+)
                     }
-
                     #[inline(always)]
-                    fn le(&self, other: &($($T),+)) -> bool {
-                        $(*self.$get_ref_fn() <= *other.$get_ref_fn())&&+
-                    }
-
+                    fn le(&self, other: &($($T),+)) -> bool { !(*other).lt(&(*self)) }
                     #[inline(always)]
-                    fn ge(&self, other: &($($T),+)) -> bool {
-                        $(*self.$get_ref_fn() >= *other.$get_ref_fn())&&+
-                    }
-
+                    fn ge(&self, other: &($($T),+)) -> bool { !(*self).lt(other) }
                     #[inline(always)]
-                    fn gt(&self, other: &($($T),+)) -> bool {
-                        $(*self.$get_ref_fn() > *other.$get_ref_fn())&&+
-                    }
+                    fn gt(&self, other: &($($T),+)) -> bool { (*other).lt(&(*self)) }
                 }
             )+
         }
     )
 )
 
+// Constructs an expression that performs a lexical less-than ordering.
+// The values are interleaved, so the macro invocation for
+// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_lt!(a1, b1, a2, b2, a3, b3)`
+macro_rules! lexical_lt(
+    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => (
+        if $a < $b { true } else { lexical_lt!($($rest_a, $rest_b),+) }
+    );
+    ($a:expr, $b:expr) => ($a < $b);
+)
+
 tuple_impls!(
     (CloneableTuple2, ImmutableTuple2) {
         (n0, n0_ref) -> A { (ref a,_) => a }