use std::cmp::Ordering::{self, Less, Equal, Greater};
use std::default::Default;
use std::fmt::{self, Debug};
use std::iter::{self, Peekable, IntoIterator};
use std::hash::{Hash, Hasher};
use std::ops;
use compare::{Compare, Natural, natural};
use tree_map::{self, TreeMap};
#[derive(Clone)]
pub struct TreeSet<T, C: Compare<T> = Natural<T>> {
map: TreeMap<T, (), C>
}
impl<T: PartialEq + Ord> PartialEq for TreeSet<T> {
#[inline]
fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
}
impl<T: Eq + Ord> Eq for TreeSet<T> {}
impl<T: Ord> PartialOrd for TreeSet<T> {
#[inline]
fn partial_cmp(&self, other: &TreeSet<T>) -> Option<Ordering> {
self.map.partial_cmp(&other.map)
}
}
impl<T: Ord> Ord for TreeSet<T> {
#[inline]
fn cmp(&self, other: &TreeSet<T>) -> Ordering {
iter::order::cmp(self.iter(), other.iter())
}
}
impl<T: Debug, C> Debug for TreeSet<T, C> where C: Compare<T> {
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<T, C> Default for TreeSet<T, C> where C: Compare<T> + Default {
#[inline]
fn default() -> TreeSet<T, C> { TreeSet::with_comparator(Default::default()) }
}
impl<T: Ord> TreeSet<T> {
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn new() -> TreeSet<T> { TreeSet::with_comparator(natural()) }
}
impl<T, C> TreeSet<T, C> where C: Compare<T> {
pub fn with_comparator(cmp: C) -> TreeSet<T, C> {
TreeSet { map: TreeMap::with_comparator(cmp) }
}
pub fn comparator(&self) -> &C { self.map.comparator() }
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn iter(&self) -> Iter<T> {
Iter { iter: self.map.iter() }
}
#[inline]
pub fn rev_iter(&self) -> RevIter<T> {
RevIter { iter: self.map.rev_iter() }
}
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn into_iter(self) -> IntoIter<T> {
fn first<A, B>((a, _): (A, B)) -> A { a }
let first: fn((T, ())) -> T = first;
IntoIter(self.map.into_iter().map(first))
}
#[inline]
pub fn lower_bound(&self, v: &T) -> Iter<T> {
Iter { iter: self.map.lower_bound(v) }
}
#[inline]
pub fn upper_bound(&self, v: &T) -> Iter<T> {
Iter { iter: self.map.upper_bound(v) }
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn difference<'a>(&'a self, other: &'a TreeSet<T, C>)
-> Difference<'a, T, C> where C: Eq {
assert!(self.comparator() == other.comparator());
Difference {
a: self.iter().peekable(),
b: other.iter().peekable(),
cmp: self.comparator(),
}
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet<T, C>)
-> SymmetricDifference<'a, T, C> where C: Eq {
assert!(self.comparator() == other.comparator());
SymmetricDifference {
a: self.iter().peekable(),
b: other.iter().peekable(),
cmp: self.comparator(),
}
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn intersection<'a>(&'a self, other: &'a TreeSet<T, C>)
-> Intersection<'a, T, C> where C: Eq {
assert!(self.comparator() == other.comparator());
Intersection {
a: self.iter().peekable(),
b: other.iter().peekable(),
cmp: self.comparator(),
}
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn union<'a>(&'a self, other: &'a TreeSet<T, C>) -> Union<'a, T, C>
where C: Eq {
assert!(self.comparator() == other.comparator());
Union {
a: self.iter().peekable(),
b: other.iter().peekable(),
cmp: self.comparator(),
}
}
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn len(&self) -> usize { 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<Q: ?Sized>(&self, value: &Q) -> bool
where C: Compare<Q, T>
{
self.map.contains_key(value)
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn is_disjoint(&self, other: &TreeSet<T, C>) -> bool where C: Eq {
self.intersection(other).next().is_none()
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn is_subset(&self, other: &TreeSet<T, C>) -> bool where C: Eq {
assert!(self.comparator() == other.comparator());
let mut x = self.iter();
let mut y = other.iter();
let mut a = x.next();
let mut b = y.next();
while a.is_some() {
if b.is_none() {
return false;
}
let a1 = a.unwrap();
let b1 = b.unwrap();
match self.comparator().compare(b1, a1) {
Less => (),
Greater => return false,
Equal => a = x.next(),
}
b = y.next();
}
true
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn is_superset(&self, other: &TreeSet<T, C>) -> bool where C: Eq {
other.is_subset(self)
}
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() }
#[inline]
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
where C: Compare<Q, T>
{
self.map.remove(value).is_some()
}
}
pub struct Iter<'a, T:'a> {
iter: tree_map::Iter<'a, T, ()>
}
pub struct RevIter<'a, T:'a> {
iter: tree_map::RevIter<'a, T, ()>
}
pub struct IntoIter<T>(iter::Map<tree_map::IntoIter<T, ()>, fn((T, ())) -> T>);
pub struct Difference<'a, T:'a, C:'a> {
a: Peekable<Iter<'a, T>>,
b: Peekable<Iter<'a, T>>,
cmp: &'a C,
}
pub struct SymmetricDifference<'a, T:'a, C:'a> {
a: Peekable<Iter<'a, T>>,
b: Peekable<Iter<'a, T>>,
cmp: &'a C,
}
pub struct Intersection<'a, T:'a, C:'a> {
a: Peekable<Iter<'a, T>>,
b: Peekable<Iter<'a, T>>,
cmp: &'a C,
}
pub struct Union<'a, T:'a, C:'a> {
a: Peekable<Iter<'a, T>>,
b: Peekable<Iter<'a, T>>,
cmp: &'a C,
}
fn cmp_opt<T, C: Compare<T>>(x: Option<& &T>, y: Option<& &T>,
short: Ordering, long: Ordering, cmp: &C) -> Ordering {
match (x, y) {
(None , _ ) => short,
(_ , None ) => long,
(Some(x1), Some(y1)) => cmp.compare(*x1, *y1),
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
#[inline] fn next(&mut self) -> Option<&'a T> { self.iter.next().map(|(value, _)| value) }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
impl<'a, T> Iterator for RevIter<'a, T> {
type Item = &'a T;
#[inline] fn next(&mut self) -> Option<&'a T> { self.iter.next().map(|(value, _)| value) }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
impl<T> Iterator for IntoIter<T> {
type Item = T;
#[inline] fn next(&mut self) -> Option<T> { self.0.next() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
}
impl<'a, T, C> Iterator for Difference<'a, T, C> where C: Compare<T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
match cmp_opt(self.a.peek(), self.b.peek(), Less, Less, self.cmp) {
Less => return self.a.next(),
Equal => { self.a.next(); self.b.next(); }
Greater => { self.b.next(); }
}
}
}
}
impl<'a, T, C> Iterator for SymmetricDifference<'a, T, C> where C: Compare<T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less, self.cmp) {
Less => return self.a.next(),
Equal => { self.a.next(); self.b.next(); }
Greater => return self.b.next(),
}
}
}
}
impl<'a, T, C> Iterator for Intersection<'a, T, C> where C: Compare<T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
let o_cmp = match (self.a.peek(), self.b.peek()) {
(None , _ ) => None,
(_ , None ) => None,
(Some(a1), Some(b1)) => Some(self.cmp.compare(*a1, *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, T, C> Iterator for Union<'a, T, C> where C: Compare<T> {
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less, self.cmp) {
Less => return self.a.next(),
Equal => { self.b.next(); return self.a.next() }
Greater => return self.b.next(),
}
}
}
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
impl<'a, 'b, T, C> ops::BitOr<&'b TreeSet<T, C>> for &'a TreeSet<T, C>
where T: Clone, C: Compare<T> + Eq + Clone {
type Output = TreeSet<T, C>;
fn bitor(self, rhs: &TreeSet<T, C>) -> TreeSet<T, C> {
let it = self.union(rhs).cloned();
let mut set = TreeSet::with_comparator(self.comparator().clone());
set.extend(it);
set
}
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
impl<'a, 'b, T, C> ops::BitAnd<&'b TreeSet<T, C>> for &'a TreeSet<T, C>
where T: Clone, C: Compare<T> + Eq + Clone {
type Output = TreeSet<T, C>;
fn bitand(self, rhs: &TreeSet<T, C>) -> TreeSet<T, C> {
let it = self.intersection(rhs).cloned();
let mut set = TreeSet::with_comparator(self.comparator().clone());
set.extend(it);
set
}
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
impl<'a, 'b, T, C> ops::BitXor<&'b TreeSet<T, C>> for &'a TreeSet<T, C>
where T: Clone, C: Compare<T> + Eq + Clone {
type Output = TreeSet<T, C>;
fn bitxor(self, rhs: &TreeSet<T, C>) -> TreeSet<T, C> {
let it = self.symmetric_difference(rhs).cloned();
let mut set = TreeSet::with_comparator(self.comparator().clone());
set.extend(it);
set
}
}
#[unstable = "matches collection reform specification, waiting for dust to settle"]
impl<'a, 'b, T, C> ops::Sub<&'b TreeSet<T, C>> for &'a TreeSet<T, C>
where T: Clone, C: Compare<T> + Eq + Clone {
type Output = TreeSet<T, C>;
fn sub(self, rhs: &TreeSet<T, C>) -> TreeSet<T, C> {
let it = self.difference(rhs).cloned();
let mut set = TreeSet::with_comparator(self.comparator().clone());
set.extend(it);
set
}
}
impl<T, C> iter::FromIterator<T> for TreeSet<T, C> where C: Compare<T> + Default {
fn from_iter<Iter: IntoIterator<Item=T>>(iter: Iter) -> TreeSet<T, C> {
let mut set: TreeSet<T, C> = Default::default();
set.extend(iter);
set
}
}
impl<T, C> Extend<T> for TreeSet<T, C> where C: Compare<T> {
#[inline]
fn extend<Iter: IntoIterator<Item=T>>(&mut self, iter: Iter) {
for elem in iter {
self.insert(elem);
}
}
}
impl<T: Hash, C> Hash for TreeSet<T, C> where C: Compare<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
for elt in self.iter() {
elt.hash(state);
}
}
}
impl<'a, T, C> IntoIterator for &'a TreeSet<T, C> where C: Compare<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> { self.iter() }
}
impl<T, C> IntoIterator for TreeSet<T, C> where C: Compare<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> { self.into_iter() }
}
#[cfg(feature="ordered_iter")]
impl<'a, K> ::ordered_iter::OrderedSetIterator for Iter<'a, K> {}
#[cfg(test)]
mod test {
use std::hash;
use super::TreeSet;
#[test]
fn test_clear() {
let mut s = TreeSet::new();
s.clear();
assert!(s.insert(5));
assert!(s.insert(12));
assert!(s.insert(19));
s.clear();
assert!(!s.contains(&5));
assert!(!s.contains(&12));
assert!(!s.contains(&19));
assert!(s.is_empty());
}
#[test]
fn test_disjoint() {
let mut xs = TreeSet::new();
let mut ys = TreeSet::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 = TreeSet::new();
assert!(a.insert(0));
assert!(a.insert(5));
assert!(a.insert(11));
assert!(a.insert(7));
let mut b = TreeSet::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_iterator() {
let mut m = TreeSet::new();
assert!(m.insert(3));
assert!(m.insert(0));
assert!(m.insert(4));
assert!(m.insert(2));
assert!(m.insert(1));
let mut n = 0;
for x in m.iter() {
assert_eq!(*x, n);
n += 1
}
}
#[test]
fn test_rev_iter() {
let mut m = TreeSet::new();
assert!(m.insert(3));
assert!(m.insert(0));
assert!(m.insert(4));
assert!(m.insert(2));
assert!(m.insert(1));
let mut n = 4;
for x in m.rev_iter() {
assert_eq!(*x, n);
n -= 1;
}
}
#[test]
fn test_move_iter() {
let s: TreeSet<i32> = range(0, 5).collect();
let mut n = 0;
for x in s.into_iter() {
assert_eq!(x, n);
n += 1;
}
}
#[test]
fn test_move_iter_size_hint() {
let s: TreeSet<i32> = vec!(0, 1).into_iter().collect();
let mut it = s.into_iter();
assert_eq!(it.size_hint(), (2, Some(2)));
assert!(it.next() != None);
assert_eq!(it.size_hint(), (1, Some(1)));
assert!(it.next() != None);
assert_eq!(it.size_hint(), (0, Some(0)));
assert_eq!(it.next(), None);
}
#[test]
fn test_clone_eq() {
let mut m = TreeSet::new();
m.insert(1);
m.insert(2);
assert!(m.clone() == m);
}
#[test]
fn test_hash() {
let mut x = TreeSet::new();
let mut y = TreeSet::new();
x.insert(1);
x.insert(2);
x.insert(3);
y.insert(3);
y.insert(2);
y.insert(1);
assert!(hash::hash::<_, hash::SipHasher>(&x) == hash::hash::<_, hash::SipHasher>(&y));
}
struct Counter<'a, 'b> {
i: &'a mut usize,
expected: &'b [i32],
}
impl<'a, 'b, 'c> FnMut<(&'c i32,)> for Counter<'a, 'b> {
type Output = bool;
extern "rust-call" fn call_mut(&mut self, (&x,): (&'c i32,)) -> bool {
assert_eq!(x, self.expected[*self.i]);
*self.i += 1;
true
}
}
fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) where
F: FnOnce(&TreeSet<i32>, &TreeSet<i32>, Counter) -> bool,
{
let mut set_a = TreeSet::new();
let mut set_b = TreeSet::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: &[i32], b: &[i32], expected: &[i32]) {
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, -5],
&[2, 11, 77, -9, -42, 5, 3],
&[3, 5, 11, 77]);
}
#[test]
fn test_difference() {
fn check_difference(a: &[i32], b: &[i32], expected: &[i32]) {
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(&[-5, 11, 22, 33, 40, 42],
&[-12, -5, 14, 23, 34, 38, 39, 50],
&[11, 22, 33, 40, 42]);
}
#[test]
fn test_symmetric_difference() {
fn check_symmetric_difference(a: &[i32], b: &[i32],
expected: &[i32]) {
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],
&[-2, 3, 9, 14, 22],
&[-2, 1, 5, 11, 14, 22]);
}
#[test]
fn test_union() {
fn check_union(a: &[i32], b: &[i32],
expected: &[i32]) {
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],
&[-2, 1, 5, 9, 13, 19],
&[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
}
#[test]
fn test_bit_or() {
let a: TreeSet<i32> = vec![1, 3, 5, 9, 11, 16, 19, 24].into_iter().collect();
let b: TreeSet<i32> = vec![-2, 1, 5, 9, 13, 19].into_iter().collect();
let set: TreeSet<i32> = &a | &b;
let v: Vec<i32> = set.into_iter().collect();
assert_eq!(v, vec![-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
}
#[test]
fn test_bit_and() {
let a: TreeSet<i32> = vec![11, 1, 3, 77, 103, 5, -5].into_iter().collect();
let b: TreeSet<i32> = vec![2, 11, 77, -9, -42, 5, 3].into_iter().collect();
let set: TreeSet<i32> = &a & &b;
let v: Vec<i32> = set.into_iter().collect();
assert_eq!(v, vec![3, 5, 11, 77]);
}
#[test]
fn test_bit_xor() {
let a: TreeSet<i32> = vec![1, 3, 5, 9, 11].into_iter().collect();
let b: TreeSet<i32> = vec![-2, 3, 9, 14, 22].into_iter().collect();
let set: TreeSet<i32> = &a ^ &b;
let v: Vec<i32> = set.into_iter().collect();
assert_eq!(v, vec![-2, 1, 5, 11, 14, 22]);
}
#[test]
fn test_sub() {
let a: TreeSet<i32> = vec![-5, 11, 22, 33, 40, 42].into_iter().collect();
let b: TreeSet<i32> = vec![-12, -5, 14, 23, 34, 38, 39, 50].into_iter().collect();
let set: TreeSet<i32> = &a - &b;
let v: Vec<i32> = set.into_iter().collect();
assert_eq!(v, vec![11, 22, 33, 40, 42]);
}
#[test]
fn test_zip() {
let mut x = TreeSet::new();
x.insert(5);
x.insert(12);
x.insert(11);
let mut y = TreeSet::new();
y.insert("foo");
y.insert("bar");
let x = x;
let y = y;
let mut z = x.iter().zip(y.iter());
assert_eq!(z.next().unwrap(), (&5, &("bar")));
assert_eq!(z.next().unwrap(), (&11, &("foo")));
assert!(z.next().is_none());
}
#[test]
fn test_from_iter() {
let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let set: TreeSet<i32> = xs.iter().map(|&x| x).collect();
for x in xs.iter() {
assert!(set.contains(x));
}
}
#[test]
fn test_debug() {
let mut set = TreeSet::new();
let empty: TreeSet<i32> = TreeSet::new();
set.insert(1);
set.insert(2);
assert_eq!(format!("{:?}", set), "{1, 2}");
assert_eq!(format!("{:?}", empty), "{}");
}
#[test]
fn test_comparator_iterator() {
use compare::{Compare, natural};
let mut m = TreeSet::with_comparator(natural().rev());
assert!(m.insert(3));
assert!(m.insert(0));
assert!(m.insert(4));
assert!(m.insert(2));
assert!(m.insert(1));
let mut n = 5;
for &t in m.iter() {
n -= 1;
assert_eq!(t, n);
}
assert_eq!(n, 0);
}
#[test]
fn test_comparator_borrowed() {
use compare::{Compare, natural};
let mut m = TreeSet::with_comparator(natural().borrow());
assert!(m.insert("a".to_string()));
assert!(m.contains("a"));
assert!(m.contains(&"a"));
assert!(m.contains(&"a".to_string()));
assert!(m.remove("a"));
assert!(!m.remove(&"a"));
assert!(!m.remove(&"a".to_string()));
}
}