// Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use core::prelude::*; use core::default::Default; use core::fmt; use core::fmt::Show; use core::iter::Peekable; use core::iter; use std::hash::{Writer, Hash}; use tree_map::{TreeMap, Entries, RevEntries, MoveEntries}; // FIXME(conventions): implement bounded iterators // FIXME(conventions): implement BitOr, BitAnd, BitXor, and Sub // FIXME(conventions): replace rev_iter(_mut) by making iter(_mut) DoubleEnded /// An implementation of the `Set` trait on top of the `TreeMap` container. The /// only requirement is that the type of the elements contained ascribes to the /// `Ord` trait. /// /// ## Example /// /// ```{rust} /// use std::collections::TreeSet; /// /// let mut set = TreeSet::new(); /// /// set.insert(2i); /// set.insert(1i); /// set.insert(3i); /// /// for i in set.iter() { /// println!("{}", i) // prints 1, then 2, then 3 /// } /// /// set.remove(&3); /// /// if !set.contains(&3) { /// println!("set does not contain a 3 anymore"); /// } /// ``` /// /// The easiest way to use `TreeSet` with a custom type is to implement `Ord`. /// We must also implement `PartialEq`, `Eq` and `PartialOrd`. /// /// ``` /// use std::collections::TreeSet; /// /// // We need `Eq` and `PartialEq`, these can be derived. /// #[deriving(Eq, PartialEq)] /// struct Troll<'a> { /// name: &'a str, /// level: uint, /// } /// /// // Implement `Ord` and sort trolls by level. /// impl<'a> Ord for Troll<'a> { /// fn cmp(&self, other: &Troll) -> Ordering { /// // If we swap `self` and `other`, we get descending ordering. /// self.level.cmp(&other.level) /// } /// } /// /// // `PartialOrd` needs to be implemented as well. /// impl<'a> PartialOrd for Troll<'a> { /// fn partial_cmp(&self, other: &Troll) -> Option { /// Some(self.cmp(other)) /// } /// } /// /// let mut trolls = TreeSet::new(); /// /// trolls.insert(Troll { name: "Orgarr", level: 2 }); /// trolls.insert(Troll { name: "Blargarr", level: 3 }); /// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 }); /// trolls.insert(Troll { name: "Wartilda", level: 1 }); /// /// println!("You are facing {} trolls!", trolls.len()); /// /// // Print the trolls, ordered by level with smallest level first /// for x in trolls.iter() { /// println!("level {}: {}!", x.level, x.name); /// } /// /// // Kill all trolls /// trolls.clear(); /// assert_eq!(trolls.len(), 0); /// ``` #[deriving(Clone)] pub struct TreeSet { map: TreeMap } impl PartialEq for TreeSet { #[inline] fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } } impl Eq for TreeSet {} impl PartialOrd for TreeSet { #[inline] fn partial_cmp(&self, other: &TreeSet) -> Option { self.map.partial_cmp(&other.map) } } impl Ord for TreeSet { #[inline] fn cmp(&self, other: &TreeSet) -> Ordering { iter::order::cmp(self.iter(), other.iter()) } } impl Show for TreeSet { 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 TreeSet { #[inline] fn default() -> TreeSet { TreeSet::new() } } impl TreeSet { /// Creates an empty `TreeSet`. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// let mut set: TreeSet = TreeSet::new(); /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } /// Gets a lazy iterator over the values in the set, in ascending order. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// let set: TreeSet = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect(); /// /// // Will print in ascending order. /// for x in set.iter() { /// println!("{}", x); /// } /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> SetItems<'a, T> { SetItems{iter: self.map.iter()} } /// Gets a lazy iterator over the values in the set, in descending order. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// let set: TreeSet = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect(); /// /// // Will print in descending order. /// for x in set.rev_iter() { /// println!("{}", x); /// } /// ``` #[inline] pub fn rev_iter<'a>(&'a self) -> RevSetItems<'a, T> { RevSetItems{iter: self.map.rev_iter()} } /// Creates a consuming iterator, that is, one that moves each value out of the /// set in ascending order. The set cannot be used after calling this. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// let set: TreeSet = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect(); /// /// // Not possible with a regular `.iter()` /// let v: Vec = set.into_iter().collect(); /// assert_eq!(v, vec![1, 2, 3, 4, 5]); /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveSetItems { self.map.into_iter().map(|(value, _)| value) } /// Gets a lazy iterator pointing to the first value not less than `v` (greater or equal). /// If all elements in the set are less than `v` empty iterator is returned. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// let set: TreeSet = [2, 4, 6, 8].iter().map(|&x| x).collect(); /// /// assert_eq!(set.lower_bound(&4).next(), Some(&4)); /// assert_eq!(set.lower_bound(&5).next(), Some(&6)); /// assert_eq!(set.lower_bound(&10).next(), None); /// ``` #[inline] pub fn lower_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> { SetItems{iter: self.map.lower_bound(v)} } /// Gets a lazy iterator pointing to the first value greater than `v`. /// If all elements in the set are less than or equal to `v` an /// empty iterator is returned. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// let set: TreeSet = [2, 4, 6, 8].iter().map(|&x| x).collect(); /// /// assert_eq!(set.upper_bound(&4).next(), Some(&6)); /// assert_eq!(set.upper_bound(&5).next(), Some(&6)); /// assert_eq!(set.upper_bound(&10).next(), None); /// ``` #[inline] pub fn upper_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> { SetItems{iter: self.map.upper_bound(v)} } /// Visits the values representing the difference, in ascending order. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); /// /// // Can be seen as `a - b`. /// for x in a.difference(&b) { /// println!("{}", x); // Print 1 then 2 /// } /// /// let diff: TreeSet = a.difference(&b).map(|&x| x).collect(); /// assert_eq!(diff, [1, 2].iter().map(|&x| x).collect()); /// /// // Note that difference is not symmetric, /// // and `b - a` means something else: /// let diff: TreeSet = b.difference(&a).map(|&x| x).collect(); /// assert_eq!(diff, [4, 5].iter().map(|&x| x).collect()); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn difference<'a>(&'a self, other: &'a TreeSet) -> DifferenceItems<'a, T> { DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} } /// Visits the values representing the symmetric difference, in ascending order. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); /// /// // Print 1, 2, 4, 5 in ascending order. /// for x in a.symmetric_difference(&b) { /// println!("{}", x); /// } /// /// let diff1: TreeSet = a.symmetric_difference(&b).map(|&x| x).collect(); /// let diff2: TreeSet = b.symmetric_difference(&a).map(|&x| x).collect(); /// /// assert_eq!(diff1, diff2); /// assert_eq!(diff1, [1, 2, 4, 5].iter().map(|&x| x).collect()); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet) -> SymDifferenceItems<'a, T> { SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} } /// Visits the values representing the intersection, in ascending order. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); /// let b: TreeSet = [2, 3, 4].iter().map(|&x| x).collect(); /// /// // Print 2, 3 in ascending order. /// for x in a.intersection(&b) { /// println!("{}", x); /// } /// /// let diff: TreeSet = a.intersection(&b).map(|&x| x).collect(); /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect()); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn intersection<'a>(&'a self, other: &'a TreeSet) -> IntersectionItems<'a, T> { IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()} } /// Visits the values representing the union, in ascending order. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); /// /// // Print 1, 2, 3, 4, 5 in ascending order. /// for x in a.union(&b) { /// println!("{}", x); /// } /// /// let diff: TreeSet = a.union(&b).map(|&x| x).collect(); /// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect()); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn union<'a>(&'a self, other: &'a TreeSet) -> UnionItems<'a, T> { UnionItems{a: self.iter().peekable(), b: other.iter().peekable()} } /// Return the number of elements in the set /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// /// let mut v = TreeSet::new(); /// assert_eq!(v.len(), 0); /// v.insert(1i); /// assert_eq!(v.len(), 1); /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.map.len() } /// Returns true if the set contains no elements /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// /// let mut v = TreeSet::new(); /// assert!(v.is_empty()); /// v.insert(1i); /// assert!(!v.is_empty()); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Clears the set, removing all values. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// /// let mut v = TreeSet::new(); /// v.insert(1i); /// v.clear(); /// assert!(v.is_empty()); /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { self.map.clear() } /// Returns `true` if the set contains a value. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// /// let set: TreeSet = [1i, 2, 3].iter().map(|&x| x).collect(); /// assert_eq!(set.contains(&1), true); /// assert_eq!(set.contains(&4), false); /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn contains(&self, value: &T) -> bool { self.map.contains_key(value) } /// Returns `true` if the set has no elements in common with `other`. /// This is equivalent to checking for an empty intersection. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// /// let a: TreeSet = [1i, 2, 3].iter().map(|&x| x).collect(); /// let mut b: TreeSet = TreeSet::new(); /// /// assert_eq!(a.is_disjoint(&b), true); /// b.insert(4); /// assert_eq!(a.is_disjoint(&b), true); /// b.insert(1); /// assert_eq!(a.is_disjoint(&b), false); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_disjoint(&self, other: &TreeSet) -> bool { self.intersection(other).next().is_none() } /// Returns `true` if the set is a subset of another. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// /// let sup: TreeSet = [1i, 2, 3].iter().map(|&x| x).collect(); /// let mut set: TreeSet = TreeSet::new(); /// /// assert_eq!(set.is_subset(&sup), true); /// set.insert(2); /// assert_eq!(set.is_subset(&sup), true); /// set.insert(4); /// assert_eq!(set.is_subset(&sup), false); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_subset(&self, other: &TreeSet) -> bool { 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 b1.cmp(a1) { Less => (), Greater => return false, Equal => a = x.next(), } b = y.next(); } true } /// Returns `true` if the set is a superset of another. /// /// # Example /// /// ``` /// use std::collections::TreeSet; /// /// let sub: TreeSet = [1i, 2].iter().map(|&x| x).collect(); /// let mut set: TreeSet = TreeSet::new(); /// /// assert_eq!(set.is_superset(&sub), false); /// /// set.insert(0); /// set.insert(1); /// assert_eq!(set.is_superset(&sub), false); /// /// set.insert(2); /// assert_eq!(set.is_superset(&sub), true); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_superset(&self, other: &TreeSet) -> bool { other.is_subset(self) } /// Adds a value to the set. Returns `true` if the value was not already /// present in the set. /// /// # Example /// /// ``` /// use std::collections::BTreeSet; /// /// let mut set = BTreeSet::new(); /// /// assert_eq!(set.insert(2i), true); /// assert_eq!(set.insert(2i), false); /// assert_eq!(set.len(), 1); /// ``` #[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() } /// Removes a value from the set. Returns `true` if the value was /// present in the set. /// /// # Example /// /// ``` /// use std::collections::BTreeSet; /// /// let mut set = BTreeSet::new(); /// /// set.insert(2i); /// assert_eq!(set.remove(&2), true); /// assert_eq!(set.remove(&2), false); /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value).is_some() } } /// A lazy forward iterator over a set. pub struct SetItems<'a, T:'a> { iter: Entries<'a, T, ()> } /// A lazy backward iterator over a set. pub struct RevSetItems<'a, T:'a> { iter: RevEntries<'a, T, ()> } /// A lazy forward iterator over a set that consumes the set while iterating. pub type MoveSetItems = iter::Map<'static, (T, ()), T, MoveEntries>; /// A lazy iterator producing elements in the set difference (in-order). pub struct DifferenceItems<'a, T:'a> { a: Peekable<&'a T, SetItems<'a, T>>, b: Peekable<&'a T, SetItems<'a, T>>, } /// A lazy iterator producing elements in the set symmetric difference (in-order). pub struct SymDifferenceItems<'a, T:'a> { a: Peekable<&'a T, SetItems<'a, T>>, b: Peekable<&'a T, SetItems<'a, T>>, } /// A lazy iterator producing elements in the set intersection (in-order). pub struct IntersectionItems<'a, T:'a> { a: Peekable<&'a T, SetItems<'a, T>>, b: Peekable<&'a T, SetItems<'a, T>>, } /// A lazy iterator producing elements in the set union (in-order). pub struct UnionItems<'a, T:'a> { a: Peekable<&'a T, SetItems<'a, T>>, b: Peekable<&'a T, SetItems<'a, T>>, } /// Compare `x` and `y`, but return `short` if x is None and `long` if y is None fn cmp_opt(x: Option<&T>, y: Option<&T>, short: Ordering, long: Ordering) -> Ordering { match (x, y) { (None , _ ) => short, (_ , None ) => long, (Some(x1), Some(y1)) => x1.cmp(y1), } } impl<'a, T> Iterator<&'a T> for SetItems<'a, T> { #[inline] fn next(&mut self) -> Option<&'a T> { self.iter.next().map(|(value, _)| value) } } impl<'a, T> Iterator<&'a T> for RevSetItems<'a, T> { #[inline] fn next(&mut self) -> Option<&'a T> { self.iter.next().map(|(value, _)| value) } } impl<'a, T: Ord> Iterator<&'a T> for DifferenceItems<'a, T> { fn next(&mut self) -> Option<&'a T> { 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, T: Ord> Iterator<&'a T> for SymDifferenceItems<'a, T> { fn next(&mut self) -> Option<&'a T> { 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, T: Ord> Iterator<&'a T> for IntersectionItems<'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(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, T: Ord> Iterator<&'a T> for UnionItems<'a, T> { fn next(&mut self) -> Option<&'a T> { 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(), } } } } impl FromIterator for TreeSet { fn from_iter>(iter: Iter) -> TreeSet { let mut set = TreeSet::new(); set.extend(iter); set } } impl Extendable for TreeSet { #[inline] fn extend>(&mut self, mut iter: Iter) { for elem in iter { self.insert(elem); } } } impl> Hash for TreeSet { fn hash(&self, state: &mut S) { for elt in self.iter() { elt.hash(state); } } } #[cfg(test)] mod test { use std::prelude::*; use std::hash; use super::TreeSet; #[test] fn test_clear() { let mut s = TreeSet::new(); s.clear(); assert!(s.insert(5i)); 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(5i)); assert!(ys.insert(11i)); 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(0i)); assert!(a.insert(5)); assert!(a.insert(11)); assert!(a.insert(7)); let mut b = TreeSet::new(); assert!(b.insert(0i)); 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(3i)); 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(3i)); 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 = range(0i, 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 = vec!(0i, 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(1i); m.insert(2); assert!(m.clone() == m); } #[test] fn test_hash() { let mut x = TreeSet::new(); let mut y = TreeSet::new(); x.insert(1i); x.insert(2); x.insert(3); y.insert(3i); y.insert(2); y.insert(1); assert!(hash::hash(&x) == hash::hash(&y)); } fn check(a: &[int], b: &[int], expected: &[int], f: |&TreeSet, &TreeSet, f: |&int| -> bool| -> 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, |x| { assert_eq!(*x, expected[i]); i += 1; true }); assert_eq!(i, expected.len()); } #[test] fn test_intersection() { fn check_intersection(a: &[int], b: &[int], expected: &[int]) { 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: &[int], b: &[int], expected: &[int]) { 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: &[int], b: &[int], expected: &[int]) { 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: &[int], b: &[int], expected: &[int]) { 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_zip() { let mut x = TreeSet::new(); x.insert(5u); x.insert(12u); x.insert(11u); 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()); // FIXME: #5801: this needs a type hint to compile... let result: Option<(&uint, & &'static str)> = z.next(); assert_eq!(result.unwrap(), (&5u, &("bar"))); let result: Option<(&uint, & &'static str)> = z.next(); assert_eq!(result.unwrap(), (&11u, &("foo"))); let result: Option<(&uint, & &'static str)> = z.next(); assert!(result.is_none()); } #[test] fn test_from_iter() { let xs = [1i, 2, 3, 4, 5, 6, 7, 8, 9]; let set: TreeSet = xs.iter().map(|&x| x).collect(); for x in xs.iter() { assert!(set.contains(x)); } } #[test] fn test_show() { let mut set: TreeSet = TreeSet::new(); let empty: TreeSet = TreeSet::new(); set.insert(1); set.insert(2); let set_str = format!("{}", set); assert!(set_str == "{1, 2}".to_string()); assert_eq!(format!("{}", empty), "{}".to_string()); } }