Skip to content

Commit 6a4d185

Browse files
committed
std: implement lexicographical Ord for TreeMap/TreeSet
1 parent 83ca034 commit 6a4d185

File tree

1 file changed

+82
-4
lines changed

1 file changed

+82
-4
lines changed

src/libstd/treemap.rs

+82-4
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ use core::prelude::*;
2828

2929
// range search - O(log n) retrieval of an iterator from some key
3030

31-
// implement Ord for TreeSet
32-
// could be superset/subset-based or in-order lexicographic comparison... but
33-
// there are methods for is_superset/is_subset so lexicographic is more useful
34-
3531
// (possibly) implement the overloads Python does for sets:
3632
// * union: |
3733
// * intersection: &
@@ -71,6 +67,45 @@ impl <K: Eq Ord, V: Eq> TreeMap<K, V>: Eq {
7167
pure fn ne(&self, other: &TreeMap<K, V>) -> bool { !self.eq(other) }
7268
}
7369

70+
// Lexicographical comparison
71+
pure fn lt<K: Ord, V>(a: &TreeMap<K, V>, b: &TreeMap<K, V>) -> bool {
72+
let mut x = a.iter();
73+
let mut y = b.iter();
74+
75+
let (a_len, b_len) = (a.len(), b.len());
76+
for uint::min(a_len, b_len).times {
77+
unsafe { // purity workaround
78+
x = x.next();
79+
y = y.next();
80+
let (key_a,_) = x.get().unwrap();
81+
let (key_b,_) = y.get().unwrap();
82+
if *key_a < *key_b { return true; }
83+
if *key_a > *key_b { return false; }
84+
}
85+
};
86+
87+
return a_len < b_len;
88+
}
89+
90+
impl <K: Ord, V> TreeMap<K, V>: Ord {
91+
#[inline(always)]
92+
pure fn lt(&self, other: &TreeMap<K, V>) -> bool {
93+
lt(self, other)
94+
}
95+
#[inline(always)]
96+
pure fn le(&self, other: &TreeMap<K, V>) -> bool {
97+
!lt(other, self)
98+
}
99+
#[inline(always)]
100+
pure fn ge(&self, other: &TreeMap<K, V>) -> bool {
101+
!lt(self, other)
102+
}
103+
#[inline(always)]
104+
pure fn gt(&self, other: &TreeMap<K, V>) -> bool {
105+
lt(other, self)
106+
}
107+
}
108+
74109
impl <K: Ord, V> TreeMap<K, V>: Container {
75110
/// Return the number of elements in the map
76111
pure fn len(&self) -> uint { self.length }
@@ -220,6 +255,17 @@ impl <T: Eq Ord> TreeSet<T>: Eq {
220255
pure fn ne(&self, other: &TreeSet<T>) -> bool { self.map != other.map }
221256
}
222257

258+
impl <T: Ord> TreeSet<T>: Ord {
259+
#[inline(always)]
260+
pure fn lt(&self, other: &TreeSet<T>) -> bool { self.map < other.map }
261+
#[inline(always)]
262+
pure fn le(&self, other: &TreeSet<T>) -> bool { self.map <= other.map }
263+
#[inline(always)]
264+
pure fn ge(&self, other: &TreeSet<T>) -> bool { self.map >= other.map }
265+
#[inline(always)]
266+
pure fn gt(&self, other: &TreeSet<T>) -> bool { self.map > other.map }
267+
}
268+
223269
impl <T: Ord> TreeSet<T>: Container {
224270
/// Return the number of elements in the set
225271
pure fn len(&self) -> uint { self.map.len() }
@@ -878,6 +924,38 @@ mod test_treemap {
878924
assert a == b;
879925
}
880926

927+
#[test]
928+
fn test_lt() {
929+
let mut a = TreeMap::new();
930+
let mut b = TreeMap::new();
931+
932+
assert !(a < b) && !(b < a);
933+
assert b.insert(0, 5);
934+
assert a < b;
935+
assert a.insert(0, 7);
936+
assert !(a < b) && !(b < a);
937+
assert b.insert(-2, 0);
938+
assert b < a;
939+
assert a.insert(-5, 2);
940+
assert a < b;
941+
assert a.insert(6, 2);
942+
assert a < b && !(b < a);
943+
}
944+
945+
#[test]
946+
fn test_ord() {
947+
let mut a = TreeMap::new();
948+
let mut b = TreeMap::new();
949+
950+
assert a <= b && a >= b;
951+
assert a.insert(1, 1);
952+
assert a > b && a >= b;
953+
assert b < a && b <= a;
954+
assert b.insert(2, 2);
955+
assert b > a && b >= a;
956+
assert a < b && a <= b;
957+
}
958+
881959
#[test]
882960
fn test_lazy_iterator() {
883961
let mut m = TreeMap::new();

0 commit comments

Comments
 (0)