diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index 1451bf9d7c7bc..ecd99a4bc22e0 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -714,24 +714,26 @@ impl TreeSet { } /// Visit the values (in-order) representing the difference - pub fn difference<'a>(&'a self, other: &'a TreeSet) -> DifferenceItems<'a, T> { + pub fn difference<'a>(&'a self, other: &'a TreeSet) + -> DifferenceItems<'a, T, SetItems<'a, T>> { DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} } /// Visit the values (in-order) representing the symmetric difference pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet) - -> SymDifferenceItems<'a, T> { + -> SymDifferenceItems<'a, T, SetItems<'a, T>> { SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} } /// Visit the values (in-order) representing the intersection pub fn intersection<'a>(&'a self, other: &'a TreeSet) - -> IntersectionItems<'a, T> { + -> IntersectionItems<'a, T, SetItems<'a, T>> { IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()} } /// Visit the values (in-order) representing the union - pub fn union<'a>(&'a self, other: &'a TreeSet) -> UnionItems<'a, T> { + pub fn union<'a>(&'a self, other: &'a TreeSet) + -> UnionItems<'a, T, SetItems<'a, T>> { UnionItems{a: self.iter().peekable(), b: other.iter().peekable()} } } @@ -750,27 +752,33 @@ pub struct RevSetItems<'a, T> { pub type MoveSetItems = iter::Map<'static, (T, ()), T, MoveEntries>; /// Lazy iterator producing elements in the set difference (in-order) -pub struct DifferenceItems<'a, T> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, +pub struct DifferenceItems<'a, T, I> { + a: Peekable<&'a T, I>, + b: Peekable<&'a T, I>, } /// Lazy iterator producing elements in the set symmetric difference (in-order) -pub struct SymDifferenceItems<'a, T> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, +pub struct SymDifferenceItems<'a, T, I> { + a: Peekable<&'a T, I>, + b: Peekable<&'a T, I>, +} + +/// Lazy iterator producing elements in the multiset sum (in-order) +pub struct SumItems<'a, T, I> { + a: Peekable<&'a T, I>, + b: Peekable<&'a T, I>, } /// Lazy iterator producing elements in the set intersection (in-order) -pub struct IntersectionItems<'a, T> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, +pub struct IntersectionItems<'a, T, I> { + a: Peekable<&'a T, I>, + b: Peekable<&'a T, I>, } /// Lazy iterator producing elements in the set union (in-order) -pub struct UnionItems<'a, T> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, +pub struct UnionItems<'a, T, I> { + a: Peekable<&'a T, I>, + b: Peekable<&'a T, I>, } /// Compare `x` and `y`, but return `short` if x is None and `long` if y is None @@ -783,7 +791,7 @@ fn cmp_opt(x: Option<&T>, y: Option<&T>, } } -impl<'a, T: Ord> Iterator<&'a T> for DifferenceItems<'a, T> { +impl<'a, T: Ord, I: Iterator<&'a T>> Iterator<&'a T> for DifferenceItems<'a, T, I> { fn next(&mut self) -> Option<&'a T> { loop { match cmp_opt(self.a.peek(), self.b.peek(), Less, Less) { @@ -795,7 +803,7 @@ impl<'a, T: Ord> Iterator<&'a T> for DifferenceItems<'a, T> { } } -impl<'a, T: Ord> Iterator<&'a T> for SymDifferenceItems<'a, T> { +impl<'a, T: Ord, I: Iterator<&'a T>> Iterator<&'a T> for SymDifferenceItems<'a, T, I> { fn next(&mut self) -> Option<&'a T> { loop { match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) { @@ -807,7 +815,19 @@ impl<'a, T: Ord> Iterator<&'a T> for SymDifferenceItems<'a, T> { } } -impl<'a, T: Ord> Iterator<&'a T> for IntersectionItems<'a, T> { +impl<'a, T: Ord, I: Iterator<&'a T>> Iterator<&'a T> for SumItems<'a, T, I> { + 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 => return self.a.next(), + Greater => return self.b.next(), + } + } + } +} + +impl<'a, T: Ord, I: Iterator<&'a T>> Iterator<&'a T> for IntersectionItems<'a, T, I> { fn next(&mut self) -> Option<&'a T> { loop { let o_cmp = match (self.a.peek(), self.b.peek()) { @@ -825,7 +845,7 @@ impl<'a, T: Ord> Iterator<&'a T> for IntersectionItems<'a, T> { } } -impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> { +impl<'a, T: Ord, I: Iterator<&'a T>> Iterator<&'a T> for UnionItems<'a, T, I> { fn next(&mut self) -> Option<&'a T> { loop { match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) { @@ -838,6 +858,341 @@ impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> { } +/// A implementation of a multiset on top of the `TreeMap` container. The only +/// requirement is that the type of the elements contained ascribes to the +/// `Ord` trait. +#[deriving(Clone)] +pub struct TreeMultiset { + map: TreeMap, + length: uint, +} + +impl PartialEq for TreeMultiset { + #[inline] + fn eq(&self, other: &TreeMultiset) -> bool { self.map == other.map } +} + +impl PartialOrd for TreeMultiset { + #[inline] + fn partial_cmp(&self, other: &TreeMultiset) -> Option { + self.map.partial_cmp(&other.map) + } +} + +impl> Hash for TreeMultiset { + fn hash(&self, state: &mut S) { + for elt in self.iter() { + elt.hash(state); + } + } +} + +impl Show for TreeMultiset { + 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 Collection for TreeMultiset { + #[inline] + fn len(&self) -> uint { self.length } +} + +impl Mutable for TreeMultiset { + #[inline] + fn clear(&mut self) { + self.map.clear(); + self.length = 0; + } +} + +impl Extendable for TreeMultiset { + #[inline] + fn extend>(&mut self, mut iter: Iter) { + for elem in iter { + self.insert(elem); + } + } +} + +impl FromIterator for TreeMultiset { + #[inline] + fn from_iter>(iter: Iter) -> TreeMultiset { + let mut mset = TreeMultiset::new(); + mset.extend(iter); + mset + } +} + +impl Default for TreeMultiset { + #[inline] + fn default() -> TreeMultiset { TreeMultiset::new() } +} + +impl TreeMultiset { + /// Create an empty TreeMultiset + #[inline] + pub fn new() -> TreeMultiset { TreeMultiset {map: TreeMap::new(), length: 0} } + + /// Get the number of distinct values in the multiset + #[inline] + pub fn num_distinct(&self) -> uint { self.map.len() } + + /// Get a lazy iterator over the values in the multiset. + /// Requires that it be frozen (immutable). + #[inline] + pub fn iter<'a>(&'a self) -> MultisetItems<'a, T> { + MultisetItems{iter: self.map.iter(), current: None, count: 0 } + } + + /// Get a lazy iterator over the values in the multiset. + /// Requires that it be frozen (immutable). + #[inline] + pub fn rev_iter<'a>(&'a self) -> RevMultisetItems<'a, T> { + RevMultisetItems{iter: self.map.rev_iter(), current: None, count: 0} + } + + /// Get a lazy iterator pointing to the first value greater than or equal to `v`. + /// If all elements in the multiset are less than `v`, an empty iterator is returned. + #[inline] + pub fn lower_bound<'a>(&'a self, v: &T) -> MultisetItems<'a, T> { + MultisetItems{iter: self.map.lower_bound(v), current: None, count: 0} + } + + /// Get a lazy iterator pointing to the first value greater than `v`. + /// If all elements in the multiset are not greater than `v`, an empty iterator + /// is returned. + #[inline] + pub fn upper_bound<'a>(&'a self, v: &T) -> MultisetItems<'a, T> { + MultisetItems{iter: self.map.upper_bound(v), current: None, count: 0} + } + + /// Visit the values (in-order) representing the difference + #[inline] + pub fn difference<'a>(&'a self, other: &'a TreeMultiset) + -> DifferenceItems<'a, T, MultisetItems<'a, T>> { + DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} + } + + /// Visit the values (in-order) representing the symmetric difference + #[inline] + pub fn symmetric_difference<'a>(&'a self, other: &'a TreeMultiset) + -> SymDifferenceItems<'a, T, MultisetItems<'a, T>> { + SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} + } + + /// Visit the values (in-order) representing the multiset sum + #[inline] + pub fn sum<'a>(&'a self, other: &'a TreeMultiset) + -> SumItems<'a, T, MultisetItems<'a, T>> { + SumItems{a: self.iter().peekable(), b: other.iter().peekable()} + } + + /// Visit the values (in-order) representing the intersection + #[inline] + pub fn intersection<'a>(&'a self, other: &'a TreeMultiset) + -> IntersectionItems<'a, T, MultisetItems<'a, T>> { + IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()} + } + + /// Visit the values (in-order) representing the union + #[inline] + pub fn union<'a>(&'a self, other: &'a TreeMultiset) + -> UnionItems<'a, T, MultisetItems<'a, T>> { + UnionItems{a: self.iter().peekable(), b: other.iter().peekable()} + } + + /// Return the number of occurrences of the value in the multiset. + #[inline] + pub fn count(&self, value: &T) -> uint { + match self.map.find(value) { + None => 0u, + Some(count) => *count + } + } + + /// Return true if the multiset has no elements in common with `other`. + pub fn is_disjoint(&self, other: &TreeMultiset) -> 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() && b.is_some() { + let a1 = a.unwrap(); + let b1 = b.unwrap(); + + match a1.cmp(b1) { + Less => a = x.next(), + Greater => b = y.next(), + Equal => return false, + } + } + true + } + + /// Return true if, for any given element, the number times it occurs in the + /// multiset is not greater than the number of times it occurs in `other`. + pub fn is_subset(&self, other: &TreeMultiset) -> 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 + } + + /// Return true if the value occurs at least once in the multiset. + #[inline] + pub fn contains(&self, value: &T) -> bool { + self.count(value) > 0 + } + + /// Return true if the multiset is a superset of another. + #[inline] + pub fn is_superset(&self, other: &TreeMultiset) -> bool { + other.is_subset(self) + } + + /// Add `n` occurrences of `value` to the multiset. Return true if the value + /// was not already present in the multiset. + #[inline] + pub fn insert_many(&mut self, value: T, n: uint) -> bool { + let curr = self.count(&value); + self.length += n; + self.map.insert(value, curr + n) + } + + /// Remove `n` occurrences of `value` from the multiset. If there are less + /// than `n` occurrences, remove all occurrences. Return the number of + /// occurrences removed. + #[inline] + pub fn remove_many(&mut self, value: &T, n: uint) -> uint { + let curr = self.count(value); + + if n >= curr { + self.map.remove(value); + self.length -= curr; + curr + } else { + match self.map.find_mut(value) { + None => 0u, + Some(mult) => { + self.length -= n; + *mult = curr - n; + n + } + } + } + } + + /// Add one occurrence of `value` to the multiset. Return true if the value + /// was not already present in the multiset. + #[inline] + pub fn insert(&mut self, value: T) -> bool { + self.insert_many(value, 1) + } + + /// Remove one occurrence of `value` from the multiset. Return true if the + /// value was present in the multiset. + #[inline] + pub fn remove(&mut self, value: &T) -> bool { + self.remove_many(value, 1) > 0u + } +} + +impl TreeMultiset { + pub fn to_set(&self) -> TreeSet { + let mut set = TreeSet::new(); + for (k, _) in self.map.clone().move_iter() { + set.insert(k); + } + set + } +} + +/// Lazy forward iterator over a multiset +pub struct MultisetItems<'a, T> { + iter: Entries<'a, T, uint>, + current: Option<&'a T>, + count: uint, +} + +/// Lazy backward iterator over a multiset +pub struct RevMultisetItems<'a, T> { + iter: RevEntries<'a, T, uint>, + current: Option<&'a T>, + count: uint, +} + +impl<'a, T> Iterator<&'a T> for MultisetItems<'a, T> { + #[inline] + fn next(&mut self) -> Option<&'a T> { + if self.count == 0 { + // Either we've exhausted the multiset or we just need to grab + // the next entry from self.iter + match self.iter.next() { + None => return None, + Some((val, count)) => { + self.current = Some(val); + self.count = *count; + } + } + } + + // Assume here that we will never have an entry with a count of zero. + // This means we have to take care that when we remove the last occurrence + // from a multiset, we must delete the key also. + self.count -= 1; + self.current + } +} + +impl<'a, T> Iterator<&'a T> for RevMultisetItems<'a, T> { + #[inline] + fn next(&mut self) -> Option<&'a T> { + if self.count == 0 { + // Either we've exhausted the multiset or we just need to grab + // the next entry from self.iter + match self.iter.next() { + None => return None, + Some((val, count)) => { + self.current = Some(val); + self.count = *count; + } + } + } + + // Assume here that we will never have an entry with a count of zero. + // This means we have to take care that when we remove the last occurrence + // from a multiset, we must delete the key also. + self.count -= 1; + self.current + } +} + + // Nodes keep track of their level in the tree, starting at 1 in the // leaves and with a red child sharing the level of the parent. #[deriving(Clone)] @@ -1897,3 +2252,330 @@ mod test_set { assert_eq!(format!("{}", empty), "{}".to_string()); } } + +#[cfg(test)] +mod test_mset { + use std::prelude::*; + use std::hash; + + use {Mutable, MutableMap}; + use super::{TreeMap, TreeMultiset}; + + #[test] + fn test_len() { + let mut s = TreeMultiset::new(); + assert!(s.len() == 0); + assert!(s.insert(1i)); + assert!(s.len() == 1); + assert!(s.insert_many(3, 5)); + assert!(s.len() == 6); + assert!(s.insert_many(7, 2)); + assert!(s.len() == 8); + + assert!(s.remove(&7)); + assert!(s.len() == 7); + assert!(s.remove(&7)); + assert!(s.len() == 6); + assert!(!s.remove(&7)); + assert!(s.len() == 6); + assert!(s.remove_many(&3, 3) == 3); + assert!(s.len() == 3); + assert!(s.remove_many(&3, 8) == 2); + assert!(s.len() == 1); + } + + #[test] + fn test_clear() { + let mut s = TreeMultiset::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_count() { + let mut m = TreeMultiset::new(); + assert!(m.insert(1i)); + assert!(m.count(&1) == 1); + assert!(!m.insert(1i)); + assert!(m.count(&1) == 2); + + assert!(m.count(&2) == 0); + assert!(m.insert_many(2i, 4)); + assert!(m.count(&2) == 4); + assert!(m.remove_many(&2, 3) == 3); + assert!(m.count(&2) == 1); + assert!(m.remove(&2)); + assert!(m.count(&2) == 0); + assert!(!m.remove(&2)); + assert!(m.count(&2) == 0); + } + + #[test] + fn test_disjoint() { + let mut xs = TreeMultiset::new(); + let mut ys = TreeMultiset::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!(!ys.is_disjoint(&xs)); + assert!(!xs.is_disjoint(&ys)); + assert!(!xs.insert(7)); + assert!(!ys.is_disjoint(&xs)); + assert!(!xs.is_disjoint(&ys)); + } + + #[test] + fn test_subset_and_superset() { + let mut a = TreeMultiset::new(); + assert!(a.insert(0i)); + assert!(a.insert(5)); + assert!(a.insert(11)); + assert!(a.insert(7)); + + let mut b = TreeMultiset::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!(!a.insert(5)); + assert!(b.insert(5)); + + 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)); + + assert!(!b.insert(7)); + assert!(!b.insert(7)); + + 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 = TreeMultiset::new(); + + assert!(m.insert(3i)); + assert!(m.insert(2)); + assert!(m.insert(0)); + assert!(m.insert(-2)); + assert!(m.insert(4)); + assert!(!m.insert(2)); + assert!(m.insert(1)); + + let v = vec!(-2i, 0, 1, 2, 2, 3, 4); + for (x, y) in m.iter().zip(v.iter()) { + assert_eq!(*x, *y); + } + } + + #[test] + fn test_rev_iter() { + let mut m = TreeMultiset::new(); + + assert!(m.insert(3i)); + assert!(m.insert(2)); + assert!(m.insert(0)); + assert!(m.insert(-2)); + assert!(m.insert(4)); + assert!(!m.insert(2)); + assert!(m.insert(1)); + + let v = vec!(4i, 3, 2, 2, 1, 0, -2); + for (x, y) in m.rev_iter().zip(v.iter()) { + assert_eq!(*x, *y); + } + } + + #[test] + fn test_clone_eq() { + let mut m = TreeMultiset::new(); + + m.insert(1i); + m.insert(2); + + assert!(m.clone() == m); + } + + #[test] + fn test_hash() { + let mut x = TreeMultiset::new(); + let mut y = TreeMultiset::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: |&TreeMultiset, &TreeMultiset, f: |&int| -> bool| -> bool) { + let mut set_a = TreeMultiset::new(); + let mut set_b = TreeMultiset::new(); + + for x in a.iter() { set_a.insert(*x); } + for y in b.iter() { 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, 2], [], []); + check_intersection([], [1, 2, 3, 2], []); + check_intersection([2], [1, 2, 3], [2]); + check_intersection([2, 2], [1, 2, 3, 2], [2, 2]); + check_intersection([1, 2, 3, 2], [2, 2], [2, 2]); + check_intersection([11, 5, 5, 1, 3, 77, 103, 5, -5, 1, 1, 77], + [2, 11, 77, -9, -42, 5, 3, 77, 2, 5], + [3, 5, 5, 11, 77, 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, 12, 1], [], [1, 1, 12]); + check_difference([], [1, 2, 2, 3, 9], []); + check_difference([1, 3, 3, 3, 5, 9, 11], + [3, 9, 3], + [1, 3, 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, 1, 2, 3], [2], [1, 1, 3]); + check_symmetric_difference([2, 2], [1, 2, 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_sum() { + fn check_sum(a: &[int], b: &[int], + expected: &[int]) { + check(a, b, expected, |x, y, f| x.sum(y).all(f)) + } + + check_sum([], [], []); + check_sum([1, 2, 2, 3], [2], [1, 2, 2, 2, 3]); + check_sum([2, 2], [1, 2, 2, 3], [1, 2, 2, 2, 2, 3]); + check_sum([1, 3, 5, 9, 11, 16, 19, 24], + [-2, 1, 5, 9, 13, 19], + [-2, 1, 1, 3, 5, 5, 9, 9, 11, 13, 16, 19, 19, 24]); + } + + #[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, 2, 3], [2], [1, 2, 2, 3]); + check_union([2, 2, 2], [1, 2, 2, 3], [1, 2, 2, 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_from_iter() { + let xs = [1i, 2, 3, 3, 3, 4, 5, 4, 6, 7, 8, 9]; + + let set: TreeMultiset = xs.iter().map(|&x| x).collect(); + + for x in xs.iter() { + if *x == 3 { + assert!(set.count(x) == 3); + } else if *x == 4 { + assert!(set.count(x) == 2); + } else { + assert!(set.count(x) == 1); + } + } + } + + #[test] + fn test_show() { + let mut set: TreeMultiset = TreeMultiset::new(); + let empty: TreeMultiset = TreeMultiset::new(); + + set.insert(1); + set.insert_many(2, 3); + + let set_str = format!("{}", set); + + assert!(set_str == "{1, 2, 2, 2}".to_string()); + assert_eq!(format!("{}", empty), "{}".to_string()); + } +}