aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/util/vec.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/util/vec.rs')
-rw-r--r--src/components/util/vec.rs42
1 files changed, 32 insertions, 10 deletions
diff --git a/src/components/util/vec.rs b/src/components/util/vec.rs
index 226c345aafd..f5c01786d9a 100644
--- a/src/components/util/vec.rs
+++ b/src/components/util/vec.rs
@@ -4,17 +4,33 @@
use std::cmp::{Ord, Eq};
-pub trait BinarySearchMethods<'a, T: Ord + Eq> {
+/// FIXME(pcwalton): Workaround for lack of unboxed closures. This is called in
+/// performance-critical code, so a closure is insufficient.
+pub trait Comparator<K,T> {
+ fn compare(&self, key: &K, value: &T) -> Ordering;
+}
+
+pub trait BinarySearchMethods<'a, T: TotalOrd + Ord + Eq> {
fn binary_search(&self, key: &T) -> Option<&'a T>;
fn binary_search_index(&self, key: &T) -> Option<uint>;
}
-impl<'a, T: Ord + Eq> BinarySearchMethods<'a, T> for &'a [T] {
+pub trait FullBinarySearchMethods<T> {
+ fn binary_search_index_by<K,C:Comparator<K,T>>(&self, key: &K, cmp: C) -> Option<uint>;
+}
+
+impl<'a, T: TotalOrd + Ord + Eq> BinarySearchMethods<'a, T> for &'a [T] {
fn binary_search(&self, key: &T) -> Option<&'a T> {
self.binary_search_index(key).map(|i| &self[i])
}
fn binary_search_index(&self, key: &T) -> Option<uint> {
+ self.binary_search_index_by(key, DefaultComparator)
+ }
+}
+
+impl<'a, T> FullBinarySearchMethods<T> for &'a [T] {
+ fn binary_search_index_by<K,C:Comparator<K,T>>(&self, key: &K, cmp: C) -> Option<uint> {
if self.len() == 0 {
return None;
}
@@ -27,20 +43,26 @@ impl<'a, T: Ord + Eq> BinarySearchMethods<'a, T> for &'a [T] {
let mid = ((low as uint) + (high as uint)) >> 1;
let midv = &self[mid];
- if midv < key {
- low = (mid as int) + 1;
- } else if midv > key {
- high = (mid as int) - 1;
- } else {
- return Some(mid);
+ match cmp.compare(key, midv) {
+ Greater => low = (mid as int) + 1,
+ Less => high = (mid as int) - 1,
+ Equal => return Some(mid),
}
}
return None;
}
}
+struct DefaultComparator;
+
+impl<T:Eq + Ord + TotalOrd> Comparator<T,T> for DefaultComparator {
+ fn compare(&self, key: &T, value: &T) -> Ordering {
+ (*key).cmp(value)
+ }
+}
+
#[cfg(test)]
-fn test_find_all_elems<T: Eq + Ord>(arr: &[T]) {
+fn test_find_all_elems<T: Eq + Ord + TotalEq + TotalOrd>(arr: &[T]) {
let mut i = 0;
while i < arr.len() {
assert!(test_match(&arr[i], arr.binary_search(&arr[i])));
@@ -49,7 +71,7 @@ fn test_find_all_elems<T: Eq + Ord>(arr: &[T]) {
}
#[cfg(test)]
-fn test_miss_all_elems<T: Eq + Ord>(arr: &[T], misses: &[T]) {
+fn test_miss_all_elems<T: Eq + Ord + TotalEq + TotalOrd>(arr: &[T], misses: &[T]) {
let mut i = 0;
while i < misses.len() {
let res = arr.binary_search(&misses[i]);