auto merge of #12520 : thestinger/rust/cmp, r=brson

* `Ord` inherits from `Eq`
* `TotalOrd` inherits from `TotalEq`
* `TotalOrd` inherits from `Ord`
* `TotalEq` inherits from `Eq`

This is a partial implementation of #12517.
This commit is contained in:
bors 2014-03-07 20:36:42 -08:00
commit 96e8c00e95
29 changed files with 156 additions and 53 deletions

View File

@ -92,6 +92,11 @@ fn clone(&self) -> BTree<K, V> {
}
}
impl<K: TotalOrd, V: TotalEq> Eq for BTree<K, V> {
fn eq(&self, other: &BTree<K, V>) -> bool {
self.equals(other)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for BTree<K, V> {
///Testing equality on BTrees by comparing the root.
@ -100,6 +105,12 @@ fn equals(&self, other: &BTree<K, V>) -> bool {
}
}
impl<K: TotalOrd, V: TotalEq> Ord for BTree<K, V> {
fn lt(&self, other: &BTree<K, V>) -> bool {
self.cmp(other) == Less
}
}
impl<K: TotalOrd, V: TotalEq> TotalOrd for BTree<K, V> {
///Returns an ordering based on the root nodes of each BTree.
fn cmp(&self, other: &BTree<K, V>) -> Ordering {
@ -191,6 +202,12 @@ fn clone(&self) -> Node<K, V> {
}
}
impl<K: TotalOrd, V: TotalEq> Eq for Node<K, V> {
fn eq(&self, other: &Node<K, V>) -> bool {
self.equals(other)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for Node<K, V> {
///Returns whether two nodes are equal based on the keys of each element.
///Two nodes are equal if all of their keys are the same.
@ -215,6 +232,12 @@ fn equals(&self, other: &Node<K, V>) -> bool{
}
}
impl<K: TotalOrd, V: TotalEq> Ord for Node<K, V> {
fn lt(&self, other: &Node<K, V>) -> bool {
self.cmp(other) == Less
}
}
impl<K: TotalOrd, V: TotalEq> TotalOrd for Node<K, V> {
///Implementation of TotalOrd for Nodes.
fn cmp(&self, other: &Node<K, V>) -> Ordering {
@ -380,6 +403,12 @@ fn clone(&self) -> Leaf<K, V> {
}
}
impl<K: TotalOrd, V: TotalEq> Eq for Leaf<K, V> {
fn eq(&self, other: &Leaf<K, V>) -> bool {
self.equals(other)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for Leaf<K, V> {
///Implementation of equals function for leaves that compares LeafElts.
fn equals(&self, other: &Leaf<K, V>) -> bool {
@ -387,6 +416,12 @@ fn equals(&self, other: &Leaf<K, V>) -> bool {
}
}
impl<K: TotalOrd, V: TotalEq> Ord for Leaf<K, V> {
fn lt(&self, other: &Leaf<K, V>) -> bool {
self.cmp(other) == Less
}
}
impl<K: TotalOrd, V: TotalEq> TotalOrd for Leaf<K, V> {
///Returns an ordering based on the first element of each Leaf.
fn cmp(&self, other: &Leaf<K, V>) -> Ordering {
@ -602,6 +637,12 @@ fn clone(&self) -> Branch<K, V> {
}
}
impl<K: TotalOrd, V: TotalEq> Eq for Branch<K, V> {
fn eq(&self, other: &Branch<K, V>) -> bool {
self.equals(other)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for Branch<K, V> {
///Equals function for Branches--compares all the elements in each branch
fn equals(&self, other: &Branch<K, V>) -> bool {
@ -609,6 +650,12 @@ fn equals(&self, other: &Branch<K, V>) -> bool {
}
}
impl<K: TotalOrd, V: TotalEq> Ord for Branch<K, V> {
fn lt(&self, other: &Branch<K, V>) -> bool {
self.cmp(other) == Less
}
}
impl<K: TotalOrd, V: TotalEq> TotalOrd for Branch<K, V> {
///Compares the first elements of two branches to determine an ordering
fn cmp(&self, other: &Branch<K, V>) -> Ordering {
@ -663,6 +710,12 @@ fn clone(&self) -> LeafElt<K, V> {
}
}
impl<K: TotalOrd, V: TotalEq> Eq for LeafElt<K, V> {
fn eq(&self, other: &LeafElt<K, V>) -> bool {
self.equals(other)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for LeafElt<K, V> {
///TotalEq for LeafElts
fn equals(&self, other: &LeafElt<K, V>) -> bool {
@ -670,6 +723,12 @@ fn equals(&self, other: &LeafElt<K, V>) -> bool {
}
}
impl<K: TotalOrd, V: TotalEq> Ord for LeafElt<K, V> {
fn lt(&self, other: &LeafElt<K, V>) -> bool {
self.cmp(other) == Less
}
}
impl<K: TotalOrd, V: TotalEq> TotalOrd for LeafElt<K, V> {
///Returns an ordering based on the keys of the LeafElts.
fn cmp(&self, other: &LeafElt<K, V>) -> Ordering {
@ -705,6 +764,12 @@ fn clone(&self) -> BranchElt<K, V> {
}
}
impl<K: TotalOrd, V: TotalEq> Eq for BranchElt<K, V>{
fn eq(&self, other: &BranchElt<K, V>) -> bool {
self.equals(other)
}
}
impl<K: TotalOrd, V: TotalEq> TotalEq for BranchElt<K, V>{
///TotalEq for BranchElts
fn equals(&self, other: &BranchElt<K, V>) -> bool {
@ -712,6 +777,12 @@ fn equals(&self, other: &BranchElt<K, V>) -> bool {
}
}
impl<K: TotalOrd, V: TotalEq> Ord for BranchElt<K, V> {
fn lt(&self, other: &BranchElt<K, V>) -> bool {
self.cmp(other) == Less
}
}
impl<K: TotalOrd, V: TotalEq> TotalOrd for BranchElt<K, V> {
///Fulfills TotalOrd for BranchElts
fn cmp(&self, other: &BranchElt<K, V>) -> Ordering {

View File

@ -607,7 +607,7 @@ fn ne(&self, other: &DList<A>) -> bool {
}
}
impl<A: Eq + Ord> Ord for DList<A> {
impl<A: Ord> Ord for DList<A> {
fn lt(&self, other: &DList<A>) -> bool {
iter::order::lt(self.iter(), other.iter())
}

View File

@ -88,7 +88,7 @@
*
*/
#[deriving(Clone, Eq, Encodable, Decodable, TotalOrd, TotalEq)]
#[deriving(Clone, Eq, Encodable, Decodable, Ord, TotalOrd, TotalEq)]
struct WorkKey {
kind: ~str,
name: ~str

View File

@ -46,7 +46,7 @@
use syntax::crateid::CrateId;
use syntax::parse::token;
#[deriving(Clone, Eq, TotalOrd, TotalEq)]
#[deriving(Clone, Eq, Ord, TotalOrd, TotalEq)]
pub enum OutputType {
OutputTypeBitcode,
OutputTypeAssembly,

View File

@ -166,7 +166,7 @@ pub enum EntryFnType {
EntryNone,
}
#[deriving(Eq, Clone, TotalOrd, TotalEq)]
#[deriving(Eq, Ord, Clone, TotalOrd, TotalEq)]
pub enum CrateType {
CrateTypeExecutable,
CrateTypeDylib,

View File

@ -525,7 +525,7 @@ pub fn lit_to_const(lit: &Lit) -> const_val {
}
}
fn compare_vals<T : Eq + Ord>(a: T, b: T) -> Option<int> {
fn compare_vals<T: Ord>(a: T, b: T) -> Option<int> {
Some(if a == b { 0 } else if a < b { -1 } else { 1 })
}
pub fn compare_const_vals(a: &const_val, b: &const_val) -> Option<int> {

View File

@ -633,13 +633,13 @@ pub fn is_bound(&self) -> bool {
}
}
#[deriving(Clone, Eq, TotalOrd, TotalEq, Hash, Encodable, Decodable, Show)]
#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Hash, Encodable, Decodable, Show)]
pub struct FreeRegion {
scope_id: NodeId,
bound_region: BoundRegion
}
#[deriving(Clone, Eq, TotalEq, TotalOrd, Hash, Encodable, Decodable, Show)]
#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Hash, Encodable, Decodable, Show)]
pub enum BoundRegion {
/// An anonymous region parameter for a given fn (&T)
BrAnon(uint),

View File

@ -42,8 +42,12 @@ fn ne(&self, other: &Self) -> bool { !self.eq(other) }
}
/// Trait for equality comparisons where `a == b` and `a != b` are strict inverses.
pub trait TotalEq {
fn equals(&self, other: &Self) -> bool;
pub trait TotalEq: Eq {
/// This method must return the same value as `eq`. It exists to prevent
/// deriving `TotalEq` from fields not implementing the `TotalEq` trait.
fn equals(&self, other: &Self) -> bool {
self.eq(other)
}
}
macro_rules! totaleq_impl(
@ -76,7 +80,7 @@ fn equals(&self, other: &$t) -> bool { *self == *other }
pub enum Ordering { Less = -1, Equal = 0, Greater = 1 }
/// Trait for types that form a total order
pub trait TotalOrd: TotalEq {
pub trait TotalOrd: TotalEq + Ord {
fn cmp(&self, other: &Self) -> Ordering;
}
@ -161,7 +165,7 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
* (cf. IEEE 754-2008 section 5.11).
*/
#[lang="ord"]
pub trait Ord {
pub trait Ord: Eq {
fn lt(&self, other: &Self) -> bool;
#[inline]
fn le(&self, other: &Self) -> bool { !other.lt(self) }
@ -169,8 +173,6 @@ fn le(&self, other: &Self) -> bool { !other.lt(self) }
fn gt(&self, other: &Self) -> bool { other.lt(self) }
#[inline]
fn ge(&self, other: &Self) -> bool { !self.lt(other) }
// FIXME (#12068): Add min/max/clamp default methods
}
/// The equivalence relation. Two values may be equivalent even if they are

View File

@ -2033,7 +2033,7 @@ pub fn range_inclusive<A: Add<A, A> + Ord + Clone + One + ToPrimitive>(start: A,
RangeInclusive{range: range(start, stop), done: false}
}
impl<A: Add<A, A> + Eq + Ord + Clone + ToPrimitive> Iterator<A> for RangeInclusive<A> {
impl<A: Add<A, A> + Ord + Clone + ToPrimitive> Iterator<A> for RangeInclusive<A> {
#[inline]
fn next(&mut self) -> Option<A> {
match self.range.next() {
@ -2244,7 +2244,7 @@ pub fn ne<A: Eq, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
}
/// Return `a` < `b` lexicographically (Using partial order, `Ord`)
pub fn lt<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
pub fn lt<A: Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
loop {
match (a.next(), b.next()) {
(None, None) => return false,
@ -2256,7 +2256,7 @@ pub fn lt<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
}
/// Return `a` <= `b` lexicographically (Using partial order, `Ord`)
pub fn le<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
pub fn le<A: Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
loop {
match (a.next(), b.next()) {
(None, None) => return true,
@ -2268,7 +2268,7 @@ pub fn le<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
}
/// Return `a` > `b` lexicographically (Using partial order, `Ord`)
pub fn gt<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
pub fn gt<A: Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
loop {
match (a.next(), b.next()) {
(None, None) => return false,
@ -2280,7 +2280,7 @@ pub fn gt<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
}
/// Return `a` >= `b` lexicographically (Using partial order, `Ord`)
pub fn ge<A: Eq + Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
pub fn ge<A: Ord, T: Iterator<A>>(mut a: T, mut b: T) -> bool {
loop {
match (a.next(), b.next()) {
(None, None) => return true,
@ -2978,6 +2978,12 @@ fn add(&self, _: &Foo) -> Foo {
}
}
impl Eq for Foo {
fn eq(&self, _: &Foo) -> bool {
true
}
}
impl Ord for Foo {
fn lt(&self, _: &Foo) -> bool {
false

View File

@ -40,7 +40,7 @@
use any::Any;
use clone::Clone;
use clone::DeepClone;
use cmp::{Eq, TotalEq, TotalOrd};
use cmp::{Eq, TotalOrd};
use default::Default;
use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSize};
use kinds::Send;

View File

@ -682,7 +682,7 @@ impl<T: TotalOrd> TotalOrd for ~[T] {
fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
}
impl<'a, T: Eq + Ord> Ord for &'a [T] {
impl<'a, T: Ord> Ord for &'a [T] {
fn lt(&self, other: & &'a [T]) -> bool {
order::lt(self.iter(), other.iter())
}
@ -700,7 +700,7 @@ fn gt(&self, other: & &'a [T]) -> bool {
}
}
impl<T: Eq + Ord> Ord for ~[T] {
impl<T: Ord> Ord for ~[T] {
#[inline]
fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() }
#[inline]

View File

@ -13,7 +13,7 @@
use cast::{forget, transmute};
use clone::Clone;
use cmp::{Eq, Ordering, TotalEq, TotalOrd};
use cmp::{Ord, Eq, Ordering, TotalEq, TotalOrd};
use container::Container;
use default::Default;
use fmt;
@ -136,21 +136,28 @@ fn extend<I: Iterator<T>>(&mut self, iterator: &mut I) {
}
}
impl<T:Eq> Eq for Vec<T> {
impl<T: Eq> Eq for Vec<T> {
#[inline]
fn eq(&self, other: &Vec<T>) -> bool {
self.as_slice() == other.as_slice()
}
}
impl<T:TotalEq> TotalEq for Vec<T> {
impl<T: Ord> Ord for Vec<T> {
#[inline]
fn lt(&self, other: &Vec<T>) -> bool {
self.as_slice() < other.as_slice()
}
}
impl<T: TotalEq> TotalEq for Vec<T> {
#[inline]
fn equals(&self, other: &Vec<T>) -> bool {
self.as_slice().equals(&other.as_slice())
}
}
impl<T:TotalOrd> TotalOrd for Vec<T> {
impl<T: TotalOrd> TotalOrd for Vec<T> {
#[inline]
fn cmp(&self, other: &Vec<T>) -> Ordering {
self.as_slice().cmp(&other.as_slice())

View File

@ -39,7 +39,7 @@ pub fn P<T: 'static>(value: T) -> P<T> {
// table) and a SyntaxContext to track renaming and
// macro expansion per Flatt et al., "Macros
// That Work Together"
#[deriving(Clone, Hash, TotalEq, TotalOrd, Show)]
#[deriving(Clone, Hash, Ord, TotalEq, TotalOrd, Show)]
pub struct Ident {
name: Name,
ctxt: SyntaxContext
@ -151,7 +151,7 @@ pub struct PathSegment {
pub type NodeId = u32;
#[deriving(Clone, TotalEq, TotalOrd, Eq, Encodable, Decodable, Hash, Show)]
#[deriving(Clone, TotalEq, TotalOrd, Ord, Eq, Encodable, Decodable, Hash, Show)]
pub struct DefId {
krate: CrateNum,
node: NodeId,

View File

@ -26,7 +26,7 @@
// Code implementation
#[deriving(Eq, TotalOrd, TotalEq)]
#[deriving(Eq, Ord, TotalOrd, TotalEq)]
struct Code(u64);
impl Code {

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(Eq)]
struct Error;
#[deriving(Ord)]
#[deriving(Eq, Ord)]
enum Enum {
A {
x: Error //~ ERROR

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(Eq)]
struct Error;
#[deriving(Ord)]
#[deriving(Eq, Ord)]
enum Enum {
A(
Error //~ ERROR

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(Eq)]
struct Error;
#[deriving(Ord)]
#[deriving(Eq, Ord)]
struct Struct {
x: Error //~ ERROR
//~^ ERROR

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(Eq)]
struct Error;
#[deriving(Ord)]
#[deriving(Eq, Ord)]
struct Struct(
Error //~ ERROR
//~^ ERROR

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(Eq)]
struct Error;
#[deriving(TotalEq)]
#[deriving(Eq, TotalEq)]
enum Enum {
A {
x: Error //~ ERROR

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(Eq)]
struct Error;
#[deriving(TotalEq)]
#[deriving(Eq, TotalEq)]
enum Enum {
A(
Error //~ ERROR

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(Eq)]
struct Error;
#[deriving(TotalEq)]
#[deriving(Eq, TotalEq)]
struct Struct {
x: Error //~ ERROR
}

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(Eq)]
struct Error;
#[deriving(TotalEq)]
#[deriving(Eq, TotalEq)]
struct Struct(
Error //~ ERROR
);

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(TotalEq)]
#[deriving(Eq, Ord, TotalEq)]
struct Error;
#[deriving(TotalOrd,TotalEq)]
#[deriving(Eq, Ord, TotalOrd,TotalEq)]
enum Enum {
A {
x: Error //~ ERROR

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(TotalEq)]
#[deriving(Eq, Ord, TotalEq)]
struct Error;
#[deriving(TotalOrd,TotalEq)]
#[deriving(Eq, Ord, TotalOrd,TotalEq)]
enum Enum {
A(
Error //~ ERROR

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(TotalEq)]
#[deriving(Eq, Ord, TotalEq)]
struct Error;
#[deriving(TotalOrd,TotalEq)]
#[deriving(Eq, Ord, TotalOrd,TotalEq)]
struct Struct {
x: Error //~ ERROR
}

View File

@ -13,10 +13,10 @@
#[feature(struct_variant)];
extern crate extra;
#[deriving(TotalEq)]
#[deriving(Eq, Ord, TotalEq)]
struct Error;
#[deriving(TotalOrd,TotalEq)]
#[deriving(Eq, Ord, TotalOrd,TotalEq)]
struct Struct(
Error //~ ERROR
);

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[deriving(Eq)]
struct thing(uint);
impl Ord for thing { //~ ERROR not all trait methods implemented, missing: `lt`
fn le(&self, other: &thing) -> bool { true }

View File

@ -22,6 +22,14 @@ fn eq(&self, other: &Fool) -> bool {
struct Int(int);
impl Eq for Int {
fn eq(&self, other: &Int) -> bool {
let Int(this) = *self;
let Int(other) = *other;
this == other
}
}
impl Ord for Int {
fn lt(&self, other: &Int) -> bool {
let Int(this) = *self;
@ -32,6 +40,14 @@ fn lt(&self, other: &Int) -> bool {
struct RevInt(int);
impl Eq for RevInt {
fn eq(&self, other: &RevInt) -> bool {
let RevInt(this) = *self;
let RevInt(other) = *other;
this == other
}
}
impl Ord for RevInt {
fn lt(&self, other: &RevInt) -> bool {
let RevInt(this) = *self;

View File

@ -15,7 +15,7 @@
static mut drop_counts: [uint, .. MAX_LEN] = [0, .. MAX_LEN];
static mut clone_count: uint = 0;
#[deriving(Rand, Ord, TotalEq, TotalOrd)]
#[deriving(Rand, Eq, Ord, TotalEq, TotalOrd)]
struct DropCounter { x: uint, clone_num: uint }
impl Clone for DropCounter {