rustc: Make <=, >=, and > use traits as well

This commit is contained in:
Patrick Walton 2012-08-29 19:23:15 -07:00
parent 70d3633c0b
commit a1c11cab2d
14 changed files with 192 additions and 23 deletions

View File

@ -42,6 +42,24 @@ impl package : cmp::Ord {
if self.versions.lt(other.versions) { return true; }
return false;
}
pure fn le(&&other: package) -> bool {
if self.name.lt(other.name) { return true; }
if other.name.lt(self.name) { return false; }
if self.uuid.lt(other.uuid) { return true; }
if other.uuid.lt(self.uuid) { return false; }
if self.url.lt(other.url) { return true; }
if other.url.lt(self.url) { return false; }
if self.method.lt(other.method) { return true; }
if other.method.lt(self.method) { return false; }
if self.description.lt(other.description) { return true; }
if other.description.lt(self.description) { return false; }
if self.tags.lt(other.tags) { return true; }
if other.tags.lt(self.tags) { return false; }
if self.versions.le(other.versions) { return true; }
return false;
}
pure fn ge(&&other: package) -> bool { !other.lt(self) }
pure fn gt(&&other: package) -> bool { !other.le(self) }
}
type local_package = {

View File

@ -19,6 +19,9 @@ impl<T:Eq> @const T : Eq {
impl<T:Ord> @const T : Ord {
pure fn lt(&&other: @const T) -> bool { *self < *other }
pure fn le(&&other: @const T) -> bool { *self <= *other }
pure fn ge(&&other: @const T) -> bool { *self >= *other }
pure fn gt(&&other: @const T) -> bool { *self > *other }
}
#[test]

View File

@ -9,11 +9,17 @@
#[lang="ord"]
trait Ord {
pure fn lt(&&other: self) -> bool;
pure fn le(&&other: self) -> bool;
pure fn ge(&&other: self) -> bool;
pure fn gt(&&other: self) -> bool;
}
#[cfg(test)]
trait Ord {
pure fn lt(&&other: self) -> bool;
pure fn le(&&other: self) -> bool;
pure fn ge(&&other: self) -> bool;
pure fn gt(&&other: self) -> bool;
}
#[cfg(notest)]
@ -38,3 +44,12 @@ pure fn le<T: Ord Eq>(v1: &T, v2: &T) -> bool {
pure fn eq<T: Eq>(v1: &T, v2: &T) -> bool {
v1.eq(v2)
}
pure fn ge<T: Ord>(v1: &T, v2: &T) -> bool {
v1.ge(v2)
}
pure fn gt<T: Ord>(v1: &T, v2: &T) -> bool {
v1.gt(v2)
}

View File

@ -421,6 +421,9 @@ impl float: Eq {
impl float: Ord {
pure fn lt(&&other: float) -> bool { self < other }
pure fn le(&&other: float) -> bool { self <= other }
pure fn ge(&&other: float) -> bool { self >= other }
pure fn gt(&&other: float) -> bool { self > other }
}
impl float: num::Num {

View File

@ -68,9 +68,10 @@ pure fn abs(i: T) -> T {
}
impl T: Ord {
pure fn lt(&&other: T) -> bool {
return self < other;
}
pure fn lt(&&other: T) -> bool { return self < other; }
pure fn le(&&other: T) -> bool { return self <= other; }
pure fn ge(&&other: T) -> bool { return self >= other; }
pure fn gt(&&other: T) -> bool { return self > other; }
}
impl T: Eq {

View File

@ -188,6 +188,21 @@ impl<T> *const T : Ord {
let b: uint = unsafe::reinterpret_cast(other);
return a < b;
}
pure fn le(&&other: *const T) -> bool unsafe {
let a: uint = unsafe::reinterpret_cast(self);
let b: uint = unsafe::reinterpret_cast(other);
return a <= b;
}
pure fn ge(&&other: *const T) -> bool unsafe {
let a: uint = unsafe::reinterpret_cast(self);
let b: uint = unsafe::reinterpret_cast(other);
return a >= b;
}
pure fn gt(&&other: *const T) -> bool unsafe {
let a: uint = unsafe::reinterpret_cast(self);
let b: uint = unsafe::reinterpret_cast(other);
return a > b;
}
}
// Equality for region pointers
@ -199,9 +214,10 @@ impl<T:Eq> &const T : Eq {
// Comparison for region pointers
impl<T:Ord> &const T : Ord {
pure fn lt(&&other: &const T) -> bool {
return *self < *other;
}
pure fn lt(&&other: &const T) -> bool { *self < *other }
pure fn le(&&other: &const T) -> bool { *self <= *other }
pure fn ge(&&other: &const T) -> bool { *self >= *other }
pure fn gt(&&other: &const T) -> bool { *self > *other }
}
#[test]

View File

@ -707,7 +707,30 @@ pure fn lt(a: &str, b: &str) -> bool {
}
/// Bytewise less than or equal
pure fn le(a: &~str, b: &~str) -> bool { *a <= *b }
pure fn le(a: &str, b: &str) -> bool {
let (a_len, b_len) = (a.len(), b.len());
let mut end = uint::min(&a_len, &b_len);
let mut i = 0;
while i < end {
let (c_a, c_b) = (a[i], b[i]);
if c_a < c_b { return true; }
if c_a > c_b { return false; }
i += 1;
}
return a_len <= b_len;
}
/// Bytewise greater than or equal
pure fn ge(a: &str, b: &str) -> bool {
!lt(b, a)
}
/// Bytewise greater than
pure fn gt(a: &str, b: &str) -> bool {
!le(b, a)
}
impl &str: Eq {
#[inline(always)]
@ -733,16 +756,34 @@ impl @str: Eq {
impl ~str : Ord {
#[inline(always)]
pure fn lt(&&other: ~str) -> bool { lt(self, other) }
#[inline(always)]
pure fn le(&&other: ~str) -> bool { le(self, other) }
#[inline(always)]
pure fn ge(&&other: ~str) -> bool { ge(self, other) }
#[inline(always)]
pure fn gt(&&other: ~str) -> bool { gt(self, other) }
}
impl &str : Ord {
#[inline(always)]
pure fn lt(&&other: &str) -> bool { lt(self, other) }
#[inline(always)]
pure fn le(&&other: &str) -> bool { le(self, other) }
#[inline(always)]
pure fn ge(&&other: &str) -> bool { ge(self, other) }
#[inline(always)]
pure fn gt(&&other: &str) -> bool { gt(self, other) }
}
impl @str : Ord {
#[inline(always)]
pure fn lt(&&other: @str) -> bool { lt(self, other) }
#[inline(always)]
pure fn le(&&other: @str) -> bool { le(self, other) }
#[inline(always)]
pure fn ge(&&other: @str) -> bool { ge(self, other) }
#[inline(always)]
pure fn gt(&&other: @str) -> bool { gt(self, other) }
}
/// String hash function

View File

@ -96,6 +96,22 @@ impl<A: Ord, B: Ord> (A, B): Ord {
}
}
}
pure fn le(&&other: (A, B)) -> bool {
match self {
(self_a, self_b) => {
match other {
(other_a, other_b) => {
if self_a.lt(other_a) { return true; }
if other_a.lt(self_a) { return false; }
if self_b.le(other_b) { return true; }
return false;
}
}
}
}
}
pure fn ge(&&other: (A, B)) -> bool { !other.lt(self) }
pure fn gt(&&other: (A, B)) -> bool { !other.ge(self) }
}
impl<A: Eq, B: Eq, C: Eq> (A, B, C): Eq {
@ -133,6 +149,24 @@ impl<A: Ord, B: Ord, C: Ord> (A, B, C): Ord {
}
}
}
pure fn le(&&other: (A, B, C)) -> bool {
match self {
(self_a, self_b, self_c) => {
match other {
(other_a, other_b, other_c) => {
if self_a.lt(other_a) { return true; }
if other_a.lt(self_a) { return false; }
if self_b.lt(other_b) { return true; }
if other_b.lt(self_b) { return false; }
if self_c.le(other_c) { return true; }
return false;
}
}
}
}
}
pure fn ge(&&other: (A, B, C)) -> bool { !other.lt(self) }
pure fn gt(&&other: (A, B, C)) -> bool { !other.ge(self) }
}
#[test]

View File

@ -61,9 +61,10 @@ pure fn compl(i: T) -> T {
}
impl T: Ord {
pure fn lt(&&other: T) -> bool {
return self < other;
}
pure fn lt(&&other: T) -> bool { self < other }
pure fn le(&&other: T) -> bool { self <= other }
pure fn ge(&&other: T) -> bool { self >= other }
pure fn gt(&&other: T) -> bool { self > other }
}
impl T: Eq {

View File

@ -8,5 +8,8 @@ impl<T:Eq> ~const T : Eq {
impl<T:Ord> ~const T : Ord {
pure fn lt(&&other: ~const T) -> bool { *self < *other }
pure fn le(&&other: ~const T) -> bool { *self <= *other }
pure fn ge(&&other: ~const T) -> bool { *self >= *other }
pure fn gt(&&other: ~const T) -> bool { *self > *other }
}

View File

@ -1443,25 +1443,55 @@ pure fn lt<T: Ord>(a: &[T], b: &[T]) -> bool {
return a_len < b_len;
}
pure fn le<T: Ord>(a: &[T], b: &[T]) -> bool {
let (a_len, b_len) = (a.len(), b.len());
let mut end = uint::min(&a_len, &b_len);
let mut i = 0;
while i < end {
let (c_a, c_b) = (&a[i], &b[i]);
if *c_a < *c_b { return true; }
if *c_a > *c_b { return false; }
i += 1;
}
return a_len <= b_len;
}
pure fn ge<T: Ord>(a: &[T], b: &[T]) -> bool { !lt(b, a) }
pure fn gt<T: Ord>(a: &[T], b: &[T]) -> bool { !le(b, a) }
impl<T: Ord> &[T]: Ord {
#[inline(always)]
pure fn lt(&&other: &[T]) -> bool {
lt(self, other)
}
pure fn lt(&&other: &[T]) -> bool { lt(self, other) }
#[inline(always)]
pure fn le(&&other: &[T]) -> bool { le(self, other) }
#[inline(always)]
pure fn ge(&&other: &[T]) -> bool { ge(self, other) }
#[inline(always)]
pure fn gt(&&other: &[T]) -> bool { gt(self, other) }
}
impl<T: Ord> ~[T]: Ord {
#[inline(always)]
pure fn lt(&&other: ~[T]) -> bool {
lt(self, other)
}
pure fn lt(&&other: ~[T]) -> bool { lt(self, other) }
#[inline(always)]
pure fn le(&&other: ~[T]) -> bool { le(self, other) }
#[inline(always)]
pure fn ge(&&other: ~[T]) -> bool { ge(self, other) }
#[inline(always)]
pure fn gt(&&other: ~[T]) -> bool { gt(self, other) }
}
impl<T: Ord> @[T]: Ord {
#[inline(always)]
pure fn lt(&&other: @[T]) -> bool {
lt(self, other)
}
pure fn lt(&&other: @[T]) -> bool { lt(self, other) }
#[inline(always)]
pure fn le(&&other: @[T]) -> bool { le(self, other) }
#[inline(always)]
pure fn ge(&&other: @[T]) -> bool { ge(self, other) }
#[inline(always)]
pure fn gt(&&other: @[T]) -> bool { gt(self, other) }
}
#[cfg(notest)]

View File

@ -217,7 +217,7 @@ fn print_failures(st: console_test_state) {
st.out.write_line(~"\nfailures:");
let failures = copy st.failures;
let failures = vec::map(failures, |test| test.name);
let failures = sort::merge_sort(str::le, failures);
let failures = sort::merge_sort(|x, y| str::le(*x, *y), failures);
for vec::each(failures) |name| {
st.out.write_line(fmt!(" %s", name));
}
@ -371,7 +371,7 @@ fn filter_tests(opts: test_opts,
// Sort the tests alphabetically
filtered = {
pure fn lteq(t1: &test_desc, t2: &test_desc) -> bool {
str::le(&t1.name, &t2.name)
str::le(t1.name, t2.name)
}
sort::merge_sort(lteq, filtered)
};

View File

@ -106,8 +106,11 @@ pure fn binop_to_method_name(op: binop) -> Option<~str> {
shl => return Some(~"shl"),
shr => return Some(~"shr"),
lt => return Some(~"lt"),
le => return Some(~"le"),
ge => return Some(~"ge"),
gt => return Some(~"gt"),
eq => return Some(~"eq"),
and | or | le | ne | ge | gt => return None
and | or | ne => return None
}
}

View File

@ -4341,7 +4341,8 @@ struct Resolver {
self.add_fixed_trait_for_expr(expr.id,
self.lang_items.shr_trait);
}
expr_binary(lt, _, _) => {
expr_binary(lt, _, _) | expr_binary(le, _, _) |
expr_binary(ge, _, _) | expr_binary(gt, _, _) => {
self.add_fixed_trait_for_expr(expr.id,
self.lang_items.ord_trait);
}