mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-25 05:14:27 +00:00
auto merge of #15030 : sfackler/rust/partial-cmp, r=huonw
I ended up altering the semantics of Json's PartialOrd implementation. It used to be the case that Null < Null, but I can't think of any reason for an ordering other than the default one so I just switched it over to using the derived implementation. This also fixes broken `PartialOrd` implementations for `Vec` and `TreeMap`. # Note This isn't ready to merge yet since libcore tests are broken as you end up with 2 versions of `Option`. The rest should be reviewable though. RFC: 0028-partial-cmp
This commit is contained in:
commit
e1683f50c0
@ -18,6 +18,7 @@ use core::fmt;
|
||||
use core::intrinsics;
|
||||
use core::kinds::Send;
|
||||
use core::mem;
|
||||
use core::option::Option;
|
||||
use core::raw::TraitObject;
|
||||
use core::result::{Ok, Err, Result};
|
||||
|
||||
@ -64,6 +65,10 @@ impl<T:PartialEq> PartialEq for Box<T> {
|
||||
fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
impl<T:PartialOrd> PartialOrd for Box<T> {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
|
||||
(**self).partial_cmp(*other)
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
|
||||
#[inline]
|
||||
|
@ -170,6 +170,11 @@ impl<T: PartialEq> PartialEq for Rc<T> {
|
||||
impl<T: Eq> Eq for Rc<T> {}
|
||||
|
||||
impl<T: PartialOrd> PartialOrd for Rc<T> {
|
||||
#[inline(always)]
|
||||
fn partial_cmp(&self, other: &Rc<T>) -> Option<Ordering> {
|
||||
(**self).partial_cmp(&**other)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn lt(&self, other: &Rc<T>) -> bool { **self < **other }
|
||||
|
||||
|
@ -107,8 +107,8 @@ impl<K: Ord, V: Eq> PartialEq for BTree<K, V> {
|
||||
impl<K: Ord, V: Eq> Eq for BTree<K, V> {}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for BTree<K, V> {
|
||||
fn lt(&self, other: &BTree<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &BTree<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,8 +229,8 @@ impl<K: Ord, V: Eq> PartialEq for Node<K, V> {
|
||||
impl<K: Ord, V: Eq> Eq for Node<K, V> {}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for Node<K, V> {
|
||||
fn lt(&self, other: &Node<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &Node<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,8 +408,8 @@ impl<K: Ord, V: Eq> PartialEq for Leaf<K, V> {
|
||||
impl<K: Ord, V: Eq> Eq for Leaf<K, V> {}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for Leaf<K, V> {
|
||||
fn lt(&self, other: &Leaf<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &Leaf<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
@ -638,8 +638,8 @@ impl<K: Ord, V: Eq> PartialEq for Branch<K, V> {
|
||||
impl<K: Ord, V: Eq> Eq for Branch<K, V> {}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for Branch<K, V> {
|
||||
fn lt(&self, other: &Branch<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &Branch<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
@ -706,8 +706,8 @@ impl<K: Ord, V: Eq> PartialEq for LeafElt<K, V> {
|
||||
impl<K: Ord, V: Eq> Eq for LeafElt<K, V> {}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for LeafElt<K, V> {
|
||||
fn lt(&self, other: &LeafElt<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &LeafElt<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
@ -755,8 +755,8 @@ impl<K: Ord, V: Eq> PartialEq for BranchElt<K, V>{
|
||||
impl<K: Ord, V: Eq> Eq for BranchElt<K, V>{}
|
||||
|
||||
impl<K: Ord, V: Eq> PartialOrd for BranchElt<K, V> {
|
||||
fn lt(&self, other: &BranchElt<K, V>) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &BranchElt<K, V>) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -595,17 +595,8 @@ impl<A: PartialEq> PartialEq for DList<A> {
|
||||
}
|
||||
|
||||
impl<A: PartialOrd> PartialOrd for DList<A> {
|
||||
fn lt(&self, other: &DList<A>) -> bool {
|
||||
iter::order::lt(self.iter(), other.iter())
|
||||
}
|
||||
fn le(&self, other: &DList<A>) -> bool {
|
||||
iter::order::le(self.iter(), other.iter())
|
||||
}
|
||||
fn gt(&self, other: &DList<A>) -> bool {
|
||||
iter::order::gt(self.iter(), other.iter())
|
||||
}
|
||||
fn ge(&self, other: &DList<A>) -> bool {
|
||||
iter::order::ge(self.iter(), other.iter())
|
||||
fn partial_cmp(&self, other: &DList<A>) -> Option<Ordering> {
|
||||
iter::order::partial_cmp(self.iter(), other.iter())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,8 +572,8 @@ impl<'a> Eq for MaybeOwned<'a> {}
|
||||
|
||||
impl<'a> PartialOrd for MaybeOwned<'a> {
|
||||
#[inline]
|
||||
fn lt(&self, other: &MaybeOwned) -> bool {
|
||||
self.as_slice().lt(&other.as_slice())
|
||||
fn partial_cmp(&self, other: &MaybeOwned) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,23 +56,11 @@ impl<K: PartialEq + Ord, V: PartialEq> PartialEq for TreeMap<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
// Lexicographical comparison
|
||||
fn lt<K: PartialOrd + Ord, V: PartialOrd>(a: &TreeMap<K, V>,
|
||||
b: &TreeMap<K, V>) -> bool {
|
||||
// the Zip iterator is as long as the shortest of a and b.
|
||||
for ((key_a, value_a), (key_b, value_b)) in a.iter().zip(b.iter()) {
|
||||
if *key_a < *key_b { return true; }
|
||||
if *key_a > *key_b { return false; }
|
||||
if *value_a < *value_b { return true; }
|
||||
if *value_a > *value_b { return false; }
|
||||
}
|
||||
|
||||
a.len() < b.len()
|
||||
}
|
||||
|
||||
impl<K: PartialOrd + Ord, V: PartialOrd> PartialOrd for TreeMap<K, V> {
|
||||
impl<K: Ord, V: PartialOrd> PartialOrd for TreeMap<K, V> {
|
||||
#[inline]
|
||||
fn lt(&self, other: &TreeMap<K, V>) -> bool { lt(self, other) }
|
||||
fn partial_cmp(&self, other: &TreeMap<K, V>) -> Option<Ordering> {
|
||||
iter::order::partial_cmp(self.iter(), other.iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Ord + Show, V: Show> Show for TreeMap<K, V> {
|
||||
@ -568,9 +556,11 @@ impl<T: PartialEq + Ord> PartialEq for TreeSet<T> {
|
||||
fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
|
||||
}
|
||||
|
||||
impl<T: PartialOrd + Ord> PartialOrd for TreeSet<T> {
|
||||
impl<T: Ord> PartialOrd for TreeSet<T> {
|
||||
#[inline]
|
||||
fn lt(&self, other: &TreeSet<T>) -> bool { self.map < other.map }
|
||||
fn partial_cmp(&self, other: &TreeSet<T>) -> Option<Ordering> {
|
||||
self.map.partial_cmp(&other.map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Ord + Show> Show for TreeSet<T> {
|
||||
|
@ -389,8 +389,8 @@ impl<T: PartialEq> PartialEq for Vec<T> {
|
||||
|
||||
impl<T: PartialOrd> PartialOrd for Vec<T> {
|
||||
#[inline]
|
||||
fn lt(&self, other: &Vec<T>) -> bool {
|
||||
self.as_slice() < other.as_slice()
|
||||
fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
|
||||
self.as_slice().partial_cmp(&other.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,10 @@
|
||||
//! assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
|
||||
//! ```
|
||||
|
||||
use option::{Option, Some};
|
||||
#[cfg(stage0)]
|
||||
use option::None;
|
||||
|
||||
/// Trait for values that can be compared for equality and inequality.
|
||||
///
|
||||
/// This trait allows for partial equality, for types that do not have an
|
||||
@ -127,7 +131,9 @@ impl Ord for Ordering {
|
||||
|
||||
impl PartialOrd for Ordering {
|
||||
#[inline]
|
||||
fn lt(&self, other: &Ordering) -> bool { (*self as int) < (*other as int) }
|
||||
fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
|
||||
(*self as int).partial_cmp(&(*other as int))
|
||||
}
|
||||
}
|
||||
|
||||
/// Combine orderings, lexically.
|
||||
@ -145,7 +151,7 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
|
||||
|
||||
/// Trait for values that can be compared for a sort-order.
|
||||
///
|
||||
/// PartialOrd only requires implementation of the `lt` method,
|
||||
/// PartialOrd only requires implementation of the `partial_cmp` method,
|
||||
/// with the others generated from default implementations.
|
||||
///
|
||||
/// However it remains possible to implement the others separately for types
|
||||
@ -154,20 +160,57 @@ pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
|
||||
/// 5.11).
|
||||
#[lang="ord"]
|
||||
pub trait PartialOrd: PartialEq {
|
||||
/// This method returns an ordering between `self` and `other` values
|
||||
/// if one exists.
|
||||
#[cfg(stage0)]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match (!self.lt(other), !other.lt(self)) {
|
||||
(false, false) => None,
|
||||
(false, true) => Some(Less),
|
||||
(true, false) => Some(Greater),
|
||||
(true, true) => Some(Equal),
|
||||
}
|
||||
}
|
||||
|
||||
/// This method returns an ordering between `self` and `other` values
|
||||
/// if one exists.
|
||||
#[cfg(not(stage0))]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering>;
|
||||
|
||||
/// This method tests less than (for `self` and `other`) and is used by the `<` operator.
|
||||
fn lt(&self, other: &Self) -> bool;
|
||||
fn lt(&self, other: &Self) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
Some(Less) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// This method tests less than or equal to (`<=`).
|
||||
#[inline]
|
||||
fn le(&self, other: &Self) -> bool { !other.lt(self) }
|
||||
fn le(&self, other: &Self) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
Some(Less) | Some(Equal) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// This method tests greater than (`>`).
|
||||
#[inline]
|
||||
fn gt(&self, other: &Self) -> bool { other.lt(self) }
|
||||
fn gt(&self, other: &Self) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
Some(Greater) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// This method tests greater than or equal to (`>=`).
|
||||
#[inline]
|
||||
fn ge(&self, other: &Self) -> bool { !self.lt(other) }
|
||||
fn ge(&self, other: &Self) -> bool {
|
||||
match self.partial_cmp(other) {
|
||||
Some(Greater) | Some(Equal) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The equivalence relation. Two values may be equivalent even if they are
|
||||
@ -195,6 +238,7 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
|
||||
mod impls {
|
||||
use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering,
|
||||
Less, Greater, Equal};
|
||||
use option::{Option, Some, None};
|
||||
|
||||
macro_rules! eq_impl(
|
||||
($($t:ty)*) => ($(
|
||||
@ -227,6 +271,15 @@ mod impls {
|
||||
macro_rules! ord_impl(
|
||||
($($t:ty)*) => ($(
|
||||
impl PartialOrd for $t {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
|
||||
match (self <= other, self >= other) {
|
||||
(false, false) => None,
|
||||
(false, true) => Some(Greater),
|
||||
(true, false) => Some(Less),
|
||||
(true, true) => Some(Equal),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
|
||||
#[inline]
|
||||
@ -241,13 +294,15 @@ mod impls {
|
||||
|
||||
impl PartialOrd for () {
|
||||
#[inline]
|
||||
fn lt(&self, _other: &()) -> bool { false }
|
||||
fn partial_cmp(&self, _: &()) -> Option<Ordering> {
|
||||
Some(Equal)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for bool {
|
||||
#[inline]
|
||||
fn lt(&self, other: &bool) -> bool {
|
||||
(*self as u8) < (*other as u8)
|
||||
fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
|
||||
(*self as u8).partial_cmp(&(*other as u8))
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,6 +343,10 @@ mod impls {
|
||||
fn ne(&self, other: & &'a T) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
impl<'a, T: PartialOrd> PartialOrd for &'a T {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &&'a T) -> Option<Ordering> {
|
||||
(**self).partial_cmp(*other)
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: & &'a T) -> bool { *(*self) < *(*other) }
|
||||
#[inline]
|
||||
@ -311,6 +370,10 @@ mod impls {
|
||||
fn ne(&self, other: &&'a mut T) -> bool { **self != *(*other) }
|
||||
}
|
||||
impl<'a, T: PartialOrd> PartialOrd for &'a mut T {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &&'a mut T) -> Option<Ordering> {
|
||||
(**self).partial_cmp(*other)
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: &&'a mut T) -> bool { **self < **other }
|
||||
#[inline]
|
||||
|
@ -2183,7 +2183,7 @@ impl<A: Clone> RandomAccessIterator<A> for Repeat<A> {
|
||||
pub mod order {
|
||||
use cmp;
|
||||
use cmp::{Eq, Ord, PartialOrd, PartialEq};
|
||||
use option::{Some, None};
|
||||
use option::{Option, Some, None};
|
||||
use super::Iterator;
|
||||
|
||||
/// Compare `a` and `b` for equality using `Eq`
|
||||
@ -2212,6 +2212,22 @@ pub mod order {
|
||||
}
|
||||
}
|
||||
|
||||
/// Order `a` and `b` lexicographically using `PartialOrd`
|
||||
pub fn partial_cmp<A: PartialOrd, T: Iterator<A>, S: Iterator<A>>(mut a: T, mut b: S)
|
||||
-> Option<cmp::Ordering> {
|
||||
loop {
|
||||
match (a.next(), b.next()) {
|
||||
(None, None) => return Some(cmp::Equal),
|
||||
(None, _ ) => return Some(cmp::Less),
|
||||
(_ , None) => return Some(cmp::Greater),
|
||||
(Some(x), Some(y)) => match x.partial_cmp(&y) {
|
||||
Some(cmp::Equal) => (),
|
||||
non_eq => return non_eq,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Compare `a` and `b` for equality (Using partial equality, `PartialEq`)
|
||||
pub fn eq<A: PartialEq, T: Iterator<A>, S: Iterator<A>>(mut a: T, mut b: S) -> bool {
|
||||
loop {
|
||||
|
@ -93,7 +93,7 @@ use intrinsics;
|
||||
use iter::{range, Iterator};
|
||||
use option::{Some, None, Option};
|
||||
|
||||
use cmp::{PartialEq, Eq, PartialOrd, Equiv};
|
||||
use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
|
||||
|
||||
/// Create a null pointer.
|
||||
///
|
||||
@ -488,11 +488,51 @@ mod externfnpointers {
|
||||
|
||||
// Comparison for pointers
|
||||
impl<T> PartialOrd for *const T {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
|
||||
if self < other {
|
||||
Some(Less)
|
||||
} else if self == other {
|
||||
Some(Equal)
|
||||
} else {
|
||||
Some(Greater)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn lt(&self, other: &*const T) -> bool { *self < *other }
|
||||
|
||||
#[inline]
|
||||
fn le(&self, other: &*const T) -> bool { *self <= *other }
|
||||
|
||||
#[inline]
|
||||
fn gt(&self, other: &*const T) -> bool { *self > *other }
|
||||
|
||||
#[inline]
|
||||
fn ge(&self, other: &*const T) -> bool { *self >= *other }
|
||||
}
|
||||
|
||||
impl<T> PartialOrd for *mut T {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
|
||||
if self < other {
|
||||
Some(Less)
|
||||
} else if self == other {
|
||||
Some(Equal)
|
||||
} else {
|
||||
Some(Greater)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn lt(&self, other: &*mut T) -> bool { *self < *other }
|
||||
|
||||
#[inline]
|
||||
fn le(&self, other: &*mut T) -> bool { *self <= *other }
|
||||
|
||||
#[inline]
|
||||
fn gt(&self, other: &*mut T) -> bool { *self > *other }
|
||||
|
||||
#[inline]
|
||||
fn ge(&self, other: &*mut T) -> bool { *self >= *other }
|
||||
}
|
||||
|
@ -253,6 +253,7 @@ pub mod traits {
|
||||
use cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering, Equiv};
|
||||
use iter::order;
|
||||
use collections::Collection;
|
||||
use option::Option;
|
||||
|
||||
impl<'a,T:PartialEq> PartialEq for &'a [T] {
|
||||
fn eq(&self, other: & &'a [T]) -> bool {
|
||||
@ -279,6 +280,11 @@ pub mod traits {
|
||||
}
|
||||
|
||||
impl<'a, T: PartialOrd> PartialOrd for &'a [T] {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &&'a [T]) -> Option<Ordering> {
|
||||
order::partial_cmp(self.iter(), other.iter())
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: & &'a [T]) -> bool {
|
||||
order::lt(self.iter(), other.iter())
|
||||
}
|
||||
|
@ -931,7 +931,7 @@ pub mod traits {
|
||||
use cmp::{Ord, Ordering, Less, Equal, Greater, PartialEq, PartialOrd, Equiv, Eq};
|
||||
use collections::Collection;
|
||||
use iter::Iterator;
|
||||
use option::{Some, None};
|
||||
use option::{Option, Some, None};
|
||||
use str::{Str, StrSlice, eq_slice};
|
||||
|
||||
impl<'a> Ord for &'a str {
|
||||
@ -962,7 +962,9 @@ pub mod traits {
|
||||
|
||||
impl<'a> PartialOrd for &'a str {
|
||||
#[inline]
|
||||
fn lt(&self, other: & &'a str) -> bool { self.cmp(other) == Less }
|
||||
fn partial_cmp(&self, other: &&'a str) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S: Str> Equiv<S> for &'a str {
|
||||
|
@ -64,6 +64,7 @@
|
||||
use clone::Clone;
|
||||
use cmp::*;
|
||||
use default::Default;
|
||||
use option::{Option, Some};
|
||||
|
||||
// macro for implementing n-ary tuple functions and operations
|
||||
macro_rules! tuple_impls {
|
||||
@ -125,6 +126,10 @@ macro_rules! tuple_impls {
|
||||
impl<$($T:Eq),+> Eq for ($($T,)+) {}
|
||||
|
||||
impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
|
||||
lexical_partial_cmp!($(self.$refN(), other.$refN()),+)
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: &($($T,)+)) -> bool {
|
||||
lexical_ord!(lt, $(self.$refN(), other.$refN()),+)
|
||||
@ -172,6 +177,16 @@ macro_rules! lexical_ord {
|
||||
($rel: ident, $a:expr, $b:expr) => { (*$a) . $rel ($b) };
|
||||
}
|
||||
|
||||
macro_rules! lexical_partial_cmp {
|
||||
($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
|
||||
match ($a).partial_cmp($b) {
|
||||
Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
|
||||
ordering => ordering
|
||||
}
|
||||
};
|
||||
($a:expr, $b:expr) => { ($a).partial_cmp($b) };
|
||||
}
|
||||
|
||||
macro_rules! lexical_cmp {
|
||||
($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
|
||||
match ($a).cmp($b) {
|
||||
|
@ -707,8 +707,8 @@ fn test_range() {
|
||||
}
|
||||
|
||||
impl PartialOrd for Foo {
|
||||
fn lt(&self, _: &Foo) -> bool {
|
||||
false
|
||||
fn partial_cmp(&self, _: &Foo) -> Option<Ordering> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,8 +73,8 @@ impl<'a, T: PartialEq> PartialEq for MaybeOwnedVector<'a, T> {
|
||||
impl<'a, T: Eq> Eq for MaybeOwnedVector<'a, T> {}
|
||||
|
||||
impl<'a, T: PartialOrd> PartialOrd for MaybeOwnedVector<'a, T> {
|
||||
fn lt(&self, other: &MaybeOwnedVector<T>) -> bool {
|
||||
self.as_slice().lt(&other.as_slice())
|
||||
fn partial_cmp(&self, other: &MaybeOwnedVector<T>) -> Option<Ordering> {
|
||||
self.as_slice().partial_cmp(&other.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,8 +91,8 @@ impl Eq for BigUint {}
|
||||
|
||||
impl PartialOrd for BigUint {
|
||||
#[inline]
|
||||
fn lt(&self, other: &BigUint) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &BigUint) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
@ -816,8 +816,8 @@ impl Eq for BigInt {}
|
||||
|
||||
impl PartialOrd for BigInt {
|
||||
#[inline]
|
||||
fn lt(&self, other: &BigInt) -> bool {
|
||||
self.cmp(other) == Less
|
||||
fn partial_cmp(&self, other: &BigInt) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,8 @@ macro_rules! cmp_impl {
|
||||
};
|
||||
}
|
||||
cmp_impl!(impl PartialEq, eq, ne)
|
||||
cmp_impl!(impl PartialOrd, lt, gt, le, ge)
|
||||
cmp_impl!(impl PartialOrd, lt -> bool, gt -> bool, le -> bool, ge -> bool,
|
||||
partial_cmp -> Option<cmp::Ordering>)
|
||||
cmp_impl!(impl Eq, )
|
||||
cmp_impl!(impl Ord, cmp -> cmp::Ordering)
|
||||
|
||||
|
@ -55,12 +55,12 @@ pub enum Identifier {
|
||||
|
||||
impl cmp::PartialOrd for Identifier {
|
||||
#[inline]
|
||||
fn lt(&self, other: &Identifier) -> bool {
|
||||
fn partial_cmp(&self, other: &Identifier) -> Option<Ordering> {
|
||||
match (self, other) {
|
||||
(&Numeric(a), &Numeric(b)) => a < b,
|
||||
(&Numeric(_), _) => true,
|
||||
(&AlphaNumeric(ref a), &AlphaNumeric(ref b)) => *a < *b,
|
||||
(&AlphaNumeric(_), _) => false
|
||||
(&Numeric(a), &Numeric(ref b)) => a.partial_cmp(b),
|
||||
(&Numeric(_), _) => Some(Less),
|
||||
(&AlphaNumeric(ref a), &AlphaNumeric(ref b)) => a.partial_cmp(b),
|
||||
(&AlphaNumeric(_), _) => Some(Greater)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -130,30 +130,31 @@ impl cmp::PartialEq for Version {
|
||||
|
||||
impl cmp::PartialOrd for Version {
|
||||
#[inline]
|
||||
fn lt(&self, other: &Version) -> bool {
|
||||
fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
|
||||
match self.major.partial_cmp(&other.major) {
|
||||
Some(Equal) => {}
|
||||
r => return r,
|
||||
}
|
||||
|
||||
self.major < other.major ||
|
||||
match self.minor.partial_cmp(&other.minor) {
|
||||
Some(Equal) => {}
|
||||
r => return r,
|
||||
}
|
||||
|
||||
(self.major == other.major &&
|
||||
self.minor < other.minor) ||
|
||||
match self.patch.partial_cmp(&other.patch) {
|
||||
Some(Equal) => {}
|
||||
r => return r,
|
||||
}
|
||||
|
||||
(self.major == other.major &&
|
||||
self.minor == other.minor &&
|
||||
self.patch < other.patch) ||
|
||||
|
||||
(self.major == other.major &&
|
||||
self.minor == other.minor &&
|
||||
self.patch == other.patch &&
|
||||
// NB: semver spec says 0.0.0-pre < 0.0.0
|
||||
// but the version of ord defined for vec
|
||||
// says that [] < [pre], so we alter it
|
||||
// here.
|
||||
(match (self.pre.len(), other.pre.len()) {
|
||||
(0, 0) => false,
|
||||
(0, _) => false,
|
||||
(_, 0) => true,
|
||||
(_, _) => self.pre < other.pre
|
||||
}))
|
||||
// NB: semver spec says 0.0.0-pre < 0.0.0
|
||||
// but the version of ord defined for vec
|
||||
// says that [] < [pre] so we alter it here
|
||||
match (self.pre.len(), other.pre.len()) {
|
||||
(0, 0) => Some(Equal),
|
||||
(0, _) => Some(Greater),
|
||||
(_, 0) => Some(Less),
|
||||
(_, _) => self.pre.partial_cmp(&other.pre)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,7 +244,7 @@ use std::vec::Vec;
|
||||
use Encodable;
|
||||
|
||||
/// Represents a json value
|
||||
#[deriving(Clone, PartialEq)]
|
||||
#[deriving(Clone, PartialEq, PartialOrd)]
|
||||
pub enum Json {
|
||||
Number(f64),
|
||||
String(String),
|
||||
@ -2087,62 +2087,6 @@ impl ::Decoder<DecoderError> for Decoder {
|
||||
}
|
||||
}
|
||||
|
||||
/// Test if two json values are less than one another
|
||||
impl PartialOrd for Json {
|
||||
fn lt(&self, other: &Json) -> bool {
|
||||
match *self {
|
||||
Number(f0) => {
|
||||
match *other {
|
||||
Number(f1) => f0 < f1,
|
||||
String(_) | Boolean(_) | List(_) | Object(_) |
|
||||
Null => true
|
||||
}
|
||||
}
|
||||
|
||||
String(ref s0) => {
|
||||
match *other {
|
||||
Number(_) => false,
|
||||
String(ref s1) => s0 < s1,
|
||||
Boolean(_) | List(_) | Object(_) | Null => true
|
||||
}
|
||||
}
|
||||
|
||||
Boolean(b0) => {
|
||||
match *other {
|
||||
Number(_) | String(_) => false,
|
||||
Boolean(b1) => b0 < b1,
|
||||
List(_) | Object(_) | Null => true
|
||||
}
|
||||
}
|
||||
|
||||
List(ref l0) => {
|
||||
match *other {
|
||||
Number(_) | String(_) | Boolean(_) => false,
|
||||
List(ref l1) => (*l0) < (*l1),
|
||||
Object(_) | Null => true
|
||||
}
|
||||
}
|
||||
|
||||
Object(ref d0) => {
|
||||
match *other {
|
||||
Number(_) | String(_) | Boolean(_) | List(_) => false,
|
||||
Object(ref d1) => d0 < d1,
|
||||
Null => true
|
||||
}
|
||||
}
|
||||
|
||||
Null => {
|
||||
match *other {
|
||||
Number(_) | String(_) | Boolean(_) | List(_) |
|
||||
Object(_) =>
|
||||
false,
|
||||
Null => true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for converting values to JSON
|
||||
pub trait ToJson {
|
||||
/// Converts the value of `self` to an instance of JSON
|
||||
|
@ -24,6 +24,7 @@ use default::Default;
|
||||
use fmt;
|
||||
use hash;
|
||||
use kinds::marker;
|
||||
use option::Option;
|
||||
use ops::Deref;
|
||||
use raw;
|
||||
|
||||
@ -58,6 +59,10 @@ impl<T: PartialEq + 'static> PartialEq for Gc<T> {
|
||||
fn ne(&self, other: &Gc<T>) -> bool { *(*self) != *(*other) }
|
||||
}
|
||||
impl<T: PartialOrd + 'static> PartialOrd for Gc<T> {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &Gc<T>) -> Option<Ordering> {
|
||||
(**self).partial_cmp(&**other)
|
||||
}
|
||||
#[inline]
|
||||
fn lt(&self, other: &Gc<T>) -> bool { *(*self) < *(*other) }
|
||||
#[inline]
|
||||
|
@ -43,22 +43,116 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
|
||||
} }
|
||||
);
|
||||
|
||||
let ordering_ty = Literal(Path::new(vec!["std", "cmp", "Ordering"]));
|
||||
let ret_ty = Literal(Path::new_(vec!["std", "option", "Option"],
|
||||
None,
|
||||
vec![box ordering_ty],
|
||||
true));
|
||||
|
||||
let inline = cx.meta_word(span, InternedString::new("inline"));
|
||||
let attrs = vec!(cx.attribute(span, inline));
|
||||
|
||||
let partial_cmp_def = MethodDef {
|
||||
name: "partial_cmp",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: borrowed_explicit_self(),
|
||||
args: vec![borrowed_self()],
|
||||
ret_ty: ret_ty,
|
||||
attributes: attrs,
|
||||
const_nonmatching: false,
|
||||
combine_substructure: combine_substructure(|cx, span, substr| {
|
||||
cs_partial_cmp(cx, span, substr)
|
||||
})
|
||||
};
|
||||
|
||||
let trait_def = TraitDef {
|
||||
span: span,
|
||||
attributes: Vec::new(),
|
||||
path: Path::new(vec!("std", "cmp", "PartialOrd")),
|
||||
additional_bounds: Vec::new(),
|
||||
attributes: vec![],
|
||||
path: Path::new(vec!["std", "cmp", "PartialOrd"]),
|
||||
additional_bounds: vec![],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: vec!(
|
||||
methods: vec![
|
||||
partial_cmp_def,
|
||||
md!("lt", true, false),
|
||||
md!("le", true, true),
|
||||
md!("gt", false, false),
|
||||
md!("ge", false, true)
|
||||
)
|
||||
]
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
||||
pub fn some_ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> Gc<ast::Expr> {
|
||||
let cnst = match cnst {
|
||||
Less => "Less",
|
||||
Equal => "Equal",
|
||||
Greater => "Greater"
|
||||
};
|
||||
let ordering = cx.path_global(span,
|
||||
vec!(cx.ident_of("std"),
|
||||
cx.ident_of("cmp"),
|
||||
cx.ident_of(cnst)));
|
||||
let ordering = cx.expr_path(ordering);
|
||||
cx.expr_some(span, ordering)
|
||||
}
|
||||
|
||||
pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
|
||||
substr: &Substructure) -> Gc<Expr> {
|
||||
let test_id = cx.ident_of("__test");
|
||||
let equals_expr = some_ordering_const(cx, span, Equal);
|
||||
|
||||
/*
|
||||
Builds:
|
||||
|
||||
let __test = self_field1.partial_cmp(&other_field2);
|
||||
if __test == ::std::option::Some(::std::cmp::Equal) {
|
||||
let __test = self_field2.partial_cmp(&other_field2);
|
||||
if __test == ::std::option::Some(::std::cmp::Equal) {
|
||||
...
|
||||
} else {
|
||||
__test
|
||||
}
|
||||
} else {
|
||||
__test
|
||||
}
|
||||
|
||||
FIXME #6449: These `if`s could/should be `match`es.
|
||||
*/
|
||||
cs_same_method_fold(
|
||||
// foldr nests the if-elses correctly, leaving the first field
|
||||
// as the outermost one, and the last as the innermost.
|
||||
false,
|
||||
|cx, span, old, new| {
|
||||
// let __test = new;
|
||||
// if __test == Some(::std::cmp::Equal) {
|
||||
// old
|
||||
// } else {
|
||||
// __test
|
||||
// }
|
||||
|
||||
let assign = cx.stmt_let(span, false, test_id, new);
|
||||
|
||||
let cond = cx.expr_binary(span, ast::BiEq,
|
||||
cx.expr_ident(span, test_id),
|
||||
equals_expr.clone());
|
||||
let if_ = cx.expr_if(span,
|
||||
cond,
|
||||
old, Some(cx.expr_ident(span, test_id)));
|
||||
cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
|
||||
},
|
||||
equals_expr.clone(),
|
||||
|cx, span, list, _| {
|
||||
match list {
|
||||
// an earlier nonmatching variant is Less than a
|
||||
// later one.
|
||||
[(self_var, _, _), (other_var, _, _)] =>
|
||||
some_ordering_const(cx, span, self_var.cmp(&other_var)),
|
||||
_ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
|
||||
}
|
||||
},
|
||||
cx, span, substr)
|
||||
}
|
||||
|
||||
/// Strict inequality.
|
||||
fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span,
|
||||
substr: &Substructure) -> Gc<Expr> {
|
||||
|
@ -27,6 +27,7 @@ enum Enum {
|
||||
//~^^^^^ ERROR
|
||||
//~^^^^^^ ERROR
|
||||
//~^^^^^^^ ERROR
|
||||
//~^^^^^^^^ ERROR
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ enum Enum {
|
||||
//~^^^^^ ERROR
|
||||
//~^^^^^^ ERROR
|
||||
//~^^^^^^^ ERROR
|
||||
//~^^^^^^^^ ERROR
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ struct Struct {
|
||||
//~^^^^^ ERROR
|
||||
//~^^^^^^ ERROR
|
||||
//~^^^^^^^ ERROR
|
||||
//~^^^^^^^^ ERROR
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -26,6 +26,7 @@ struct Struct(
|
||||
//~^^^^^ ERROR
|
||||
//~^^^^^^ ERROR
|
||||
//~^^^^^^^ ERROR
|
||||
//~^^^^^^^^ ERROR
|
||||
);
|
||||
|
||||
fn main() {}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
struct thing(uint);
|
||||
impl PartialOrd for thing { //~ ERROR not all trait methods implemented, missing: `lt`
|
||||
impl PartialOrd for thing { //~ ERROR not all trait methods implemented, missing: `partial_cmp`
|
||||
fn le(&self, other: &thing) -> bool { true }
|
||||
fn ge(&self, other: &thing) -> bool { true }
|
||||
}
|
||||
|
@ -31,10 +31,10 @@ impl PartialEq for Int {
|
||||
}
|
||||
|
||||
impl PartialOrd for Int {
|
||||
fn lt(&self, other: &Int) -> bool {
|
||||
fn partial_cmp(&self, other: &Int) -> Option<Ordering> {
|
||||
let Int(this) = *self;
|
||||
let Int(other) = *other;
|
||||
this < other
|
||||
this.partial_cmp(&other)
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,10 +49,10 @@ impl PartialEq for RevInt {
|
||||
}
|
||||
|
||||
impl PartialOrd for RevInt {
|
||||
fn lt(&self, other: &RevInt) -> bool {
|
||||
fn partial_cmp(&self, other: &RevInt) -> Option<Ordering> {
|
||||
let RevInt(this) = *self;
|
||||
let RevInt(other) = *other;
|
||||
this > other
|
||||
other.partial_cmp(&this)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ impl PartialEq for FailCmp {
|
||||
}
|
||||
|
||||
impl PartialOrd for FailCmp {
|
||||
fn lt(&self, _: &FailCmp) -> bool { fail!("lt") }
|
||||
fn partial_cmp(&self, _: &FailCmp) -> Option<Ordering> { fail!("partial_cmp") }
|
||||
}
|
||||
|
||||
impl Eq for FailCmp {}
|
||||
|
Loading…
Reference in New Issue
Block a user