diff options
| author | Huon Wilson <dbau.pp+github@gmail.com> | 2013-12-20 14:42:00 +1100 |
|---|---|---|
| committer | Huon Wilson <dbau.pp+github@gmail.com> | 2013-12-22 18:16:50 +1100 |
| commit | 2e8c522c6206eacb8f8d5e2d30590c4080cbed7a (patch) | |
| tree | 93ebeaa7880139d5ec21114aeec644c872b9c254 | |
| parent | 1b1e4caa79077d48c1bf56bf5bfa7bfc83fdf941 (diff) | |
| download | rust-2e8c522c6206eacb8f8d5e2d30590c4080cbed7a.tar.gz rust-2e8c522c6206eacb8f8d5e2d30590c4080cbed7a.zip | |
std::vec: make the sorting closure use `Ordering` rather than just being
(implicitly) less_eq.
| -rw-r--r-- | src/libextra/glob.rs | 2 | ||||
| -rw-r--r-- | src/libextra/priority_queue.rs | 4 | ||||
| -rw-r--r-- | src/libextra/stats.rs | 25 | ||||
| -rw-r--r-- | src/libextra/test.rs | 5 | ||||
| -rw-r--r-- | src/librustc/metadata/cstore.rs | 2 | ||||
| -rw-r--r-- | src/librustc/metadata/encoder.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/check_match.rs | 4 | ||||
| -rw-r--r-- | src/librustc/middle/lint.rs | 12 | ||||
| -rw-r--r-- | src/librustc/middle/trans/base.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/html/render.rs | 56 | ||||
| -rw-r--r-- | src/libstd/prelude.rs | 3 | ||||
| -rw-r--r-- | src/libstd/vec.rs | 86 | ||||
| -rw-r--r-- | src/libsyntax/attr.rs | 6 | ||||
| -rw-r--r-- | src/test/bench/shootout-k-nucleotide-pipes.rs | 43 | ||||
| -rw-r--r-- | src/test/run-pass/vector-sort-failure-safe.rs | 6 |
15 files changed, 118 insertions, 140 deletions
diff --git a/src/libextra/glob.rs b/src/libextra/glob.rs index 78651b818fa..1182d526fa4 100644 --- a/src/libextra/glob.rs +++ b/src/libextra/glob.rs @@ -148,7 +148,7 @@ impl Iterator<Path> for GlobIterator { fn list_dir_sorted(path: &Path) -> ~[Path] { match io::result(|| fs::readdir(path)) { Ok(mut children) => { - children.sort_by(|p1, p2| p2.filename() <= p1.filename()); + children.sort_by(|p1, p2| p2.filename().cmp(&p1.filename())); children } Err(..) => ~[] diff --git a/src/libextra/priority_queue.rs b/src/libextra/priority_queue.rs index 3c1743cfe34..bba7d767732 100644 --- a/src/libextra/priority_queue.rs +++ b/src/libextra/priority_queue.rs @@ -231,11 +231,7 @@ mod tests { fn test_top_and_pop() { let data = ~[2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]; let mut sorted = data.clone(); -<<<<<<< HEAD - sorted.sort(|x, y| x.le(y)); -======= sorted.sort(); ->>>>>>> 9ceda35... std::vec: add a sugary .sort() method for plain Ord sorting. let mut heap = PriorityQueue::from_vec(data); while !heap.is_empty() { assert_eq!(heap.top(), sorted.last()); diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs index ba8f7d4f23f..5f3700fec07 100644 --- a/src/libextra/stats.rs +++ b/src/libextra/stats.rs @@ -19,6 +19,25 @@ use std::util; // NB: this can probably be rewritten in terms of num::Num // to be less f64-specific. +fn f64_cmp(x: f64, y: f64) -> Ordering { + // arbitrarily decide that NaNs are larger than everything. + if y.is_nan() { + Less + } else if x.is_nan() { + Greater + } else if x < y { + Less + } else if x == y { + Equal + } else { + Greater + } +} + +fn f64_sort(v: &mut [f64]) { + v.sort_by(|x: &f64, y: &f64| f64_cmp(*x, *y)); +} + /// Trait that provides simple descriptive statistics on a univariate set of numeric samples. pub trait Stats { @@ -239,13 +258,13 @@ impl<'a> Stats for &'a [f64] { fn percentile(self, pct: f64) -> f64 { let mut tmp = self.to_owned(); - tmp.sort(); + f64_sort(tmp); percentile_of_sorted(tmp, pct) } fn quartiles(self) -> (f64,f64,f64) { let mut tmp = self.to_owned(); - tmp.sort(); + f64_sort(tmp); let a = percentile_of_sorted(tmp, 25.0); let b = percentile_of_sorted(tmp, 50.0); let c = percentile_of_sorted(tmp, 75.0); @@ -290,7 +309,7 @@ fn percentile_of_sorted(sorted_samples: &[f64], /// See: http://en.wikipedia.org/wiki/Winsorising pub fn winsorize(samples: &mut [f64], pct: f64) { let mut tmp = samples.to_owned(); - tmp.sort(); + f64_sort(tmp); let lo = percentile_of_sorted(tmp, pct); let hi = percentile_of_sorted(tmp, 100.0-pct); for samp in samples.mut_iter() { diff --git a/src/libextra/test.rs b/src/libextra/test.rs index dd29a4d8d47..3d6dfd612f2 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -837,10 +837,7 @@ pub fn filter_tests( }; // Sort the tests alphabetically - fn lteq(t1: &TestDescAndFn, t2: &TestDescAndFn) -> bool { - t1.desc.name.to_str() <= t2.desc.name.to_str() - } - filtered.sort_by(lteq); + filtered.sort_by(|t1, t2| t1.desc.name.to_str().cmp(&t2.desc.name.to_str())); // Shard the remaining tests, if sharding requested. match opts.test_shard { diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 6eb280df8ee..d6c79e7861c 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -167,7 +167,7 @@ pub fn find_extern_mod_stmt_cnum(cstore: &CStore, cstore.extern_mod_crate_map.find(&emod_id).map(|x| *x) } -#[deriving(Clone)] +#[deriving(Clone, TotalEq, TotalOrd)] struct crate_hash { name: @str, vers: @str, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 5e709f0296c..5b2a51e419f 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1531,7 +1531,7 @@ fn encode_crate_deps(ecx: &EncodeContext, }); // Sort by cnum - deps.sort_by(|kv1, kv2| kv1.cnum <= kv2.cnum); + deps.sort_by(|kv1, kv2| kv1.cnum.cmp(&kv2.cnum)); // Sanity-check the crate numbers let mut expected_cnum = 1; diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 4d4cda82055..948c7932ca0 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -466,9 +466,9 @@ fn missing_ctor(cx: &MatchCheckCtxt, // those with a destructured slice come first. vec_pat_lens.sort_by(|&(len1, slice1), &(len2, slice2)| { if len1 == len2 { - slice1 > slice2 + slice2.cmp(&slice1) } else { - len1 <= len2 + len1.cmp(&len2) } }); vec_pat_lens.dedup(); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index bdf4c550378..9ec0fa33716 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -63,7 +63,7 @@ use syntax::{ast, ast_util, visit}; use syntax::ast_util::IdVisitingOperation; use syntax::visit::Visitor; -#[deriving(Clone, Eq)] +#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd)] pub enum lint { ctypes, unused_imports, @@ -110,20 +110,16 @@ pub fn level_to_str(lv: level) -> &'static str { } } -#[deriving(Clone, Eq, Ord)] +#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd)] pub enum level { allow, warn, deny, forbid } -#[deriving(Clone, Eq)] +#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd)] pub struct LintSpec { + default: level, lint: lint, desc: &'static str, - default: level -} - -impl Ord for LintSpec { - fn lt(&self, other: &LintSpec) -> bool { self.default < other.default } } pub type LintDict = HashMap<&'static str, LintSpec>; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 831c3ccce9d..c562a78b961 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -3163,7 +3163,7 @@ pub fn trans_crate(sess: session::Session, println!("n_closures: {}", ccx.stats.n_closures); println("fn stats:"); - ccx.stats.fn_stats.sort_by(|&(_, _, insns_a), &(_, _, insns_b)| insns_a >= insns_b); + ccx.stats.fn_stats.sort_by(|&(_, _, insns_a), &(_, _, insns_b)| insns_b.cmp(&insns_a)); for tuple in ccx.stats.fn_stats.iter() { match *tuple { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index b474bbca865..8a14e37c816 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -898,44 +898,44 @@ fn item_module(w: &mut Writer, cx: &Context, debug!("{:?}", items); let mut indices = vec::from_fn(items.len(), |i| i); - fn le(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> bool { + fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering { if shortty(i1) == shortty(i2) { - return i1.name <= i2.name; + return i1.name.cmp(&i2.name); } match (&i1.inner, &i2.inner) { (&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => { match (&a.inner, &b.inner) { - (&clean::ExternMod(..), _) => true, - (_, &clean::ExternMod(..)) => false, - _ => idx1 <= idx2, + (&clean::ExternMod(..), _) => Less, + (_, &clean::ExternMod(..)) => Greater, + _ => idx1.cmp(&idx2), } } - (&clean::ViewItemItem(..), _) => true, - (_, &clean::ViewItemItem(..)) => false, - (&clean::ModuleItem(..), _) => true, - (_, &clean::ModuleItem(..)) => false, - (&clean::StructItem(..), _) => true, - (_, &clean::StructItem(..)) => false, - (&clean::EnumItem(..), _) => true, - (_, &clean::EnumItem(..)) => false, - (&clean::StaticItem(..), _) => true, - (_, &clean::StaticItem(..)) => false, - (&clean::ForeignFunctionItem(..), _) => true, - (_, &clean::ForeignFunctionItem(..)) => false, - (&clean::ForeignStaticItem(..), _) => true, - (_, &clean::ForeignStaticItem(..)) => false, - (&clean::TraitItem(..), _) => true, - (_, &clean::TraitItem(..)) => false, - (&clean::FunctionItem(..), _) => true, - (_, &clean::FunctionItem(..)) => false, - (&clean::TypedefItem(..), _) => true, - (_, &clean::TypedefItem(..)) => false, - _ => idx1 <= idx2, + (&clean::ViewItemItem(..), _) => Less, + (_, &clean::ViewItemItem(..)) => Greater, + (&clean::ModuleItem(..), _) => Less, + (_, &clean::ModuleItem(..)) => Greater, + (&clean::StructItem(..), _) => Less, + (_, &clean::StructItem(..)) => Greater, + (&clean::EnumItem(..), _) => Less, + (_, &clean::EnumItem(..)) => Greater, + (&clean::StaticItem(..), _) => Less, + (_, &clean::StaticItem(..)) => Greater, + (&clean::ForeignFunctionItem(..), _) => Less, + (_, &clean::ForeignFunctionItem(..)) => Greater, + (&clean::ForeignStaticItem(..), _) => Less, + (_, &clean::ForeignStaticItem(..)) => Greater, + (&clean::TraitItem(..), _) => Less, + (_, &clean::TraitItem(..)) => Greater, + (&clean::FunctionItem(..), _) => Less, + (_, &clean::FunctionItem(..)) => Greater, + (&clean::TypedefItem(..), _) => Less, + (_, &clean::TypedefItem(..)) => Greater, + _ => idx1.cmp(&idx2), } } debug!("{:?}", indices); - indices.sort_by(|&i1, &i2| le(&items[i1], &items[i2], i1, i2)); + indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2)); debug!("{:?}", indices); let mut curty = ""; @@ -1530,7 +1530,7 @@ fn build_sidebar(m: &clean::Module) -> HashMap<~str, ~[~str]> { } for (_, items) in map.mut_iter() { - items.sort(|i1, i2| i1 <= i2); + items.sort(); } return map; } diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 91aa3470ff4..583e87370bc 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -79,7 +79,8 @@ pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4}; pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8}; pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12}; pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCopyableVector}; -pub use vec::{OwnedVector, OwnedCopyableVector,OwnedEqVector, MutableVector, MutableOrdVector}; +pub use vec::{OwnedVector, OwnedCopyableVector,OwnedEqVector}; +pub use vec::{MutableVector, MutableTotalOrdVector}; pub use vec::{Vector, VectorVector, CopyableVector, ImmutableVector}; // Reexported runtime types diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 58392774fa0..d31fe0ee434 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1921,7 +1921,7 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] { } } -fn merge_sort<T>(v: &mut [T], less_eq: |&T, &T| -> bool) { +fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) { // warning: this wildly uses unsafe. static INSERTION: uint = 8; @@ -1930,7 +1930,7 @@ fn merge_sort<T>(v: &mut [T], less_eq: |&T, &T| -> bool) { // allocate some memory to use as scratch memory, we keep the // length 0 so we can keep shallow copies of the contents of `v` // without risking the dtors running on an object twice if - // `less_eq` fails. + // `compare` fails. let mut working_space = with_capacity(2 * len); // these both are buffers of length `len`. let mut buf_dat = working_space.as_mut_ptr(); @@ -1960,7 +1960,8 @@ fn merge_sort<T>(v: &mut [T], less_eq: |&T, &T| -> bool) { // start <= j - 1 < len, so .offset(j - 1) is in // bounds. - while j > start as int && !less_eq(&*buf_dat.offset(j - 1), &*read_ptr) { + while j > start as int && + compare(&*read_ptr, &*buf_dat.offset(j - 1)) == Less { j -= 1; } @@ -2034,10 +2035,10 @@ fn merge_sort<T>(v: &mut [T], less_eq: |&T, &T| -> bool) { // `left < right_start` and `right < right_end`, // so these are valid. - let to_copy = if less_eq(&*left, &*right) { - step(&mut left) - } else { + let to_copy = if compare(&*left, &*right) == Greater { step(&mut right) + } else { + step(&mut left) }; ptr::copy_nonoverlapping_memory(out, to_copy, 1); step(&mut out); @@ -2164,8 +2165,8 @@ pub trait MutableVector<'a, T> { /// Reverse the order of elements in a vector, in place fn reverse(self); - /// Sort the vector, in place, using `less_eq` to compare `a <= - /// b`. + /// Sort the vector, in place, using `compare` to compare + /// elements. /// /// This sort is `O(n log n)` worst-case and stable, but allocates /// approximately `2 * n`, where `n` is the length of `self`. @@ -2174,14 +2175,14 @@ pub trait MutableVector<'a, T> { /// /// ```rust /// let mut v = [5, 4, 1, 3, 2]; - /// v.sort(|a, b| *a <= *b); + /// v.sort(|a, b| a.cmp(b)); /// assert_eq!(v, [1, 2, 3, 4, 5]); /// /// // reverse sorting - /// v.sort(|a, b| *b <= *a); + /// v.sort(|a, b| b.cmp(a)); /// assert_eq!(v, [5, 4, 3, 2, 1]); /// ``` - fn sort_by(self, less_eq: |&T, &T| -> bool); + fn sort_by(self, compare: |&T, &T| -> Ordering); /** * Consumes `src` and moves as many elements as it can into `self` @@ -2328,12 +2329,8 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] { } #[inline] -<<<<<<< HEAD - fn sort(self, less_eq: |&T, &T| -> bool) { -======= - fn sort_by<Sort: SortComparator<T>>(self, less_eq: Sort) { ->>>>>>> 9ceda35... std::vec: add a sugary .sort() method for plain Ord sorting. - merge_sort(self, less_eq) + fn sort_by(self, compare: |&T, &T| -> Ordering) { + merge_sort(self, compare) } #[inline] @@ -2391,7 +2388,7 @@ impl<'a, T:Clone> MutableCloneableVector<T> for &'a mut [T] { /// Methods for mutable vectors with orderable elements, such as /// in-place sorting. -pub trait MutableOrdVector<T> { +pub trait MutableTotalOrdVector<T> { /// Sort the vector, in place. /// /// This is equivalent to `self.sort_by(std::vec::SortForward)`. @@ -2408,10 +2405,10 @@ pub trait MutableOrdVector<T> { /// ``` fn sort(self); } -impl<'a, T: Ord> MutableOrdVector<T> for &'a mut [T] { +impl<'a, T: TotalOrd> MutableTotalOrdVector<T> for &'a mut [T] { #[inline] fn sort(self) { - self.sort_by(SortForward) + self.sort_by(|a,b| a.cmp(b)) } } @@ -3502,41 +3499,25 @@ mod tests { for len in range(4u, 25) { for _ in range(0, 100) { let mut v = task_rng().gen_vec::<uint>(len); - v.sort(|a,b| a <= b); - -<<<<<<< HEAD - assert!(v.windows(2).all(|w| w[0] <= w[1])); -======= let mut v1 = v.clone(); - let mut v2 = v.clone(); + v.sort(); assert!(v.windows(2).all(|w| w[0] <= w[1])); - v1.sort_by(vec::SortForward); + v1.sort_by(|a, b| a.cmp(b)); assert!(v1.windows(2).all(|w| w[0] <= w[1])); - v1.sort_by(vec::SortReverse); + v1.sort_by(|a, b| b.cmp(a)); assert!(v1.windows(2).all(|w| w[0] >= w[1])); - - v2.sort_by(|a: &uint, b: &uint| a <= b); - assert!(v2.windows(2).all(|w| w[0] <= w[1])); ->>>>>>> 9ceda35... std::vec: add a sugary .sort() method for plain Ord sorting. } } // shouldn't fail/crash let mut v: [uint, .. 0] = []; -<<<<<<< HEAD - v.sort(|a,b| a <= b); + v.sort(); let mut v = [0xDEADBEEF]; - v.sort(|a,b| a <= b); -======= - v.sort_by(SortForward); - - let mut v = [0xDEADBEEF]; - v.sort_by(SortForward); ->>>>>>> 9ceda35... std::vec: add a sugary .sort() method for plain Ord sorting. + v.sort(); assert_eq!(v, [0xDEADBEEF]); } @@ -3559,11 +3540,7 @@ mod tests { // only sort on the first element, so an unstable sort // may mix up the counts. -<<<<<<< HEAD - v.sort(|&(a,_), &(b,_)| a <= b); -======= - v.sort_by(|&(a,_): &(uint, uint), &(b,_): &(uint, uint)| a <= b); ->>>>>>> 9ceda35... std::vec: add a sugary .sort() method for plain Ord sorting. + v.sort_by(|&(a,_), &(b,_)| a.cmp(&b)); // this comparison includes the count (the second item // of the tuple), so elements with equal first items @@ -4398,10 +4375,10 @@ mod bench { use extra::test::BenchHarness; use iter::range; use vec; - use vec::{VectorVector, MutableOrdVector}; + use vec::{VectorVector, MutableTotalOrdVector}; use option::*; use ptr; - use rand::{weak_rng, task_rng, Rng}; + use rand::{weak_rng, Rng}; use mem; #[bench] @@ -4604,33 +4581,34 @@ mod bench { }) } + #[bench] fn sort_random_small(bh: &mut BenchHarness) { let mut rng = weak_rng(); bh.iter(|| { - let mut v: ~[f64] = rng.gen_vec(5); + let mut v: ~[u64] = rng.gen_vec(5); v.sort(); }); - bh.bytes = 5 * mem::size_of::<f64>() as u64; + bh.bytes = 5 * mem::size_of::<u64>() as u64; } #[bench] fn sort_random_medium(bh: &mut BenchHarness) { let mut rng = weak_rng(); bh.iter(|| { - let mut v: ~[f64] = rng.gen_vec(100); + let mut v: ~[u64] = rng.gen_vec(100); v.sort(); }); - bh.bytes = 100 * mem::size_of::<f64>() as u64; + bh.bytes = 100 * mem::size_of::<u64>() as u64; } #[bench] fn sort_random_large(bh: &mut BenchHarness) { let mut rng = weak_rng(); bh.iter(|| { - let mut v: ~[f64] = rng.gen_vec(10000); + let mut v: ~[u64] = rng.gen_vec(10000); v.sort(); }); - bh.bytes = 10000 * mem::size_of::<f64>() as u64; + bh.bytes = 10000 * mem::size_of::<u64>() as u64; } #[bench] diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 4564542f929..8dff321ca0e 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -203,11 +203,7 @@ pub fn sort_meta_items(items: &[@MetaItem]) -> ~[@MetaItem] { .map(|&mi| (mi.name(), mi)) .collect::<~[(@str, @MetaItem)]>(); -<<<<<<< HEAD - v.sort(|&(a, _), &(b, _)| a <= b); -======= - v.sort_by(|&(a, _): &(@str, @MetaItem), &(b, _): &(@str, @MetaItem)| a <= b); ->>>>>>> 9ceda35... std::vec: add a sugary .sort() method for plain Ord sorting. + v.sort_by(|&(a, _), &(b, _)| a.cmp(&b)); // There doesn't seem to be a more optimal way to do this v.move_iter().map(|(_, m)| { diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index ca04f3d9704..2f63c6046f8 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -26,37 +26,32 @@ use std::task; use std::util; use std::vec; +fn f64_cmp(x: f64, y: f64) -> Ordering { + // arbitrarily decide that NaNs are larger than everything. + if y.is_nan() { + Less + } else if x.is_nan() { + Greater + } else if x < y { + Less + } else if x == y { + Equal + } else { + Greater + } +} + // given a map, print a sorted version of it fn sort_and_fmt(mm: &HashMap<~[u8], uint>, total: uint) -> ~str { fn pct(xx: uint, yy: uint) -> f64 { return (xx as f64) * 100.0 / (yy as f64); } - fn le_by_val<TT:Clone, - UU:Clone + Ord>( - kv0: &(TT,UU), - kv1: &(TT,UU)) - -> bool { - let (_, v0) = (*kv0).clone(); - let (_, v1) = (*kv1).clone(); - return v0 >= v1; - } - - fn le_by_key<TT:Clone + Ord, - UU:Clone>( - kv0: &(TT,UU), - kv1: &(TT,UU)) - -> bool { - let (k0, _) = (*kv0).clone(); - let (k1, _) = (*kv1).clone(); - return k0 <= k1; - } - // sort by key, then by value - fn sortKV<TT:Clone + Ord, UU:Clone + Ord>(mut orig: ~[(TT,UU)]) -> ~[(TT,UU)] { - orig.sort_by(le_by_key); - orig.sort_by(le_by_val); - origin + fn sortKV(mut orig: ~[(~[u8],f64)]) -> ~[(~[u8],f64)] { + orig.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b)); + orig.sort_by(|&(_, a), &(_, b)| f64_cmp(b, a)); + orig } let mut pairs = ~[]; diff --git a/src/test/run-pass/vector-sort-failure-safe.rs b/src/test/run-pass/vector-sort-failure-safe.rs index ca82fb0422e..a45daad64b8 100644 --- a/src/test/run-pass/vector-sort-failure-safe.rs +++ b/src/test/run-pass/vector-sort-failure-safe.rs @@ -14,7 +14,7 @@ static MAX_LEN: uint = 20; static mut drop_counts: [uint, .. MAX_LEN] = [0, .. MAX_LEN]; static mut clone_count: uint = 0; -#[deriving(Rand, Ord)] +#[deriving(Rand, Ord, TotalEq, TotalOrd)] struct DropCounter { x: uint, clone_num: uint } impl Clone for DropCounter { @@ -48,7 +48,7 @@ pub fn main() { // work out the total number of comparisons required to sort // this array... let mut count = 0; - main.clone().sort_by(|a, b| { count += 1; a <= b }); + main.clone().sort_by(|a, b| { count += 1; a.cmp(b) }); // ... and then fail on each and every single one. for fail_countdown in range(0, count) { @@ -68,7 +68,7 @@ pub fn main() { fail!() } fail_countdown -= 1; - a <= b + a.cmp(b) }) }); |
