From 9ce519ba21d9b6a37df8c6de8cb8c935448211c4 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 12 Aug 2014 14:48:39 +0100 Subject: [PATCH] Have quicksort take a compare function rather than requires Ord and Eq. --- src/components/style/selector_matching.rs | 37 +++++------------------ src/components/util/sort.rs | 21 +++++++------ 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/src/components/style/selector_matching.rs b/src/components/style/selector_matching.rs index f63bc47eff1..843a5ed10d7 100644 --- a/src/components/style/selector_matching.rs +++ b/src/components/style/selector_matching.rs @@ -125,7 +125,11 @@ impl SelectorMap { shareable); // Sort only the rules we just added. - sort::quicksort(matching_rules_list.vec_mut_slice_from(init_len)); + sort::quicksort_by(matching_rules_list.vec_mut_slice_from(init_len), compare); + + fn compare(a: &DeclarationBlock, b: &DeclarationBlock) -> Ordering { + (a.specificity, a.source_order).cmp(&(b.specificity, b.source_order)) + } } fn get_matching_rules_from_hash bool { - let this_rank = (self.specificity, self.source_order); - let other_rank = (other.specificity, other.source_order); - this_rank == other_rank - } -} - -impl Eq for DeclarationBlock {} - -impl PartialOrd for DeclarationBlock { - #[inline] - fn partial_cmp(&self, other: &DeclarationBlock) -> Option { - let this_rank = (self.specificity, self.source_order); - let other_rank = (other.specificity, other.source_order); - this_rank.partial_cmp(&other_rank) - } -} - -impl Ord for DeclarationBlock { - #[inline] - fn cmp(&self, other: &DeclarationBlock) -> Ordering { - let this_rank = (self.specificity, self.source_order); - let other_rank = (other.specificity, other.source_order); - this_rank.cmp(&other_rank) - } -} /// Determines whether the given element matches the given single or compound selector. /// @@ -968,7 +944,8 @@ mod tests { let rules_list = get_mock_rules(["a.intro", "img.sidebar"]); let a = &rules_list[0][0].declarations; let b = &rules_list[1][0].declarations; - assert!(a < b, "The rule that comes later should win."); + assert!((a.specificity, a.source_order).cmp(&(b.specificity, b.source_order)) == Less, + "The rule that comes later should win."); } #[test] diff --git a/src/components/util/sort.rs b/src/components/util/sort.rs index 90ba2469544..32dc52f6574 100644 --- a/src/components/util/sort.rs +++ b/src/components/util/sort.rs @@ -4,7 +4,7 @@ //! In-place sorting. -fn quicksort_helper(arr: &mut [T], left: int, right: int) { +fn quicksort_helper(arr: &mut [T], left: int, right: int, compare: fn(&T, &T) -> Ordering) { if right <= left { return } @@ -17,11 +17,11 @@ fn quicksort_helper(arr: &mut [T], left: in let v: *mut T = &mut arr[right as uint]; loop { i += 1; - while arr[i as uint] < (*v) { + while compare(&arr[i as uint], &*v) == Less { i += 1 } j -= 1; - while (*v) < arr[j as uint] { + while compare(&*v, &arr[j as uint]) == Less { if j == left { break } @@ -31,11 +31,11 @@ fn quicksort_helper(arr: &mut [T], left: in break } arr.swap(i as uint, j as uint); - if arr[i as uint] == (*v) { + if compare(&arr[i as uint], &*v) == Equal { p += 1; arr.swap(p as uint, i as uint) } - if (*v) == arr[j as uint] { + if compare(&*v, &arr[j as uint]) == Equal { q -= 1; arr.swap(j as uint, q as uint) } @@ -60,21 +60,21 @@ fn quicksort_helper(arr: &mut [T], left: in assert!(k != 0); } - quicksort_helper(arr, left, j); - quicksort_helper(arr, i, right); + quicksort_helper(arr, left, j, compare); + quicksort_helper(arr, i, right, compare); } /// An in-place quicksort. /// /// The algorithm is from Sedgewick and Bentley, "Quicksort is Optimal": /// http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf -pub fn quicksort(arr: &mut [T]) { +pub fn quicksort_by(arr: &mut [T], compare: fn(&T, &T) -> Ordering) { if arr.len() <= 1 { return } let len = arr.len(); - quicksort_helper(arr, 0, (len - 1) as int); + quicksort_helper(arr, 0, (len - 1) as int, compare); } #[cfg(test)] @@ -90,7 +90,8 @@ pub mod test { for _ in range(0u32, 50000u32) { let len: uint = rng.gen(); let mut v: Vec = rng.gen_iter::().take((len % 32) + 1).collect(); - sort::quicksort(v.as_mut_slice()); + fn compare_ints(a: &int, b: &int) -> Ordering { a.cmp(b) } + sort::quicksort_by(v.as_mut_slice(), compare_ints); for i in range(0, v.len() - 1) { assert!(v.get(i) <= v.get(i + 1)) }