use std::default::Default;
use std::fmt;
use std::fmt::Show;
use std::iter::Peekable;
use std::hash::Hash;
use trie_map::{TrieMap, Entries};
#[deriving(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct TrieSet {
map: TrieMap<()>
}
impl Show for TrieSet {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "{{"));
for (i, x) in self.iter().enumerate() {
if i != 0 { try!(write!(f, ", ")); }
try!(write!(f, "{}", x));
}
write!(f, "}}")
}
}
impl Default for TrieSet {
#[inline]
fn default() -> TrieSet { TrieSet::new() }
}
impl TrieSet {
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn new() -> TrieSet {
TrieSet{map: TrieMap::new()}
}
#[inline]
pub fn each_reverse(&self, f: |&uint| -> bool) -> bool {
self.map.each_reverse(|k, _| f(k))
}
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn iter<'a>(&'a self) -> SetItems<'a> {
SetItems{iter: self.map.iter()}
}
pub fn lower_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
SetItems{iter: self.map.lower_bound(val)}
}
pub fn upper_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
SetItems{iter: self.map.upper_bound(val)}
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn difference<'a>(&'a self, other: &'a TrieSet) -> DifferenceItems<'a> {
DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
}
#[unstable = "matches collection reform specification, waiting for dust to settle."]
pub fn symmetric_difference<'a>(&'a self, other: &'a TrieSet) -> SymDifferenceItems<'a> {
SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn intersection<'a>(&'a self, other: &'a TrieSet) -> IntersectionItems<'a> {
IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()}
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn union<'a>(&'a self, other: &'a TrieSet) -> UnionItems<'a> {
UnionItems{a: self.iter().peekable(), b: other.iter().peekable()}
}
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn len(&self) -> uint { self.map.len() }
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn is_empty(&self) -> bool { self.len() == 0 }
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn clear(&mut self) { self.map.clear() }
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn contains(&self, value: &uint) -> bool {
self.map.contains_key(value)
}
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn is_disjoint(&self, other: &TrieSet) -> bool {
self.iter().all(|v| !other.contains(&v))
}
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn is_subset(&self, other: &TrieSet) -> bool {
self.iter().all(|v| other.contains(&v))
}
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn is_superset(&self, other: &TrieSet) -> bool {
other.is_subset(self)
}
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn insert(&mut self, value: uint) -> bool {
self.map.insert(value, ()).is_none()
}
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn remove(&mut self, value: &uint) -> bool {
self.map.remove(value).is_some()
}
}
impl FromIterator<uint> for TrieSet {
fn from_iter<Iter: Iterator<uint>>(iter: Iter) -> TrieSet {
let mut set = TrieSet::new();
set.extend(iter);
set
}
}
impl Extend<uint> for TrieSet {
fn extend<Iter: Iterator<uint>>(&mut self, mut iter: Iter) {
for elem in iter {
self.insert(elem);
}
}
}
#[cfg(stage0)]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
impl BitOr<TrieSet, TrieSet> for TrieSet {
fn bitor(&self, rhs: &TrieSet) -> TrieSet {
self.union(rhs).collect()
}
}
#[cfg(not(stage0))] #[unstable = "matches collection reform specification, waiting for dust to settle"]
impl<'a, 'b> BitOr<&'b TrieSet, TrieSet> for &'a TrieSet {
fn bitor(self, rhs: &TrieSet) -> TrieSet {
self.union(rhs).collect()
}
}
#[cfg(stage0)]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
impl BitAnd<TrieSet, TrieSet> for TrieSet {
fn bitand(&self, rhs: &TrieSet) -> TrieSet {
self.intersection(rhs).collect()
}
}
#[cfg(not(stage0))] #[unstable = "matches collection reform specification, waiting for dust to settle"]
impl<'a, 'b> BitAnd<&'b TrieSet, TrieSet> for &'a TrieSet {
fn bitand(self, rhs: &TrieSet) -> TrieSet {
self.intersection(rhs).collect()
}
}
#[cfg(stage0)]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
impl BitXor<TrieSet, TrieSet> for TrieSet {
fn bitxor(&self, rhs: &TrieSet) -> TrieSet {
self.symmetric_difference(rhs).collect()
}
}
#[cfg(not(stage0))] #[unstable = "matches collection reform specification, waiting for dust to settle"]
impl<'a, 'b> BitXor<&'b TrieSet, TrieSet> for &'a TrieSet {
fn bitxor(self, rhs: &TrieSet) -> TrieSet {
self.symmetric_difference(rhs).collect()
}
}
#[cfg(stage0)]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
impl Sub<TrieSet, TrieSet> for TrieSet {
fn sub(&self, rhs: &TrieSet) -> TrieSet {
self.difference(rhs).collect()
}
}
#[cfg(not(stage0))] #[unstable = "matches collection reform specification, waiting for dust to settle"]
impl<'a, 'b> Sub<&'b TrieSet, TrieSet> for &'a TrieSet {
fn sub(self, rhs: &TrieSet) -> TrieSet {
self.difference(rhs).collect()
}
}
pub struct SetItems<'a> {
iter: Entries<'a, ()>
}
pub struct DifferenceItems<'a> {
a: Peekable<uint, SetItems<'a>>,
b: Peekable<uint, SetItems<'a>>,
}
pub struct SymDifferenceItems<'a> {
a: Peekable<uint, SetItems<'a>>,
b: Peekable<uint, SetItems<'a>>,
}
pub struct IntersectionItems<'a> {
a: Peekable<uint, SetItems<'a>>,
b: Peekable<uint, SetItems<'a>>,
}
pub struct UnionItems<'a> {
a: Peekable<uint, SetItems<'a>>,
b: Peekable<uint, SetItems<'a>>,
}
fn cmp_opt(x: Option<&uint>, y: Option<&uint>, short: Ordering, long: Ordering) -> Ordering {
match (x, y) {
(None , _ ) => short,
(_ , None ) => long,
(Some(x1), Some(y1)) => x1.cmp(y1),
}
}
impl<'a> Iterator<uint> for SetItems<'a> {
fn next(&mut self) -> Option<uint> {
self.iter.next().map(|(key, _)| key)
}
fn size_hint(&self) -> (uint, Option<uint>) {
self.iter.size_hint()
}
}
impl<'a> Iterator<uint> for DifferenceItems<'a> {
fn next(&mut self) -> Option<uint> {
loop {
match cmp_opt(self.a.peek(), self.b.peek(), Less, Less) {
Less => return self.a.next(),
Equal => { self.a.next(); self.b.next(); }
Greater => { self.b.next(); }
}
}
}
}
impl<'a> Iterator<uint> for SymDifferenceItems<'a> {
fn next(&mut self) -> Option<uint> {
loop {
match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
Less => return self.a.next(),
Equal => { self.a.next(); self.b.next(); }
Greater => return self.b.next(),
}
}
}
}
impl<'a> Iterator<uint> for IntersectionItems<'a> {
fn next(&mut self) -> Option<uint> {
loop {
let o_cmp = match (self.a.peek(), self.b.peek()) {
(None , _ ) => None,
(_ , None ) => None,
(Some(a1), Some(b1)) => Some(a1.cmp(b1)),
};
match o_cmp {
None => return None,
Some(Less) => { self.a.next(); }
Some(Equal) => { self.b.next(); return self.a.next() }
Some(Greater) => { self.b.next(); }
}
}
}
}
impl<'a> Iterator<uint> for UnionItems<'a> {
fn next(&mut self) -> Option<uint> {
loop {
match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
Less => return self.a.next(),
Equal => { self.b.next(); return self.a.next() }
Greater => return self.b.next(),
}
}
}
}
#[cfg(test)]
mod test {
use std::uint;
use super::TrieSet;
#[test]
fn test_sane_chunk() {
let x = 1;
let y = 1 << (uint::BITS - 1);
let mut trie = TrieSet::new();
assert!(trie.insert(x));
assert!(trie.insert(y));
assert_eq!(trie.len(), 2);
let expected = [x, y];
for (i, x) in trie.iter().enumerate() {
assert_eq!(expected[i], x);
}
}
#[test]
fn test_from_iter() {
let xs = vec![9u, 8, 7, 6, 5, 4, 3, 2, 1];
let set: TrieSet = xs.iter().map(|&x| x).collect();
for x in xs.iter() {
assert!(set.contains(x));
}
}
#[test]
fn test_show() {
let mut set = TrieSet::new();
let empty = TrieSet::new();
set.insert(1);
set.insert(2);
let set_str = format!("{}", set);
assert!(set_str == "{1, 2}");
assert_eq!(format!("{}", empty), "{}");
}
#[test]
fn test_clone() {
let mut a = TrieSet::new();
a.insert(1);
a.insert(2);
a.insert(3);
assert!(a.clone() == a);
}
#[test]
fn test_lt() {
let mut a = TrieSet::new();
let mut b = TrieSet::new();
assert!(!(a < b) && !(b < a));
assert!(b.insert(2u));
assert!(a < b);
assert!(a.insert(3u));
assert!(!(a < b) && b < a);
assert!(b.insert(1));
assert!(b < a);
assert!(a.insert(0));
assert!(a < b);
assert!(a.insert(6));
assert!(a < b && !(b < a));
}
#[test]
fn test_ord() {
let mut a = TrieSet::new();
let mut b = TrieSet::new();
assert!(a <= b && a >= b);
assert!(a.insert(1u));
assert!(a > b && a >= b);
assert!(b < a && b <= a);
assert!(b.insert(2u));
assert!(b > a && b >= a);
assert!(a < b && a <= b);
}
struct Counter<'a, 'b> {
i: &'a mut uint,
expected: &'b [uint],
}
impl<'a, 'b> FnMut(uint) -> bool for Counter<'a, 'b> {
extern "rust-call" fn call_mut(&mut self, (x,): (uint,)) -> bool {
assert_eq!(x, self.expected[*self.i]);
*self.i += 1;
true
}
}
fn check<F>(a: &[uint], b: &[uint], expected: &[uint], f: F) where
F: FnOnce(&TrieSet, &TrieSet, Counter) -> bool,
{
let mut set_a = TrieSet::new();
let mut set_b = TrieSet::new();
for x in a.iter() { assert!(set_a.insert(*x)) }
for y in b.iter() { assert!(set_b.insert(*y)) }
let mut i = 0;
f(&set_a, &set_b, Counter { i: &mut i, expected: expected });
assert_eq!(i, expected.len());
}
#[test]
fn test_intersection() {
fn check_intersection(a: &[uint], b: &[uint], expected: &[uint]) {
check(a, b, expected, |x, y, f| x.intersection(y).all(f))
}
check_intersection(&[], &[], &[]);
check_intersection(&[1, 2, 3], &[], &[]);
check_intersection(&[], &[1, 2, 3], &[]);
check_intersection(&[2], &[1, 2, 3], &[2]);
check_intersection(&[1, 2, 3], &[2], &[2]);
check_intersection(&[11, 1, 3, 77, 103, 5],
&[2, 11, 77, 5, 3],
&[3, 5, 11, 77]);
}
#[test]
fn test_difference() {
fn check_difference(a: &[uint], b: &[uint], expected: &[uint]) {
check(a, b, expected, |x, y, f| x.difference(y).all(f))
}
check_difference(&[], &[], &[]);
check_difference(&[1, 12], &[], &[1, 12]);
check_difference(&[], &[1, 2, 3, 9], &[]);
check_difference(&[1, 3, 5, 9, 11],
&[3, 9],
&[1, 5, 11]);
check_difference(&[11, 22, 33, 40, 42],
&[14, 23, 34, 38, 39, 50],
&[11, 22, 33, 40, 42]);
}
#[test]
fn test_symmetric_difference() {
fn check_symmetric_difference(a: &[uint], b: &[uint], expected: &[uint]) {
check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f))
}
check_symmetric_difference(&[], &[], &[]);
check_symmetric_difference(&[1, 2, 3], &[2], &[1, 3]);
check_symmetric_difference(&[2], &[1, 2, 3], &[1, 3]);
check_symmetric_difference(&[1, 3, 5, 9, 11],
&[3, 9, 14, 22],
&[1, 5, 11, 14, 22]);
}
#[test]
fn test_union() {
fn check_union(a: &[uint], b: &[uint], expected: &[uint]) {
check(a, b, expected, |x, y, f| x.union(y).all(f))
}
check_union(&[], &[], &[]);
check_union(&[1, 2, 3], &[2], &[1, 2, 3]);
check_union(&[2], &[1, 2, 3], &[1, 2, 3]);
check_union(&[1, 3, 5, 9, 11, 16, 19, 24],
&[1, 5, 9, 13, 19],
&[1, 3, 5, 9, 11, 13, 16, 19, 24]);
}
#[test]
fn test_bit_or() {
let a: TrieSet = vec![1, 2, 3].into_iter().collect();
let b: TrieSet = vec![3, 4, 5].into_iter().collect();
let set: TrieSet = &a | &b;
let v: Vec<uint> = set.iter().collect();
assert_eq!(v, vec![1u, 2, 3, 4, 5]);
}
#[test]
fn test_bit_and() {
let a: TrieSet = vec![1, 2, 3].into_iter().collect();
let b: TrieSet = vec![2, 3, 4].into_iter().collect();
let set: TrieSet = &a & &b;
let v: Vec<uint> = set.iter().collect();
assert_eq!(v, vec![2u, 3]);
}
#[test]
fn test_bit_xor() {
let a: TrieSet = vec![1, 2, 3].into_iter().collect();
let b: TrieSet = vec![3, 4, 5].into_iter().collect();
let set: TrieSet = &a ^ &b;
let v: Vec<uint> = set.iter().collect();
assert_eq!(v, vec![1u, 2, 4, 5]);
}
#[test]
fn test_sub() {
let a: TrieSet = vec![1, 2, 3].into_iter().collect();
let b: TrieSet = vec![3, 4, 5].into_iter().collect();
let set: TrieSet = &a - &b;
let v: Vec<uint> = set.iter().collect();
assert_eq!(v, vec![1u, 2]);
}
}