Skip to content

Commit b927e48

Browse files
committed
Merge pull request #4682 from thestinger/treemap
Set trait improvements + minor treemap cleanup
2 parents da4b376 + 6b08683 commit b927e48

File tree

3 files changed

+268
-36
lines changed

3 files changed

+268
-36
lines changed

src/libcore/container.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,26 @@ pub trait Set<T>: Mutable {
6565
/// Remove a value from the set. Return true if the value was
6666
/// present in the set.
6767
fn remove(&mut self, value: &T) -> bool;
68+
69+
/// Return true if the set has no elements in common with `other`.
70+
/// This is equivalent to checking for an empty intersection.
71+
pure fn is_disjoint(&self, other: &self) -> bool;
72+
73+
/// Return true if the set is a subset of another
74+
pure fn is_subset(&self, other: &self) -> bool;
75+
76+
/// Return true if the set is a superset of another
77+
pure fn is_superset(&self, other: &self) -> bool;
78+
79+
/// Visit the values representing the difference
80+
pure fn difference(&self, other: &self, f: fn(&T) -> bool);
81+
82+
/// Visit the values representing the symmetric difference
83+
pure fn symmetric_difference(&self, other: &self, f: fn(&T) -> bool);
84+
85+
/// Visit the values representing the intersection
86+
pure fn intersection(&self, other: &self, f: fn(&T) -> bool);
87+
88+
/// Visit the values representing the union
89+
pure fn union(&self, other: &self, f: fn(&T) -> bool);
6890
}

src/libcore/hashmap.rs

Lines changed: 223 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414
#[forbid(deprecated_mode)];
1515
#[forbid(deprecated_pattern)];
1616

17+
use container::{Container, Mutable, Map, Set};
1718
use cmp::Eq;
1819
use hash::Hash;
1920
use to_bytes::IterBytes;
2021

2122
/// Open addressing with linear probing.
2223
pub mod linear {
24+
use super::*;
2325
use iter::BaseIter;
24-
use container::{Container, Mutable, Map, Set};
25-
use cmp::Eq;
26-
use cmp;
2726
use hash::Hash;
27+
use iter;
2828
use kinds::Copy;
2929
use option::{None, Option, Some};
3030
use option;
@@ -453,6 +453,60 @@ pub mod linear {
453453
/// Remove a value from the set. Return true if the value was
454454
/// present in the set.
455455
fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
456+
457+
/// Return true if the set has no elements in common with `other`.
458+
/// This is equivalent to checking for an empty intersection.
459+
pure fn is_disjoint(&self, other: &LinearSet<T>) -> bool {
460+
iter::all(self, |v| !other.contains(v))
461+
}
462+
463+
/// Return true if the set is a subset of another
464+
pure fn is_subset(&self, other: &LinearSet<T>) -> bool {
465+
iter::all(self, |v| other.contains(v))
466+
}
467+
468+
/// Return true if the set is a superset of another
469+
pure fn is_superset(&self, other: &LinearSet<T>) -> bool {
470+
other.is_subset(self)
471+
}
472+
473+
/// Visit the values representing the difference
474+
pure fn difference(&self, other: &LinearSet<T>, f: fn(&T) -> bool) {
475+
for self.each |v| {
476+
if !other.contains(v) {
477+
if !f(v) { return }
478+
}
479+
}
480+
}
481+
482+
/// Visit the values representing the symmetric difference
483+
pure fn symmetric_difference(&self, other: &LinearSet<T>,
484+
f: fn(&T) -> bool) {
485+
self.difference(other, f);
486+
other.difference(self, f);
487+
}
488+
489+
/// Visit the values representing the intersection
490+
pure fn intersection(&self, other: &LinearSet<T>, f: fn(&T) -> bool) {
491+
for self.each |v| {
492+
if other.contains(v) {
493+
if !f(v) { return }
494+
}
495+
}
496+
}
497+
498+
/// Visit the values representing the union
499+
pure fn union(&self, other: &LinearSet<T>, f: fn(&T) -> bool) {
500+
for self.each |v| {
501+
if !f(v) { return }
502+
}
503+
504+
for other.each |v| {
505+
if !self.contains(v) {
506+
if !f(v) { return }
507+
}
508+
}
509+
}
456510
}
457511

458512
pub impl <T: Hash IterBytes Eq> LinearSet<T> {
@@ -462,7 +516,7 @@ pub mod linear {
462516
}
463517

464518
#[test]
465-
pub mod test {
519+
mod test_map {
466520
use container::{Container, Mutable, Map, Set};
467521
use option::{None, Some};
468522
use hashmap::linear::LinearMap;
@@ -610,3 +664,168 @@ pub mod test {
610664
assert !m.is_empty();
611665
}
612666
}
667+
668+
#[test]
669+
mod test_set {
670+
use super::*;
671+
672+
#[test]
673+
fn test_disjoint() {
674+
let mut xs = linear::LinearSet::new();
675+
let mut ys = linear::LinearSet::new();
676+
assert xs.is_disjoint(&ys);
677+
assert ys.is_disjoint(&xs);
678+
assert xs.insert(5);
679+
assert ys.insert(11);
680+
assert xs.is_disjoint(&ys);
681+
assert ys.is_disjoint(&xs);
682+
assert xs.insert(7);
683+
assert xs.insert(19);
684+
assert xs.insert(4);
685+
assert ys.insert(2);
686+
assert ys.insert(-11);
687+
assert xs.is_disjoint(&ys);
688+
assert ys.is_disjoint(&xs);
689+
assert ys.insert(7);
690+
assert !xs.is_disjoint(&ys);
691+
assert !ys.is_disjoint(&xs);
692+
}
693+
694+
#[test]
695+
fn test_subset_and_superset() {
696+
let mut a = linear::LinearSet::new();
697+
assert a.insert(0);
698+
assert a.insert(5);
699+
assert a.insert(11);
700+
assert a.insert(7);
701+
702+
let mut b = linear::LinearSet::new();
703+
assert b.insert(0);
704+
assert b.insert(7);
705+
assert b.insert(19);
706+
assert b.insert(250);
707+
assert b.insert(11);
708+
assert b.insert(200);
709+
710+
assert !a.is_subset(&b);
711+
assert !a.is_superset(&b);
712+
assert !b.is_subset(&a);
713+
assert !b.is_superset(&a);
714+
715+
assert b.insert(5);
716+
717+
assert a.is_subset(&b);
718+
assert !a.is_superset(&b);
719+
assert !b.is_subset(&a);
720+
assert b.is_superset(&a);
721+
}
722+
723+
#[test]
724+
fn test_intersection() {
725+
let mut a = linear::LinearSet::new();
726+
let mut b = linear::LinearSet::new();
727+
728+
assert a.insert(11);
729+
assert a.insert(1);
730+
assert a.insert(3);
731+
assert a.insert(77);
732+
assert a.insert(103);
733+
assert a.insert(5);
734+
assert a.insert(-5);
735+
736+
assert b.insert(2);
737+
assert b.insert(11);
738+
assert b.insert(77);
739+
assert b.insert(-9);
740+
assert b.insert(-42);
741+
assert b.insert(5);
742+
assert b.insert(3);
743+
744+
let mut i = 0;
745+
let expected = [3, 5, 11, 77];
746+
for a.intersection(&b) |x| {
747+
assert vec::contains(expected, x);
748+
i += 1
749+
}
750+
assert i == expected.len();
751+
}
752+
753+
#[test]
754+
fn test_difference() {
755+
let mut a = linear::LinearSet::new();
756+
let mut b = linear::LinearSet::new();
757+
758+
assert a.insert(1);
759+
assert a.insert(3);
760+
assert a.insert(5);
761+
assert a.insert(9);
762+
assert a.insert(11);
763+
764+
assert b.insert(3);
765+
assert b.insert(9);
766+
767+
let mut i = 0;
768+
let expected = [1, 5, 11];
769+
for a.difference(&b) |x| {
770+
assert vec::contains(expected, x);
771+
i += 1
772+
}
773+
assert i == expected.len();
774+
}
775+
776+
#[test]
777+
fn test_symmetric_difference() {
778+
let mut a = linear::LinearSet::new();
779+
let mut b = linear::LinearSet::new();
780+
781+
assert a.insert(1);
782+
assert a.insert(3);
783+
assert a.insert(5);
784+
assert a.insert(9);
785+
assert a.insert(11);
786+
787+
assert b.insert(-2);
788+
assert b.insert(3);
789+
assert b.insert(9);
790+
assert b.insert(14);
791+
assert b.insert(22);
792+
793+
let mut i = 0;
794+
let expected = [-2, 1, 5, 11, 14, 22];
795+
for a.symmetric_difference(&b) |x| {
796+
assert vec::contains(expected, x);
797+
i += 1
798+
}
799+
assert i == expected.len();
800+
}
801+
802+
#[test]
803+
fn test_union() {
804+
let mut a = linear::LinearSet::new();
805+
let mut b = linear::LinearSet::new();
806+
807+
assert a.insert(1);
808+
assert a.insert(3);
809+
assert a.insert(5);
810+
assert a.insert(9);
811+
assert a.insert(11);
812+
assert a.insert(16);
813+
assert a.insert(19);
814+
assert a.insert(24);
815+
816+
assert b.insert(-2);
817+
assert b.insert(1);
818+
assert b.insert(5);
819+
assert b.insert(9);
820+
assert b.insert(13);
821+
assert b.insert(19);
822+
823+
let mut i = 0;
824+
let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
825+
for a.union(&b) |x| {
826+
assert vec::contains(expected, x);
827+
i += 1
828+
}
829+
assert i == expected.len();
830+
}
831+
}

0 commit comments

Comments
 (0)