Skip to content

create a sensible comparison trait hierarchy #12520

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions src/libcollections/btree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for 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.
Expand All @@ -100,6 +105,12 @@ impl<K: TotalOrd, V: TotalEq> TotalEq for BTree<K, V> {
}
}

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 {
Expand Down Expand Up @@ -191,6 +202,12 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for 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.
Expand All @@ -215,6 +232,12 @@ impl<K: TotalOrd, V: TotalEq> TotalEq for Node<K, V> {
}
}

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 {
Expand Down Expand Up @@ -380,13 +403,25 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for 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 {
self.elts.equals(&other.elts)
}
}

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 {
Expand Down Expand Up @@ -602,13 +637,25 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for 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 {
self.elts.equals(&other.elts)
}
}

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 {
Expand Down Expand Up @@ -663,13 +710,25 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for 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 {
self.key.equals(&other.key) && self.value.equals(&other.value)
}
}

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 {
Expand Down Expand Up @@ -705,13 +764,25 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for 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 {
self.key.equals(&other.key)&&self.value.equals(&other.value)
}
}

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 {
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ impl<A: Eq> Eq for DList<A> {
}
}

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())
}
Expand Down
2 changes: 1 addition & 1 deletion src/libextra/workcache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ use std::io::{File, MemWriter};
*
*/

#[deriving(Clone, Eq, Encodable, Decodable, TotalOrd, TotalEq)]
#[deriving(Clone, Eq, Encodable, Decodable, Ord, TotalOrd, TotalEq)]
struct WorkKey {
kind: ~str,
name: ~str
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use syntax::attr::AttrMetaMethods;
use syntax::crateid::CrateId;
use syntax::parse::token;

#[deriving(Clone, Eq, TotalOrd, TotalEq)]
#[deriving(Clone, Eq, Ord, TotalOrd, TotalEq)]
pub enum OutputType {
OutputTypeBitcode,
OutputTypeAssembly,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/driver/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ pub enum EntryFnType {
EntryNone,
}

#[deriving(Eq, Clone, TotalOrd, TotalEq)]
#[deriving(Eq, Ord, Clone, TotalOrd, TotalEq)]
pub enum CrateType {
CrateTypeExecutable,
CrateTypeDylib,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,13 +633,13 @@ impl Region {
}
}

#[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),
Expand Down
14 changes: 8 additions & 6 deletions src/libstd/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@ pub trait Eq {
}

/// 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(
Expand Down Expand Up @@ -76,7 +80,7 @@ totaleq_impl!(char)
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;
}

Expand Down Expand Up @@ -161,16 +165,14 @@ 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) }
#[inline]
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
Expand Down
16 changes: 11 additions & 5 deletions src/libstd/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -2244,7 +2244,7 @@ pub mod order {
}

/// 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,
Expand All @@ -2256,7 +2256,7 @@ pub mod order {
}

/// 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,
Expand All @@ -2268,7 +2268,7 @@ pub mod order {
}

/// 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,
Expand All @@ -2280,7 +2280,7 @@ pub mod order {
}

/// 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,
Expand Down Expand Up @@ -2978,6 +2978,12 @@ mod tests {
}
}

impl Eq for Foo {
fn eq(&self, _: &Foo) -> bool {
true
}
}

impl Ord for Foo {
fn lt(&self, _: &Foo) -> bool {
false
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ pub mod traits {
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())
}
Expand All @@ -700,7 +700,7 @@ pub mod traits {
}
}

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]
Expand Down
15 changes: 11 additions & 4 deletions src/libstd/vec_ng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -136,21 +136,28 @@ impl<T> Extendable<T> for Vec<T> {
}
}

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())
Expand Down
Loading