From 6a4d1855bf8a4eb95114e9f41ce0b55468b80b73 Mon Sep 17 00:00:00 2001 From: Cody Schroeder Date: Sat, 26 Jan 2013 09:40:41 -0800 Subject: [PATCH] std: implement lexicographical Ord for TreeMap/TreeSet --- src/libstd/treemap.rs | 86 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 36d919494f1..68fff9ecb39 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -28,10 +28,6 @@ // range search - O(log n) retrieval of an iterator from some key -// implement Ord for TreeSet -// could be superset/subset-based or in-order lexicographic comparison... but -// there are methods for is_superset/is_subset so lexicographic is more useful - // (possibly) implement the overloads Python does for sets: // * union: | // * intersection: & @@ -71,6 +67,45 @@ impl TreeMap: Eq { pure fn ne(&self, other: &TreeMap) -> bool { !self.eq(other) } } +// Lexicographical comparison +pure fn lt(a: &TreeMap, b: &TreeMap) -> bool { + let mut x = a.iter(); + let mut y = b.iter(); + + let (a_len, b_len) = (a.len(), b.len()); + for uint::min(a_len, b_len).times { + unsafe { // purity workaround + x = x.next(); + y = y.next(); + let (key_a,_) = x.get().unwrap(); + let (key_b,_) = y.get().unwrap(); + if *key_a < *key_b { return true; } + if *key_a > *key_b { return false; } + } + }; + + return a_len < b_len; +} + +impl TreeMap: Ord { + #[inline(always)] + pure fn lt(&self, other: &TreeMap) -> bool { + lt(self, other) + } + #[inline(always)] + pure fn le(&self, other: &TreeMap) -> bool { + !lt(other, self) + } + #[inline(always)] + pure fn ge(&self, other: &TreeMap) -> bool { + !lt(self, other) + } + #[inline(always)] + pure fn gt(&self, other: &TreeMap) -> bool { + lt(other, self) + } +} + impl TreeMap: Container { /// Return the number of elements in the map pure fn len(&self) -> uint { self.length } @@ -220,6 +255,17 @@ impl TreeSet: Eq { pure fn ne(&self, other: &TreeSet) -> bool { self.map != other.map } } +impl TreeSet: Ord { + #[inline(always)] + pure fn lt(&self, other: &TreeSet) -> bool { self.map < other.map } + #[inline(always)] + pure fn le(&self, other: &TreeSet) -> bool { self.map <= other.map } + #[inline(always)] + pure fn ge(&self, other: &TreeSet) -> bool { self.map >= other.map } + #[inline(always)] + pure fn gt(&self, other: &TreeSet) -> bool { self.map > other.map } +} + impl TreeSet: Container { /// Return the number of elements in the set pure fn len(&self) -> uint { self.map.len() } @@ -878,6 +924,38 @@ fn test_eq() { assert a == b; } + #[test] + fn test_lt() { + let mut a = TreeMap::new(); + let mut b = TreeMap::new(); + + assert !(a < b) && !(b < a); + assert b.insert(0, 5); + assert a < b; + assert a.insert(0, 7); + assert !(a < b) && !(b < a); + assert b.insert(-2, 0); + assert b < a; + assert a.insert(-5, 2); + assert a < b; + assert a.insert(6, 2); + assert a < b && !(b < a); + } + + #[test] + fn test_ord() { + let mut a = TreeMap::new(); + let mut b = TreeMap::new(); + + assert a <= b && a >= b; + assert a.insert(1, 1); + assert a > b && a >= b; + assert b < a && b <= a; + assert b.insert(2, 2); + assert b > a && b >= a; + assert a < b && a <= b; + } + #[test] fn test_lazy_iterator() { let mut m = TreeMap::new();