mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-04 20:54:13 +00:00
Merge pull request #4682 from thestinger/treemap
Set trait improvements + minor treemap cleanup
This commit is contained in:
commit
b927e48a26
@ -65,4 +65,26 @@ pub trait Set<T>: Mutable {
|
||||
/// Remove a value from the set. Return true if the value was
|
||||
/// present in the set.
|
||||
fn remove(&mut self, value: &T) -> bool;
|
||||
|
||||
/// Return true if the set has no elements in common with `other`.
|
||||
/// This is equivalent to checking for an empty intersection.
|
||||
pure fn is_disjoint(&self, other: &self) -> bool;
|
||||
|
||||
/// Return true if the set is a subset of another
|
||||
pure fn is_subset(&self, other: &self) -> bool;
|
||||
|
||||
/// Return true if the set is a superset of another
|
||||
pure fn is_superset(&self, other: &self) -> bool;
|
||||
|
||||
/// Visit the values representing the difference
|
||||
pure fn difference(&self, other: &self, f: fn(&T) -> bool);
|
||||
|
||||
/// Visit the values representing the symmetric difference
|
||||
pure fn symmetric_difference(&self, other: &self, f: fn(&T) -> bool);
|
||||
|
||||
/// Visit the values representing the intersection
|
||||
pure fn intersection(&self, other: &self, f: fn(&T) -> bool);
|
||||
|
||||
/// Visit the values representing the union
|
||||
pure fn union(&self, other: &self, f: fn(&T) -> bool);
|
||||
}
|
||||
|
@ -14,17 +14,17 @@
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use container::{Container, Mutable, Map, Set};
|
||||
use cmp::Eq;
|
||||
use hash::Hash;
|
||||
use to_bytes::IterBytes;
|
||||
|
||||
/// Open addressing with linear probing.
|
||||
pub mod linear {
|
||||
use super::*;
|
||||
use iter::BaseIter;
|
||||
use container::{Container, Mutable, Map, Set};
|
||||
use cmp::Eq;
|
||||
use cmp;
|
||||
use hash::Hash;
|
||||
use iter;
|
||||
use kinds::Copy;
|
||||
use option::{None, Option, Some};
|
||||
use option;
|
||||
@ -453,6 +453,60 @@ pub mod linear {
|
||||
/// Remove a value from the set. Return true if the value was
|
||||
/// present in the set.
|
||||
fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
|
||||
/// Return true if the set has no elements in common with `other`.
|
||||
/// This is equivalent to checking for an empty intersection.
|
||||
pure fn is_disjoint(&self, other: &LinearSet<T>) -> bool {
|
||||
iter::all(self, |v| !other.contains(v))
|
||||
}
|
||||
|
||||
/// Return true if the set is a subset of another
|
||||
pure fn is_subset(&self, other: &LinearSet<T>) -> bool {
|
||||
iter::all(self, |v| other.contains(v))
|
||||
}
|
||||
|
||||
/// Return true if the set is a superset of another
|
||||
pure fn is_superset(&self, other: &LinearSet<T>) -> bool {
|
||||
other.is_subset(self)
|
||||
}
|
||||
|
||||
/// Visit the values representing the difference
|
||||
pure fn difference(&self, other: &LinearSet<T>, f: fn(&T) -> bool) {
|
||||
for self.each |v| {
|
||||
if !other.contains(v) {
|
||||
if !f(v) { return }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Visit the values representing the symmetric difference
|
||||
pure fn symmetric_difference(&self, other: &LinearSet<T>,
|
||||
f: fn(&T) -> bool) {
|
||||
self.difference(other, f);
|
||||
other.difference(self, f);
|
||||
}
|
||||
|
||||
/// Visit the values representing the intersection
|
||||
pure fn intersection(&self, other: &LinearSet<T>, f: fn(&T) -> bool) {
|
||||
for self.each |v| {
|
||||
if other.contains(v) {
|
||||
if !f(v) { return }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Visit the values representing the union
|
||||
pure fn union(&self, other: &LinearSet<T>, f: fn(&T) -> bool) {
|
||||
for self.each |v| {
|
||||
if !f(v) { return }
|
||||
}
|
||||
|
||||
for other.each |v| {
|
||||
if !self.contains(v) {
|
||||
if !f(v) { return }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub impl <T: Hash IterBytes Eq> LinearSet<T> {
|
||||
@ -462,7 +516,7 @@ pub mod linear {
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub mod test {
|
||||
mod test_map {
|
||||
use container::{Container, Mutable, Map, Set};
|
||||
use option::{None, Some};
|
||||
use hashmap::linear::LinearMap;
|
||||
@ -610,3 +664,168 @@ pub mod test {
|
||||
assert !m.is_empty();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
mod test_set {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_disjoint() {
|
||||
let mut xs = linear::LinearSet::new();
|
||||
let mut ys = linear::LinearSet::new();
|
||||
assert xs.is_disjoint(&ys);
|
||||
assert ys.is_disjoint(&xs);
|
||||
assert xs.insert(5);
|
||||
assert ys.insert(11);
|
||||
assert xs.is_disjoint(&ys);
|
||||
assert ys.is_disjoint(&xs);
|
||||
assert xs.insert(7);
|
||||
assert xs.insert(19);
|
||||
assert xs.insert(4);
|
||||
assert ys.insert(2);
|
||||
assert ys.insert(-11);
|
||||
assert xs.is_disjoint(&ys);
|
||||
assert ys.is_disjoint(&xs);
|
||||
assert ys.insert(7);
|
||||
assert !xs.is_disjoint(&ys);
|
||||
assert !ys.is_disjoint(&xs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subset_and_superset() {
|
||||
let mut a = linear::LinearSet::new();
|
||||
assert a.insert(0);
|
||||
assert a.insert(5);
|
||||
assert a.insert(11);
|
||||
assert a.insert(7);
|
||||
|
||||
let mut b = linear::LinearSet::new();
|
||||
assert b.insert(0);
|
||||
assert b.insert(7);
|
||||
assert b.insert(19);
|
||||
assert b.insert(250);
|
||||
assert b.insert(11);
|
||||
assert b.insert(200);
|
||||
|
||||
assert !a.is_subset(&b);
|
||||
assert !a.is_superset(&b);
|
||||
assert !b.is_subset(&a);
|
||||
assert !b.is_superset(&a);
|
||||
|
||||
assert b.insert(5);
|
||||
|
||||
assert a.is_subset(&b);
|
||||
assert !a.is_superset(&b);
|
||||
assert !b.is_subset(&a);
|
||||
assert b.is_superset(&a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection() {
|
||||
let mut a = linear::LinearSet::new();
|
||||
let mut b = linear::LinearSet::new();
|
||||
|
||||
assert a.insert(11);
|
||||
assert a.insert(1);
|
||||
assert a.insert(3);
|
||||
assert a.insert(77);
|
||||
assert a.insert(103);
|
||||
assert a.insert(5);
|
||||
assert a.insert(-5);
|
||||
|
||||
assert b.insert(2);
|
||||
assert b.insert(11);
|
||||
assert b.insert(77);
|
||||
assert b.insert(-9);
|
||||
assert b.insert(-42);
|
||||
assert b.insert(5);
|
||||
assert b.insert(3);
|
||||
|
||||
let mut i = 0;
|
||||
let expected = [3, 5, 11, 77];
|
||||
for a.intersection(&b) |x| {
|
||||
assert vec::contains(expected, x);
|
||||
i += 1
|
||||
}
|
||||
assert i == expected.len();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_difference() {
|
||||
let mut a = linear::LinearSet::new();
|
||||
let mut b = linear::LinearSet::new();
|
||||
|
||||
assert a.insert(1);
|
||||
assert a.insert(3);
|
||||
assert a.insert(5);
|
||||
assert a.insert(9);
|
||||
assert a.insert(11);
|
||||
|
||||
assert b.insert(3);
|
||||
assert b.insert(9);
|
||||
|
||||
let mut i = 0;
|
||||
let expected = [1, 5, 11];
|
||||
for a.difference(&b) |x| {
|
||||
assert vec::contains(expected, x);
|
||||
i += 1
|
||||
}
|
||||
assert i == expected.len();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symmetric_difference() {
|
||||
let mut a = linear::LinearSet::new();
|
||||
let mut b = linear::LinearSet::new();
|
||||
|
||||
assert a.insert(1);
|
||||
assert a.insert(3);
|
||||
assert a.insert(5);
|
||||
assert a.insert(9);
|
||||
assert a.insert(11);
|
||||
|
||||
assert b.insert(-2);
|
||||
assert b.insert(3);
|
||||
assert b.insert(9);
|
||||
assert b.insert(14);
|
||||
assert b.insert(22);
|
||||
|
||||
let mut i = 0;
|
||||
let expected = [-2, 1, 5, 11, 14, 22];
|
||||
for a.symmetric_difference(&b) |x| {
|
||||
assert vec::contains(expected, x);
|
||||
i += 1
|
||||
}
|
||||
assert i == expected.len();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_union() {
|
||||
let mut a = linear::LinearSet::new();
|
||||
let mut b = linear::LinearSet::new();
|
||||
|
||||
assert a.insert(1);
|
||||
assert a.insert(3);
|
||||
assert a.insert(5);
|
||||
assert a.insert(9);
|
||||
assert a.insert(11);
|
||||
assert a.insert(16);
|
||||
assert a.insert(19);
|
||||
assert a.insert(24);
|
||||
|
||||
assert b.insert(-2);
|
||||
assert b.insert(1);
|
||||
assert b.insert(5);
|
||||
assert b.insert(9);
|
||||
assert b.insert(13);
|
||||
assert b.insert(19);
|
||||
|
||||
let mut i = 0;
|
||||
let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
|
||||
for a.union(&b) |x| {
|
||||
assert vec::contains(expected, x);
|
||||
i += 1
|
||||
}
|
||||
assert i == expected.len();
|
||||
}
|
||||
}
|
||||
|
@ -29,10 +29,10 @@ use core::prelude::*;
|
||||
// range search - O(log n) retrieval of an iterator from some key
|
||||
|
||||
// (possibly) implement the overloads Python does for sets:
|
||||
// * union: |
|
||||
// * intersection: &
|
||||
// * difference: -
|
||||
// * symmetric difference: ^
|
||||
// * union: |
|
||||
// These would be convenient since the methods work like `each`
|
||||
|
||||
pub struct TreeMap<K, V> {
|
||||
@ -49,10 +49,9 @@ impl <K: Eq Ord, V: Eq> TreeMap<K, V>: Eq {
|
||||
let mut y = other.iter();
|
||||
for self.len().times {
|
||||
unsafe { // unsafe as a purity workaround
|
||||
// ICE: x.next() != y.next()
|
||||
|
||||
x = x.next();
|
||||
y = y.next();
|
||||
// FIXME: #4492 (ICE), x.get() == y.get()
|
||||
let (x1, x2) = x.get().unwrap();
|
||||
let (y1, y2) = y.get().unwrap();
|
||||
|
||||
@ -292,22 +291,6 @@ impl <T: Ord> TreeSet<T>: Set<T> {
|
||||
/// Remove a value from the set. Return true if the value was
|
||||
/// present in the set.
|
||||
fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
}
|
||||
|
||||
impl <T: Ord> TreeSet<T> {
|
||||
/// Create an empty TreeSet
|
||||
static pure fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
|
||||
|
||||
/// Visit all values in reverse order
|
||||
pure fn each_reverse(&self, f: fn(&T) -> bool) {
|
||||
self.map.each_key_reverse(f)
|
||||
}
|
||||
|
||||
/// Get a lazy iterator over the values in the set.
|
||||
/// Requires that it be frozen (immutable).
|
||||
pure fn iter(&self) -> TreeSetIterator/&self<T> {
|
||||
TreeSetIterator{iter: self.map.iter()}
|
||||
}
|
||||
|
||||
/// Return true if the set has no elements in common with `other`.
|
||||
/// This is equivalent to checking for an empty intersection.
|
||||
@ -336,12 +319,12 @@ impl <T: Ord> TreeSet<T> {
|
||||
true
|
||||
}
|
||||
|
||||
/// Check of the set is a subset of another
|
||||
/// Return true if the set is a subset of another
|
||||
pure fn is_subset(&self, other: &TreeSet<T>) -> bool {
|
||||
other.is_superset(self)
|
||||
}
|
||||
|
||||
/// Check of the set is a superset of another
|
||||
/// Return true if the set is a superset of another
|
||||
pure fn is_superset(&self, other: &TreeSet<T>) -> bool {
|
||||
let mut x = self.iter();
|
||||
let mut y = other.iter();
|
||||
@ -517,6 +500,22 @@ impl <T: Ord> TreeSet<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl <T: Ord> TreeSet<T> {
|
||||
/// Create an empty TreeSet
|
||||
static pure fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
|
||||
|
||||
/// Visit all values in reverse order
|
||||
pure fn each_reverse(&self, f: fn(&T) -> bool) {
|
||||
self.map.each_key_reverse(f)
|
||||
}
|
||||
|
||||
/// Get a lazy iterator over the values in the set.
|
||||
/// Requires that it be frozen (immutable).
|
||||
pure fn iter(&self) -> TreeSetIterator/&self<T> {
|
||||
TreeSetIterator{iter: self.map.iter()}
|
||||
}
|
||||
}
|
||||
|
||||
/// Lazy forward iterator over a set
|
||||
pub struct TreeSetIterator<T> {
|
||||
priv iter: TreeMapIterator<T, ()>
|
||||
@ -652,14 +651,12 @@ fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
|
||||
let mut left = save.left.swap_unwrap();
|
||||
if left.right.is_some() {
|
||||
heir_swap(save, &mut left.right);
|
||||
save.left = Some(left);
|
||||
remove(&mut save.left, key);
|
||||
} else {
|
||||
save.key <-> left.key;
|
||||
save.value <-> left.value;
|
||||
save.left = Some(left);
|
||||
remove(&mut save.left, key);
|
||||
}
|
||||
save.left = Some(left);
|
||||
remove(&mut save.left, key);
|
||||
} else {
|
||||
save = save.left.swap_unwrap();
|
||||
}
|
||||
@ -969,9 +966,7 @@ mod test_treemap {
|
||||
let m = m;
|
||||
let mut iter = m.iter();
|
||||
|
||||
// ICE:
|
||||
//assert iter.next() == Some((&x1, &y1));
|
||||
//assert iter.next().eq(&Some((&x1, &y1)));
|
||||
// FIXME: #4492 (ICE): iter.next() == Some((&x1, &y1))
|
||||
|
||||
iter = iter.next();
|
||||
assert iter.get().unwrap() == (&x1, &y1);
|
||||
@ -984,10 +979,6 @@ mod test_treemap {
|
||||
iter = iter.next();
|
||||
assert iter.get().unwrap() == (&x5, &y5);
|
||||
|
||||
// ICE:
|
||||
//assert iter.next() == None;
|
||||
//assert iter.next().eq(&None);
|
||||
|
||||
iter = iter.next();
|
||||
assert iter.get().is_none();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user