about summary refs log tree commit diff
diff options
context:
space:
mode:
authorblake2-ppc <blake2-ppc>2013-07-13 04:29:31 +0200
committerblake2-ppc <blake2-ppc>2013-07-13 06:23:38 +0200
commit36f20423c31601c7b2e4f94368e79f44146cb064 (patch)
tree2f453243f6413acabc284a0b51403888a72edd29
parent1ee54a86171d70f439b3cf77e566150b78251bc2 (diff)
downloadrust-36f20423c31601c7b2e4f94368e79f44146cb064.tar.gz
rust-36f20423c31601c7b2e4f94368e79f44146cb064.zip
cmp: Use default methods in trait Ord, only require Ord::lt
It will be simpler to implement only one method for Ord, while we also
allow implementing all four Ord methods for semantics or performance
reasons.

We only supply three default methods (and not four), because don't have
any nice error reporting for the case where at least one method must be
implemented, but it's arbitrary which.
-rw-r--r--src/libstd/cmp.rs17
-rw-r--r--src/test/compile-fail/issue-3344.rs3
-rw-r--r--src/test/run-pass/cmp-default.rs43
3 files changed, 53 insertions, 10 deletions
diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs
index 2c4bb46b23b..77d4e945aae 100644
--- a/src/libstd/cmp.rs
+++ b/src/libstd/cmp.rs
@@ -157,19 +157,20 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
 /**
 * Trait for values that can be compared for a sort-order.
 *
-* Eventually this may be simplified to only require
-* an `le` method, with the others generated from
-* default implementations. However it should remain
-* possible to implement the others separately, for
-* compatibility with floating-point NaN semantics
+* Ord only requires implementation of the `lt` method,
+* with the others generated from default implementations.
+*
+* However it remains possible to implement the others separately,
+* for compatibility with floating-point NaN semantics
 * (cf. IEEE 754-2008 section 5.11).
 */
+#[allow(default_methods)] // NOTE: Remove when allowed in stage0
 #[lang="ord"]
 pub trait Ord {
     fn lt(&self, other: &Self) -> bool;
-    fn le(&self, other: &Self) -> bool;
-    fn ge(&self, other: &Self) -> bool;
-    fn gt(&self, other: &Self) -> bool;
+    fn le(&self, other: &Self) -> bool { !other.lt(self) }
+    fn gt(&self, other: &Self) -> bool {  other.lt(self) }
+    fn ge(&self, other: &Self) -> bool { !self.lt(other) }
 }
 
 /// The equivalence relation. Two values may be equivalent even if they are
diff --git a/src/test/compile-fail/issue-3344.rs b/src/test/compile-fail/issue-3344.rs
index ac5b469c56e..9a3fff453f3 100644
--- a/src/test/compile-fail/issue-3344.rs
+++ b/src/test/compile-fail/issue-3344.rs
@@ -9,8 +9,7 @@
 // except according to those terms.
 
 struct thing(uint);
-impl Ord for thing { //~ ERROR missing method `gt`
-    fn lt(&self, other: &thing) -> bool { **self < **other }
+impl Ord for thing { //~ ERROR missing method `lt`
     fn le(&self, other: &thing) -> bool { **self < **other }
     fn ge(&self, other: &thing) -> bool { **self < **other }
 }
diff --git a/src/test/run-pass/cmp-default.rs b/src/test/run-pass/cmp-default.rs
new file mode 100644
index 00000000000..0dc5e7eb6ce
--- /dev/null
+++ b/src/test/run-pass/cmp-default.rs
@@ -0,0 +1,43 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test default methods in Ord
+//
+struct Int(int);
+
+impl Ord for Int {
+    fn lt(&self, other: &Int) -> bool {
+        **self < **other
+    }
+}
+
+struct RevInt(int);
+
+impl Ord for RevInt {
+    fn lt(&self, other: &RevInt) -> bool {
+        **self > **other
+    }
+}
+
+pub fn main() {
+    assert!(Int(2) >  Int(1));
+    assert!(Int(2) >= Int(1));
+    assert!(Int(1) >= Int(1));
+    assert!(Int(1) <  Int(2));
+    assert!(Int(1) <= Int(2));
+    assert!(Int(1) <= Int(1));
+
+    assert!(RevInt(2) <  RevInt(1));
+    assert!(RevInt(2) <= RevInt(1));
+    assert!(RevInt(1) <= RevInt(1));
+    assert!(RevInt(1) >  RevInt(2));
+    assert!(RevInt(1) >= RevInt(2));
+    assert!(RevInt(1) >= RevInt(1));
+}