add a TotalOrd trait
This commit is contained in:
parent
a660bb362c
commit
ca1ceb15b1
4 changed files with 166 additions and 11 deletions
|
@ -37,6 +37,70 @@ pub trait Eq {
|
||||||
pure fn ne(&self, other: &Self) -> bool;
|
pure fn ne(&self, other: &Self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving_eq]
|
||||||
|
pub enum Ordering { Less, Equal, Greater }
|
||||||
|
|
||||||
|
/// Trait for types that form a total order
|
||||||
|
pub trait TotalOrd {
|
||||||
|
pure fn cmp(&self, other: &Self) -> Ordering;
|
||||||
|
}
|
||||||
|
|
||||||
|
pure fn icmp<T: Ord>(a: &T, b: &T) -> Ordering {
|
||||||
|
if *a < *b { Less }
|
||||||
|
else if *a > *b { Greater }
|
||||||
|
else { Equal }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TotalOrd for u8 {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &u8) -> Ordering { icmp(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TotalOrd for u16 {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &u16) -> Ordering { icmp(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TotalOrd for u32 {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &u32) -> Ordering { icmp(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TotalOrd for u64 {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &u64) -> Ordering { icmp(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TotalOrd for i8 {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &i8) -> Ordering { icmp(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TotalOrd for i16 {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &i16) -> Ordering { icmp(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TotalOrd for i32 {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &i32) -> Ordering { icmp(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TotalOrd for i64 {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &i64) -> Ordering { icmp(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TotalOrd for int {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &int) -> Ordering { icmp(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TotalOrd for uint {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &uint) -> Ordering { icmp(self, other) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trait for values that can be compared for a sort-order.
|
* Trait for values that can be compared for a sort-order.
|
||||||
*
|
*
|
||||||
|
@ -94,3 +158,15 @@ pub pure fn min<T:Ord>(v1: T, v2: T) -> T {
|
||||||
pub pure fn max<T:Ord>(v1: T, v2: T) -> T {
|
pub pure fn max<T:Ord>(v1: T, v2: T) -> T {
|
||||||
if v1 > v2 { v1 } else { v2 }
|
if v1 > v2 { v1 } else { v2 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
#[test]
|
||||||
|
fn test_int() {
|
||||||
|
assert 5.cmp(&10) == Less;
|
||||||
|
assert 10.cmp(&5) == Greater;
|
||||||
|
assert 5.cmp(&5) == Equal;
|
||||||
|
assert (-5).cmp(&12) == Less;
|
||||||
|
assert 12.cmp(-5) == Greater;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub use result::{Result, Ok, Err};
|
||||||
/* Reexported types and traits */
|
/* Reexported types and traits */
|
||||||
|
|
||||||
pub use clone::Clone;
|
pub use clone::Clone;
|
||||||
pub use cmp::{Eq, Ord};
|
pub use cmp::{Eq, Ord, TotalOrd, Ordering, Less, Equal, Greater};
|
||||||
pub use container::{Container, Mutable, Map, Set};
|
pub use container::{Container, Mutable, Map, Set};
|
||||||
pub use hash::Hash;
|
pub use hash::Hash;
|
||||||
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
|
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
use at_vec;
|
use at_vec;
|
||||||
use cast;
|
use cast;
|
||||||
use char;
|
use char;
|
||||||
use cmp::{Eq, Ord};
|
use cmp::{Eq, Ord, TotalOrd, Ordering, Less, Equal, Greater};
|
||||||
use libc;
|
use libc;
|
||||||
use libc::size_t;
|
use libc::size_t;
|
||||||
use io::WriterUtil;
|
use io::WriterUtil;
|
||||||
|
@ -773,6 +773,35 @@ pub pure fn eq(a: &~str, b: &~str) -> bool {
|
||||||
eq_slice(*a, *b)
|
eq_slice(*a, *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pure fn cmp(a: &str, b: &str) -> Ordering {
|
||||||
|
let low = uint::min(a.len(), b.len());
|
||||||
|
|
||||||
|
for uint::range(0, low) |idx| {
|
||||||
|
match a[idx].cmp(&b[idx]) {
|
||||||
|
Greater => return Greater,
|
||||||
|
Less => return Less,
|
||||||
|
Equal => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.len().cmp(&b.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(notest)]
|
||||||
|
impl TotalOrd for &str {
|
||||||
|
pure fn cmp(&self, other: & &self/str) -> Ordering { cmp(*self, *other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(notest)]
|
||||||
|
impl TotalOrd for ~str {
|
||||||
|
pure fn cmp(&self, other: &~str) -> Ordering { cmp(*self, *other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(notest)]
|
||||||
|
impl TotalOrd for @str {
|
||||||
|
pure fn cmp(&self, other: &@str) -> Ordering { cmp(*self, *other) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Bytewise slice less than
|
/// Bytewise slice less than
|
||||||
pure fn lt(a: &str, b: &str) -> bool {
|
pure fn lt(a: &str, b: &str) -> bool {
|
||||||
let (a_len, b_len) = (a.len(), b.len());
|
let (a_len, b_len) = (a.len(), b.len());
|
||||||
|
@ -2382,6 +2411,7 @@ mod tests {
|
||||||
use ptr;
|
use ptr;
|
||||||
use str::*;
|
use str::*;
|
||||||
use vec;
|
use vec;
|
||||||
|
use cmp::{TotalOrd, Less, Equal, Greater};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_eq() {
|
fn test_eq() {
|
||||||
|
@ -3388,4 +3418,12 @@ mod tests {
|
||||||
assert view("abcdef", 1, 5).to_managed() == @"bcde";
|
assert view("abcdef", 1, 5).to_managed() == @"bcde";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_total_ord() {
|
||||||
|
"1234".cmp(& &"123") == Greater;
|
||||||
|
"123".cmp(& &"1234") == Less;
|
||||||
|
"1234".cmp(& &"1234") == Equal;
|
||||||
|
"12345555".cmp(& &"123456") == Less;
|
||||||
|
"22".cmp(& &"1234") == Greater;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
use container::{Container, Mutable};
|
use container::{Container, Mutable};
|
||||||
use cast::transmute;
|
use cast::transmute;
|
||||||
use cast;
|
use cast;
|
||||||
use cmp::{Eq, Ord};
|
use cmp::{Eq, Ord, TotalOrd, Ordering, Less, Equal, Greater};
|
||||||
use iter::BaseIter;
|
use iter::BaseIter;
|
||||||
use iter;
|
use iter;
|
||||||
use kinds::Copy;
|
use kinds::Copy;
|
||||||
|
@ -1425,7 +1425,7 @@ pub pure fn rev_eachi<T>(v: &r/[T], blk: fn(i: uint, v: &r/T) -> bool) {
|
||||||
* Both vectors must have the same length
|
* Both vectors must have the same length
|
||||||
*/
|
*/
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn each2<U, T>(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) {
|
pub pure fn each2<U, T>(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) {
|
||||||
assert len(v1) == len(v2);
|
assert len(v1) == len(v2);
|
||||||
for uint::range(0u, len(v1)) |i| {
|
for uint::range(0u, len(v1)) |i| {
|
||||||
if !f(&v1[i], &v2[i]) {
|
if !f(&v1[i], &v2[i]) {
|
||||||
|
@ -1575,6 +1575,38 @@ impl<T:Eq> Eq for @[T] {
|
||||||
|
|
||||||
// Lexicographical comparison
|
// Lexicographical comparison
|
||||||
|
|
||||||
|
pure fn cmp<T: TotalOrd>(a: &[T], b: &[T]) -> Ordering {
|
||||||
|
let low = uint::min(a.len(), b.len());
|
||||||
|
|
||||||
|
for uint::range(0, low) |idx| {
|
||||||
|
match a[idx].cmp(&b[idx]) {
|
||||||
|
Greater => return Greater,
|
||||||
|
Less => return Less,
|
||||||
|
Equal => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.len().cmp(&b.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(notest)]
|
||||||
|
impl<T: TotalOrd> TotalOrd for &[T] {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: & &self/[T]) -> Ordering { cmp(*self, *other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(notest)]
|
||||||
|
impl<T: TotalOrd> TotalOrd for ~[T] {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(notest)]
|
||||||
|
impl<T: TotalOrd> TotalOrd for @[T] {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) }
|
||||||
|
}
|
||||||
|
|
||||||
pure fn lt<T:Ord>(a: &[T], b: &[T]) -> bool {
|
pure fn lt<T:Ord>(a: &[T], b: &[T]) -> bool {
|
||||||
let (a_len, b_len) = (a.len(), b.len());
|
let (a_len, b_len) = (a.len(), b.len());
|
||||||
let mut end = uint::min(a_len, b_len);
|
let mut end = uint::min(a_len, b_len);
|
||||||
|
@ -2151,7 +2183,7 @@ pub mod bytes {
|
||||||
use vec;
|
use vec;
|
||||||
|
|
||||||
/// Bytewise string comparison
|
/// Bytewise string comparison
|
||||||
pub pure fn cmp(a: &~[u8], b: &~[u8]) -> int {
|
pub pure fn memcmp(a: &~[u8], b: &~[u8]) -> int {
|
||||||
let a_len = len(*a);
|
let a_len = len(*a);
|
||||||
let b_len = len(*b);
|
let b_len = len(*b);
|
||||||
let n = uint::min(a_len, b_len) as libc::size_t;
|
let n = uint::min(a_len, b_len) as libc::size_t;
|
||||||
|
@ -2172,22 +2204,22 @@ pub mod bytes {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bytewise less than or equal
|
/// Bytewise less than or equal
|
||||||
pub pure fn lt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) < 0 }
|
pub pure fn lt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) < 0 }
|
||||||
|
|
||||||
/// Bytewise less than or equal
|
/// Bytewise less than or equal
|
||||||
pub pure fn le(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) <= 0 }
|
pub pure fn le(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) <= 0 }
|
||||||
|
|
||||||
/// Bytewise equality
|
/// Bytewise equality
|
||||||
pub pure fn eq(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) == 0 }
|
pub pure fn eq(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) == 0 }
|
||||||
|
|
||||||
/// Bytewise inequality
|
/// Bytewise inequality
|
||||||
pub pure fn ne(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) != 0 }
|
pub pure fn ne(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) != 0 }
|
||||||
|
|
||||||
/// Bytewise greater than or equal
|
/// Bytewise greater than or equal
|
||||||
pub pure fn ge(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) >= 0 }
|
pub pure fn ge(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) >= 0 }
|
||||||
|
|
||||||
/// Bytewise greater than
|
/// Bytewise greater than
|
||||||
pub pure fn gt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) > 0 }
|
pub pure fn gt(a: &~[u8], b: &~[u8]) -> bool { memcmp(a, b) > 0 }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies data from one vector to another.
|
* Copies data from one vector to another.
|
||||||
|
@ -2429,6 +2461,7 @@ mod tests {
|
||||||
use option;
|
use option;
|
||||||
use sys;
|
use sys;
|
||||||
use vec::*;
|
use vec::*;
|
||||||
|
use cmp::*;
|
||||||
|
|
||||||
fn square(n: uint) -> uint { return n * n; }
|
fn square(n: uint) -> uint { return n * n; }
|
||||||
|
|
||||||
|
@ -3942,6 +3975,14 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_total_ord() {
|
||||||
|
[1, 2, 3, 4].cmp(& &[1, 2, 3]) == Greater;
|
||||||
|
[1, 2, 3].cmp(& &[1, 2, 3, 4]) == Less;
|
||||||
|
[1, 2, 3, 4].cmp(& &[1, 2, 3, 4]) == Equal;
|
||||||
|
[1, 2, 3, 4, 5, 5, 5, 5].cmp(& &[1, 2, 3, 4, 5, 6]) == Less;
|
||||||
|
[2, 2].cmp(& &[1, 2, 3, 4]) == Greater;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue