diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 1cb30eaa040b2..6ec3cdee7d018 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -120,7 +120,9 @@ impl Arc { pub fn new(data: T) -> Arc { Arc { x: UnsafeArc::new(data) } } +} +impl Arc { pub fn get<'a>(&'a self) -> &'a T { unsafe { &*self.x.get_immut() } } @@ -138,9 +140,56 @@ impl Arc { let Arc { x: x } = self; x.unwrap() } + + pub fn try_get_mut<'a>(&'a mut self) -> Either<&'a mut Arc, &'a mut T> { + unsafe { + if !self.x.is_owned() { + Left(self) + } else { + Right(&mut *self.x.get()) + } + } + } + + pub fn try_unwrap(self) -> Either, T> { + match self.x.try_unwrap() { + Left(this) => Left(Arc {x: this}), + Right(v) => Right(v) + } + } +} + +impl Arc { + /// Clones the content if there is more than one reference, and returns a + /// mutable reference to the data once this is the only refence + #[inline] + pub fn cow<'r>(&'r mut self) -> &'r mut T { + unsafe { + if !self.x.is_owned() { + self.cow_clone() + } else { + &mut *self.x.get() + } + } + } + + #[inline(never)] + unsafe fn cow_clone<'r>(&'r mut self) -> &'r mut T { + self.x = UnsafeArc::new_unsafe((*self.x.get_immut()).clone()); + &mut *self.x.get() + } + + pub fn value(self) -> T { + unsafe { + match self.x.try_unwrap() { + Left(this) => (*this.get()).clone(), + Right(v) => v + } + } + } } -impl Clone for Arc { +impl Clone for Arc { /** * Duplicate an atomically reference counted wrapper. * @@ -622,6 +671,15 @@ mod tests { info2!("{:?}", arc_v); } + #[test] + fn test_arc_mut() { + let mut x = Arc::new(5); + let y = x.clone(); + *x.cow() = 9; + assert_eq!(*x.get(), 9); + assert_eq!(*y.get(), 5); + } + #[test] fn test_mutex_arc_condvar() { let arc = ~MutexArc::new(false); diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 432d854ad5469..9d86e376d7407 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -12,10 +12,13 @@ //! trees. The only requirement for the types is that the key implements //! `TotalOrd`. +use std::uint; -use std::util::{swap, replace}; -use std::iter::{Peekable}; -use std::cmp::Ordering; +pub use self::own::{TreeMap, TreeSet, + TreeMapIterator, TreeMapRevIterator, TreeMapMoveIterator, + TreeSetIterator, TreeSetRevIterator, TreeSetMoveIterator, + TreeMapHandleIterator, + Difference, SymDifference, Intersection, Union}; // This is implemented as an AA tree, which is a simplified variation of // a red-black tree where red (horizontal) nodes can only be added @@ -33,1494 +36,2183 @@ use std::cmp::Ordering; // * union: | // These would be convenient since the methods work like `each` -#[allow(missing_doc)] -#[deriving(Clone)] -pub struct TreeMap { - priv root: Option<~TreeNode>, - priv length: uint -} +/// structure representing a path into a balanced binary tree +/// this supports up to 62/126 elements which is enough given the balance assumption -impl Eq for TreeMap { - fn eq(&self, other: &TreeMap) -> bool { - self.len() == other.len() && - self.iter().zip(other.iter()).all(|(a, b)| a == b) - } +trait TreePathBuilder { + /// push a descent direction into the path + fn push(&mut self, b: bool); + + /// pop a descent direction from the path + fn pop(&mut self); } -// Lexicographical comparison -fn lt(a: &TreeMap, - b: &TreeMap) -> bool { - // the Zip iterator is as long as the shortest of a and b. - for ((key_a, value_a), (key_b, value_b)) in a.iter().zip(b.iter()) { - if *key_a < *key_b { return true; } - if *key_a > *key_b { return false; } - if *value_a < *value_b { return true; } - if *value_a > *value_b { return false; } - } +#[deriving(Clone, Default, Eq)] +struct ForgetTreePath; - a.len() < b.len() +impl TreePathBuilder for ForgetTreePath { + fn push(&mut self, _b: bool) {} + fn pop(&mut self) {} } -impl Ord for TreeMap { - #[inline] - fn lt(&self, other: &TreeMap) -> bool { lt(self, other) } - #[inline] - fn le(&self, other: &TreeMap) -> bool { !lt(other, self) } - #[inline] - fn ge(&self, other: &TreeMap) -> bool { !lt(self, other) } - #[inline] - fn gt(&self, other: &TreeMap) -> bool { lt(other, self) } +#[deriving(Clone, Eq)] +struct TreePath +{ + v: uint, // 0001hijk, or 000001ab + r: uint, // 1abcdefg, or 0 } -impl Container for TreeMap { - /// Return the number of elements in the map - fn len(&self) -> uint { self.length } - - /// Return true if the map contains no elements - fn is_empty(&self) -> bool { self.root.is_none() } -} +impl TreePath +{ + /// create an empty TreePath + pub fn new() -> TreePath + { + TreePath {v: 1, r: 0} + } -impl Mutable for TreeMap { - /// Clear the map, removing all key-value pairs. - fn clear(&mut self) { - self.root = None; - self.length = 0 + fn push_out_of_space(&mut self) + { + if self.r != 0 { + fail2!("TreePath too long for a balanced binary tree in RAM"); + } + self.r = self.v; + self.v = 1; } -} -impl Map for TreeMap { - /// Return a reference to the value corresponding to the key - fn find<'a>(&'a self, key: &K) -> Option<&'a V> { - let mut current: &'a Option<~TreeNode> = &self.root; - loop { - match *current { - Some(ref r) => { - match key.cmp(&r.key) { - Less => current = &r.left, - Greater => current = &r.right, - Equal => return Some(&r.value) - } - } - None => return None - } + fn pop_out_of_space(&mut self) + { + if self.r != 0 { + fail2!("popping from empty TreePath"); + } + self.v = self.r; + self.r = 0; + } + + /// return an iterator + pub fn iter<'a>(&'a self) -> TreePathIterator + { + let z = self.v.leading_zeros(); + let v = (self.v + self.v + 1) << z; + if self.r == 0 { + TreePathIterator {v: v, r: 0} + } else { + TreePathIterator {v: self.r + self.r + 1, r: v} } } } -impl MutableMap for TreeMap { - /// Return a mutable reference to the value corresponding to the key +impl Default for TreePath { + fn default() -> TreePath {TreePath::new()} +} + +impl TreePathBuilder for TreePath { #[inline] - fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> { - find_mut(&mut self.root, key) + fn push(&mut self, b: bool) + { + if((self.v as int) < 0) { + self.push_out_of_space(); + } + self.v = self.v + self.v + (b as uint); + } + + #[inline] + fn pop(&mut self) + { + self.v >>= 1; + if(self.v == 1) { + self.pop_out_of_space(); + } } +} + +struct TreePathIterator +{ + v: uint, // abcde100,, or 0 + r: uint, // fghi1000, or 0 +} - /// Insert a key-value pair from the map. If the key already had a value - /// present in the map, that value is returned. Otherwise None is returned. - fn swap(&mut self, key: K, value: V) -> Option { - let ret = insert(&mut self.root, key, value); - if ret.is_none() { self.length += 1 } - ret +impl Iterator for TreePathIterator { + #[inline] + fn next(&mut self) -> Option { + let p = self.v; + self.v = p + p; + if self.v != 0 { + Some((p as int) < 0) + } else if p != 0 && self.r != 0 { + let p = self.r; + self.r = 0; + self.v = p + p; + Some((p as int) < 0) + } else { + None + } } - /// Removes a key from the map, returning the value at the key if the key - /// was previously in the map. - fn pop(&mut self, key: &K) -> Option { - let ret = remove(&mut self.root, key); - if ret.is_some() { self.length -= 1 } - ret + fn size_hint(&self) -> (uint, Option) { + (0, Some((uint::bits - 1) * 2)) } } -impl TreeMap { - /// Create an empty TreeMap - pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } +#[deriving(Clone)] +enum TreeSubset +{ + EmptyTreeSubset, + SubTree(T), + InOrderFrom(T) +} - /// Iterate over the map and mutate the contained values - pub fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool { - mutate_values(&mut self.root, f) - } +macro_rules! iterator { + ($mod_name:ident, $Name:ident, $RM:ty, $ROP:ty, $RP:ty, $RK:ty, $RV:ty, $get:ident, $as_ref:ident, $destructure: ident, $ctor:ident, $Clone:ident) => { + mod $mod_name { + use std::cmp::Ordering; + use std::rc::Rc; + use std::owned::Own; + use arc::Arc; + + use super::super::{TreePath, TreePathIterator, TreePathBuilder, ForgetTreePath, TreeSubset, EmptyTreeSubset, SubTree, InOrderFrom, Dummy}; + use super::{TreeMap, TreeNode, TreeDir, TreeLeft, TreeRight}; + + /// Lazy forward iterator over a map + /// iterates over the subtree pointed to by node, then over stack in pop order, + /// visiting the elements of stack itself and their right (forward) + /// or left (for backward) subtrees + pub struct $Name<'self, K, V, D, TP> { + priv stack: ~[($ROP, $RK, $RV, TP)], + priv node: Option<($RP, TP)>, + priv remaining_min: uint, + priv remaining_max: uint, + priv dir: D + } - /// Get a lazy iterator over the key-value pairs in the map. - /// Requires that it be frozen (immutable). - pub fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> { - TreeMapIterator { - stack: ~[], - node: &self.root, - remaining_min: self.length, - remaining_max: self.length - } - } + impl<'self, K, V, D: TreeDir, TP: Default> $Name<'self, K, V, D, TP> { + /// create a new iterator + pub fn new(root: $ROP, len: uint) -> $Name<'self, K, V, D, TP> { + $Name { + stack: ~[], + node: match root.$as_ref() {Some(root) => Some((root, Default::default())), None => None}, + remaining_min: len, + remaining_max: len, + dir: TreeDir::new() + } + } + } + + impl<'self, K: TotalOrd + $Clone, V: $Clone, D: TreeDir, TP: TreePathBuilder + Default + Clone> $Name<'self, K, V, D, TP> { + /// create a new iterator starting at a specific key + pub fn new_at(root: $ROP, len: uint, k: &K, which: Ordering) -> $Name<'self, K, V, D, TP> { + let mut iter: $Name<'self, K, V, D, TP> = $Name::new(root, len); + loop { + let dir = match iter.node { + Some((ref mut rr, _)) => { + let r = rr.get(); + match (*k).cmp(&r.key) { + Equal => which, + x => x + } + } + None => { + Equal + } + }; + match dir { + Less => iter.traverse::(), + Greater => iter.traverse::(), + Equal => { + iter.traverse_complete(); + return iter; + } + } + } + } + } + + impl<'self, K: $Clone, V: $Clone, D: TreeDir, TP: TreePathBuilder + Clone> $Name<'self, K, V, D, TP> { + /// internal: return next element and tree path to it + pub fn next_with_path(&mut self) -> Option<($RK, $RV, TP)> { + while !self.stack.is_empty() || self.node.is_some() { + match self.node.take() { + Some((x, path_)) => { + let mut path = path_; + let (key, value, left, right) = x.$get().$destructure(); + let (to_stack, to_node) = if self.dir.is_right() {(right, left)} else {(left, right)}; + self.stack.push((to_stack, key, value, path.clone())); + self.node = match to_node.$as_ref() { + Some(node) => { + path.push(self.dir.is_left()); + Some((node, path)) + }, + None => None + }; + } + None => { + let (next, key, value, path) = self.stack.pop(); + self.node = match next.$as_ref() { + Some(node) => { + let mut node_path = path.clone(); + node_path.push(self.dir.is_right()); + Some((node, node_path)) + } + None => None + }; + self.remaining_max -= 1; + if self.remaining_min > 0 { + self.remaining_min -= 1; + } + return Some((key, value, path)); + } + } + } + None + } + + /// traverse_left, traverse_right and traverse_complete are used to + /// initialize TreeMapIterator pointing to element inside tree structure. + /// + /// They should be used in following manner: + /// - create iterator using TreeMap::iter_for_traversal + /// - find required node using `traverse_left`/`traverse_right` + /// (current node is `TreeMapIterator::node` field) + /// - complete initialization with `traverse_complete` + #[inline] + fn traverse(&mut self) { + let dir: TD = TreeDir::new(); + match self.node.take() { + None => fail2!(), + Some((node, path_)) => { + let mut path = path_; + let (key, value, left, right) = node.$get().$destructure(); + let to_node = if dir.is_right() != self.dir.is_right() { + if dir.is_right() { + self.stack.push((left, key, value, path.clone())); + right + } else { + self.stack.push((right, key, value, path.clone())); + left + } + } else { + self.remaining_min = 0; + if dir.is_right() {right} else {left} + }; + + self.node = match to_node.$as_ref() { + None => None, + Some(node) => { + path.push(dir.is_right()); + Some((node, path)) + } + } + } + } + } - /// Get a lazy reverse iterator over the key-value pairs in the map. - /// Requires that it be frozen (immutable). - pub fn rev_iter<'a>(&'a self) -> TreeMapRevIterator<'a, K, V> { - TreeMapRevIterator{iter: self.iter()} - } + /// traverse_left, traverse_right and traverse_complete are used to + /// initialize TreeMapIterator pointing to element inside tree structure. + /// + /// Completes traversal. Should be called before using iterator. + /// Iteration will start from `self.node`. + /// If `self.node` is None iteration will start from last node from which we + /// traversed left. + #[inline] + fn traverse_complete(&mut self) { + match self.node.take() { + Some((node, path)) => { + let (key, value, left, right) = node.$get().$destructure(); + self.stack.push((if self.dir.is_right() {right} else {left}, key, value, path)); + self.node = None; + self.remaining_min = 0; + } + None => () + } + } + } - /// Get a lazy iterator that should be initialized using - /// `iter_traverse_left`/`iter_traverse_right`/`iter_traverse_complete`. - fn iter_for_traversal<'a>(&'a self) -> TreeMapIterator<'a, K, V> { - TreeMapIterator { - stack: ~[], - node: &self.root, - remaining_min: 0, - remaining_max: self.length - } - } + impl<'self, K: $Clone, V: $Clone, D: TreeDir, TP: TreePathBuilder + Clone> Iterator<($RK, $RV)> for $Name<'self, K, V, D, TP> { + /// Advance the iterator to the next node (in order) and return a + /// tuple with a reference to the key and value. If there are no + /// more nodes, return `None`. + fn next(&mut self) -> Option<($RK, $RV)> { + match self.next_with_path() { + None => None, + Some((k, v, _)) => Some((k, v)) + } + } - /// Return a lazy iterator to the first key-value pair whose key is not less than `k` - /// If all keys in map are less than `k` an empty iterator is returned. - pub fn lower_bound_iter<'a>(&'a self, k: &K) -> TreeMapIterator<'a, K, V> { - let mut iter: TreeMapIterator<'a, K, V> = self.iter_for_traversal(); - loop { - match *iter.node { - Some(ref r) => { - match k.cmp(&r.key) { - Less => iter_traverse_left(&mut iter), - Greater => iter_traverse_right(&mut iter), - Equal => { - iter_traverse_complete(&mut iter); - return iter; - } + #[inline] + fn size_hint(&self) -> (uint, Option) { + (self.remaining_min, Some(self.remaining_max)) } - } - None => { - iter_traverse_complete(&mut iter); - return iter; - } } - } - } - /// Return a lazy iterator to the first key-value pair whose key is greater than `k` - /// If all keys in map are not greater than `k` an empty iterator is returned. - pub fn upper_bound_iter<'a>(&'a self, k: &K) -> TreeMapIterator<'a, K, V> { - let mut iter: TreeMapIterator<'a, K, V> = self.iter_for_traversal(); - loop { - match *iter.node { - Some(ref r) => { - match k.cmp(&r.key) { - Less => iter_traverse_left(&mut iter), - Greater => iter_traverse_right(&mut iter), - Equal => iter_traverse_right(&mut iter) - } - } - None => { - iter_traverse_complete(&mut iter); - return iter; - } + impl<'self, K, V, D: TreeDir, TP: TreePathBuilder + Default + Clone> $Name<'self, K, V, D, TP> { + /// return the subset that identifies the items in this iterator + pub fn get_subset(&self) -> TreeSubset { + match self.node { + Some((_, ref path)) => SubTree(path.clone()), + None => match self.stack.len() { + 0 => EmptyTreeSubset, + len => match self.stack[len - 1] { + (_, _, _, ref path) => InOrderFrom(path.clone()) + } + } + } + } } - } - } - /// Get a lazy iterator that consumes the treemap. - pub fn move_iter(self) -> TreeMapMoveIterator { - let TreeMap { root: root, length: length } = self; - let stk = match root { - None => ~[], - Some(~tn) => ~[tn] - }; - TreeMapMoveIterator { - stack: stk, - remaining: length + impl<'self, K: TotalOrd + $Clone, V: $Clone, D: TreeDir> $Name<'self, K, V, D, TreePath> { + /// create an iterator based on a subset + pub fn from_subset<'a>(map: $RM, subset: TreeSubset) + -> $Name<'a, K, V, D, TreePath> { + let mut iter = map.$ctor(); + match subset { + EmptyTreeSubset => iter.node = None, + SubTree(ref path) | InOrderFrom(ref path) => { + for dir in path.iter() { + if !dir { + iter.traverse::(); + } else { + iter.traverse::(); + } + } + } + } + + match subset { + InOrderFrom(_) => iter.traverse_complete(), + _ => {} + }; + + iter + } + } } } } -/// Lazy forward iterator over a map -pub struct TreeMapIterator<'self, K, V> { - priv stack: ~[&'self ~TreeNode], - priv node: &'self Option<~TreeNode>, - priv remaining_min: uint, - priv remaining_max: uint -} +macro_rules! treemap { + // we can't use multiplicity for New because the separator token would be +, + // which conflicts with the Kleene star plus, and cannot be escaped + ($mod_name:ident, $P:ty, $new:expr, $Clone:ident, $New1:ident + $New2:ident) => { + mod $mod_name { + #[allow(unused_imports)]; + + use std::util::{swap, replace}; + use std::iter::{Peekable}; + use std::cmp::Ordering; + use std::rc::Rc; + use std::owned::Own; + use arc::Arc; + use std::cast::transmute; + + use super::{TreePath, TreePathIterator, TreePathBuilder, ForgetTreePath, TreeSubset, EmptyTreeSubset, SubTree, InOrderFrom, Dummy}; + + pub use self::base_iter::TreeMapBaseIterator; + pub use self::mut_iter::TreeMapMutBaseIterator; + + #[allow(missing_doc)] + #[deriving(Clone)] + pub struct TreeMap { + priv root: Option<$P>, + priv length: uint + } -impl<'self, K, V> TreeMapIterator<'self, K, V> { - #[inline(always)] - fn next_(&mut self, forward: bool) -> Option<(&'self K, &'self V)> { - while !self.stack.is_empty() || self.node.is_some() { - match *self.node { - Some(ref x) => { - self.stack.push(x); - self.node = if forward { &x.left } else { &x.right }; - } - None => { - let res = self.stack.pop(); - self.node = if forward { &res.right } else { &res.left }; - self.remaining_max -= 1; - if self.remaining_min > 0 { - self.remaining_min -= 1; - } - return Some((&res.key, &res.value)); - } + impl Eq for TreeMap { + fn eq(&self, other: &TreeMap) -> bool { + self.len() == other.len() && + self.iter().zip(other.iter()).all(|(a, b)| a == b) + } } - } - None - } -} -impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V> { - /// Advance the iterator to the next node (in order) and return a - /// tuple with a reference to the key and value. If there are no - /// more nodes, return `None`. - fn next(&mut self) -> Option<(&'self K, &'self V)> { - self.next_(true) - } + // Lexicographical comparison + fn lt(a: &TreeMap, + b: &TreeMap) -> bool { + // the Zip iterator is as long as the shortest of a and b. + for ((key_a, value_a), (key_b, value_b)) in a.iter().zip(b.iter()) { + if *key_a < *key_b { return true; } + if *key_a > *key_b { return false; } + if *value_a < *value_b { return true; } + if *value_a > *value_b { return false; } + } - #[inline] - fn size_hint(&self) -> (uint, Option) { - (self.remaining_min, Some(self.remaining_max)) - } -} + a.len() < b.len() + } -/// Lazy backward iterator over a map -pub struct TreeMapRevIterator<'self, K, V> { - priv iter: TreeMapIterator<'self, K, V>, -} + impl Ord for TreeMap { + #[inline] + fn lt(&self, other: &TreeMap) -> bool { lt(self, other) } + } -impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapRevIterator<'self, K, V> { - /// Advance the iterator to the next node (in order) and return a - /// tuple with a reference to the key and value. If there are no - /// more nodes, return `None`. - fn next(&mut self) -> Option<(&'self K, &'self V)> { - self.iter.next_(false) - } + impl Container for TreeMap { + /// Return the number of elements in the map + fn len(&self) -> uint { self.length } - #[inline] - fn size_hint(&self) -> (uint, Option) { - self.iter.size_hint() - } -} + /// Return true if the map contains no elements + fn is_empty(&self) -> bool { self.root.is_none() } + } -/// iter_traverse_left, iter_traverse_right and iter_traverse_complete are used to -/// initialize TreeMapIterator pointing to element inside tree structure. -/// -/// They should be used in following manner: -/// - create iterator using TreeMap::iter_for_traversal -/// - find required node using `iter_traverse_left`/`iter_traverse_right` -/// (current node is `TreeMapIterator::node` field) -/// - complete initialization with `iter_traverse_complete` -#[inline] -fn iter_traverse_left<'a, K, V>(it: &mut TreeMapIterator<'a, K, V>) { - let node = it.node.get_ref(); - it.stack.push(node); - it.node = &node.left; -} + impl Mutable for TreeMap { + /// Clear the map, removing all key-value pairs. + fn clear(&mut self) { + self.root = None; + self.length = 0 + } + } -#[inline] -fn iter_traverse_right<'a, K, V>(it: &mut TreeMapIterator<'a, K, V>) { - it.node = &(it.node.get_ref().right); -} + impl Map for TreeMap { + /// Return a reference to the value corresponding to the key + fn find<'a>(&'a self, key: &K) -> Option<&'a V> { + let mut current: &'a Option<$P> = &self.root; + loop { + match *current { + Some(ref rr) => { + let r = rr.get(); + match key.cmp(&r.key) { + Less => current = &r.left, + Greater => current = &r.right, + Equal => return Some(&r.value) + } + } + None => return None + } + } + } + } -/// iter_traverse_left, iter_traverse_right and iter_traverse_complete are used to -/// initialize TreeMapIterator pointing to element inside tree structure. -/// -/// Completes traversal. Should be called before using iterator. -/// Iteration will start from `self.node`. -/// If `self.node` is None iteration will start from last node from which we -/// traversed left. -#[inline] -fn iter_traverse_complete<'a, K, V>(it: &mut TreeMapIterator<'a, K, V>) { - static none: Option<~TreeNode> = None; - match *it.node { - Some(ref n) => { - it.stack.push(n); - it.node = &none; - } - None => () - } -} + impl + MutableMap for TreeMap { + /// Return a mutable reference to the value corresponding to the key + #[inline] + fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> { + find_mut(&mut self.root, key) + } -/// Lazy forward iterator over a map that consumes the map while iterating -pub struct TreeMapMoveIterator { - priv stack: ~[TreeNode], - priv remaining: uint -} + /// Insert a key-value pair from the map. If the key already had a value + /// present in the map, that value is returned. Otherwise None is returned. + fn swap(&mut self, key: K, value: V) -> Option { + let ret = insert(&mut self.root, key, value); + if ret.is_none() { self.length += 1 } + ret + } -impl Iterator<(K, V)> for TreeMapMoveIterator { - #[inline] - fn next(&mut self) -> Option<(K, V)> { - while !self.stack.is_empty() { - let TreeNode { - key: key, - value: value, - left: left, - right: right, - level: level - } = self.stack.pop(); - - match left { - Some(~left) => { - let n = TreeNode { - key: key, - value: value, - left: None, - right: right, - level: level + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + fn pop(&mut self, key: &K) -> Option { + let ret = remove(&mut self.root, key); + if ret.is_some() { self.length -= 1 } + ret + } + } + + impl TreeMap { + /// Create an empty TreeMap + pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } + + fn iter_<'a, D: TreeDir, TP: Default>(&'a self) -> TreeMapBaseIterator<'a, K, V, D, TP> { + TreeMapBaseIterator::new(&self.root, self.length) + } + + fn iter_at_<'a, D: TreeDir, TP: TreePathBuilder + Clone + Default>(&'a self, k: &K, which: Ordering) + -> TreeMapBaseIterator<'a, K, V, D, TP> { + TreeMapBaseIterator::new_at(&self.root, self.length, k, which) + } + + fn handle_iter_<'a, D: TreeDir>(&'a mut self) -> TreeMapHandleIterator<'a, K, V, D> { + TreeMapHandleIterator {map: self, state: Left(self.iter_()), cache: None} + } + + fn handle_iter_at_<'a, D: TreeDir>(&'a mut self, k: &K, which: Ordering) + -> TreeMapHandleIterator<'a, K, V, D> { + TreeMapHandleIterator {map: self, state: Left(self.iter_at_(k, which)), cache: None} + } + + /// Get a lazy iterator over the key-value pairs in the map. + /// Requires that it be frozen (immutable). + pub fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> { + self.iter_() + } + + /// Get a lazy reverse iterator over the key-value pairs in the map. + /// Requires that it be frozen (immutable). + pub fn rev_iter<'a>(&'a self) -> TreeMapRevIterator<'a, K, V> { + self.iter_() + } + + /// Lazy iterator to the first key-value pair whose key is not less than `k` + /// If all keys in map are less than `k` an empty iterator is returned. + pub fn lower_bound_iter<'a>(&'a self, k: &K) -> TreeMapIterator<'a, K, V> { + self.iter_at_(k, Equal) + } + + /// Lazy iterator to the first key-value pair whose key is greater than `k` + /// If all keys in map are not greater than `k` an empty iterator is returned. + pub fn upper_bound_iter<'a>(&'a self, k: &K) -> TreeMapIterator<'a, K, V> { + self.iter_at_(k, Greater) + } + + /// Lazy rev iterator to the last key-value pair whose key is not greater than `k` + /// If all keys in map are greater than `k` an empty iterator is returned. + pub fn rev_lower_bound_iter<'a>(&'a self, k: &K) -> TreeMapRevIterator<'a, K, V> { + self.iter_at_(k, Equal) + } + + /// Lazy rev iterator to the first key-value pair whose key is less than `k` + /// If all keys in map are not less than `k` an empty iterator is returned. + pub fn rev_upper_bound_iter<'a>(&'a self, k: &K) -> TreeMapRevIterator<'a, K, V> { + self.iter_at_(k, Less) + } + + /// Get a lazy iterator over the key-value pairs in the map. + pub fn handle_iter<'a>(&'a mut self) -> TreeMapHandleIterator<'a, K, V, TreeRight> { + self.handle_iter_() + } + + /// Get a lazy reverse iterator over the key-value pairs in the map. + pub fn handle_rev_iter<'a>(&'a mut self) -> TreeMapHandleIterator<'a, K, V, TreeLeft> { + self.handle_iter_() + } + + /// Lazy iterator to the first key-value pair whose key is not less than `k` + /// If all keys in map are less than `k` an empty iterator is returned. + pub fn handle_lower_bound_iter<'a>(&'a mut self, k: &K) -> TreeMapHandleIterator<'a, K, V, TreeRight> { + self.handle_iter_at_(k, Equal) + } + + /// Lazy iterator to the first key-value pair whose key is greater than `k` + /// If all keys in map are not greater than `k` an empty iterator is returned. + pub fn handle_upper_bound_iter<'a>(&'a mut self, k: &K) -> TreeMapHandleIterator<'a, K, V, TreeRight> { + self.handle_iter_at_(k, Greater) + } + + /// Lazy rev iterator to the last key-value pair whose key is not greater than `k` + /// If all keys in map are greater than `k` an empty iterator is returned. + pub fn handle_rev_lower_bound_iter<'a>(&'a mut self, k: &K) -> TreeMapHandleIterator<'a, K, V, TreeLeft> { + self.handle_iter_at_(k, Equal) + } + + /// Lazy rev iterator to the first key-value pair whose key is less than `k` + /// If all keys in map are not less than `k` an empty iterator is returned. + pub fn handle_rev_upper_bound_iter<'a>(&'a mut self, k: &K) -> TreeMapHandleIterator<'a, K, V, TreeLeft> { + self.handle_iter_at_(k, Less) + } + } + + impl TreeMap { + fn mut_iter_<'a, D: TreeDir, TP: Default>(&'a mut self) -> TreeMapMutBaseIterator<'a, K, V, D, TP> { + TreeMapMutBaseIterator::new(&mut self.root, self.length) + } + + fn mut_iter_at_<'a, D: TreeDir, TP: TreePathBuilder + Clone + Default>(&'a mut self, k: &K, which: Ordering) + -> TreeMapMutBaseIterator<'a, K, V, D, TP> { + TreeMapMutBaseIterator::new_at(&mut self.root, self.length, k, which) + } + + /// Get a lazy iterator over the key-value pairs in the map. + pub fn mut_iter<'a>(&'a mut self) -> TreeMapMutIterator<'a, K, V> { + self.mut_iter_() + } + + /// Get a lazy reverse iterator over the key-value pairs in the map. + pub fn mut_rev_iter<'a>(&'a mut self) -> TreeMapMutRevIterator<'a, K, V> { + self.mut_iter_() + } + + /// Lazy iterator to the first key-value pair whose key is not less than `k` + /// If all keys in map are less than `k` an empty iterator is returned. + pub fn mut_lower_bound_iter<'a>(&'a mut self, k: &K) -> TreeMapMutIterator<'a, K, V> { + self.mut_iter_at_(k, Equal) + } + + /// Lazy iterator to the first key-value pair whose key is greater than `k` + /// If all keys in map are not greater than `k` an empty iterator is returned. + pub fn mut_upper_bound_iter<'a>(&'a mut self, k: &K) -> TreeMapMutIterator<'a, K, V> { + self.mut_iter_at_(k, Greater) + } + + /// Lazy rev iterator to the last key-value pair whose key is not greater than `k` + /// If all keys in map are greater than `k` an empty iterator is returned. + pub fn mut_rev_lower_bound_iter<'a>(&'a mut self, k: &K) -> TreeMapMutRevIterator<'a, K, V> { + self.mut_iter_at_(k, Equal) + } + + /// Lazy rev iterator to the first key-value pair whose key is less than `k` + /// If all keys in map are not less than `k` an empty iterator is returned. + pub fn mut_rev_upper_bound_iter<'a>(&'a mut self, k: &K) -> TreeMapMutRevIterator<'a, K, V> { + self.mut_iter_at_(k, Less) + } + + /// Get a lazy iterator that consumes the TreeMap. + pub fn move_iter(self) -> TreeMapMoveIterator { + let TreeMap { root: root, length: length } = self; + let stk = match root { + None => ~[], + Some(tn) => ~[tn.value()] }; - self.stack.push(n); - self.stack.push(left); + TreeMapMoveIterator { + stack: stk, + remaining: length + } } - None => { - match right { - Some(~right) => self.stack.push(right), - None => () + } + + iterator!(base_iter, TreeMapBaseIterator, &'a TreeMap, &'self Option<$P>, &'self $P, &'self K, &'self V, get, as_ref, destructure, iter_, Dummy) + iterator!(mut_iter, TreeMapMutBaseIterator, &'a mut TreeMap, &'self mut Option<$P>, &'self mut $P, &'self K, &'self mut V, cow, as_mut, destructure_mut, mut_iter_, $Clone) + + pub type TreeMapIterator<'self, K, V> = TreeMapBaseIterator<'self, K, V, TreeRight, ForgetTreePath>; + pub type TreeMapRevIterator<'self, K, V> = TreeMapBaseIterator<'self, K, V, TreeLeft, ForgetTreePath>; + pub type TreeMapMutIterator<'self, K, V> = TreeMapMutBaseIterator<'self, K, V, TreeRight, ForgetTreePath>; + pub type TreeMapMutRevIterator<'self, K, V> = TreeMapMutBaseIterator<'self, K, V, TreeLeft, ForgetTreePath>; + + /// mutable iterator for TreeMap + pub struct TreeMapHandleIterator<'self, K, V, D> { + priv map: &'self TreeMap, + priv state: Either, TreeSubset>, + priv cache: Option<(&'self K, &'self V, TreePath)>, + } + + /// handle to a key-value pair in the treemap + pub struct TreeMapHandle<'self, K, V, D> { + priv iter: *TreeMapHandleIterator<'self, K, V, D>, + priv path: TreePath + } + + impl<'self, K: TotalOrd + $Clone, V: $Clone, D: TreeDir> Iterator> for TreeMapHandleIterator<'self, K, V, D> { + // unfortunately we can't return the pointers, because we can't put a lifetime parameter here + fn next(&mut self) -> Option> { + match self.next() { + None => None, + Some((_, _, handle)) => Some(handle), } - self.remaining -= 1; - return Some((key, value)) } } - } - None - } + + impl<'self, K: TotalOrd + $Clone, V: $Clone, D: TreeDir> TreeMapHandleIterator<'self, K, V, D> { + /// returns the next item + pub fn next<'a>(&'a mut self) -> Option<(&'a K, &'a V, TreeMapHandle<'self, K, V, D>)> { + let res = self.get_iter().next_with_path(); + if res.is_none() { + return None + } + self.cache = res; + let (key, value, ref path) = self.cache.unwrap(); + return Some((key, value, TreeMapHandle {iter: self as *mut TreeMapHandleIterator<'self, K, V, D> as *TreeMapHandleIterator<'self, K, V, D>, path: path.clone()})) + } - #[inline] - fn size_hint(&self) -> (uint, Option) { - (self.remaining, Some(self.remaining)) - } + fn get_iter<'a>(&'a mut self) -> &'a mut TreeMapBaseIterator<'self, K, V, D, TreePath> { + let subset = match self.state { + Left(ref mut iter) => return iter, + Right(subset) => subset, + }; + self.state = Left(TreeMapBaseIterator::from_subset(self.map, subset)); + match self.state { + Left(ref mut iter) => iter, + Right(_) => unreachable!(), + } + } -} + fn destroy_iter(&mut self) { + let subset = match self.state { + Left(ref iter) => iter.get_subset(), + Right(_) => return, + }; + self.state = Right(subset); + self.cache = None; + } -impl<'self, T> Iterator<&'self T> for TreeSetIterator<'self, T> { - /// Advance the iterator to the next node (in order). If there are no more nodes, return `None`. - #[inline] - fn next(&mut self) -> Option<&'self T> { - do self.iter.next().map |(value, _)| { value } - } -} + fn resolve_handle<'a>(&self, handle: &'a TreeMapHandle<'self, K, V, D>) -> &'a TreePath { + if handle.iter != (self as *TreeMapHandleIterator<'self, K, V, D>) { + fail2!("the TreeMapHandle belongs to another iterator") + } + &handle.path + } -impl<'self, T> Iterator<&'self T> for TreeSetRevIterator<'self, T> { - /// Advance the iterator to the next node (in order). If there are no more nodes, return `None`. - #[inline] - fn next(&mut self) -> Option<&'self T> { - do self.iter.next().map |(value, _)| { value } - } -} + /// get a reference to the element pointed to by the handle + pub fn get<'a>(&'a self, handle: &TreeMapHandle<'self, K, V, D>) -> (&'a K, &'a V) { + let path = self.resolve_handle(handle); -/// A 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 -/// `TotalOrd` trait. -pub struct TreeSet { - priv map: TreeMap -} + match self.cache { + Some((key, value, cache_path)) => if *path == cache_path { + return (key, value) + }, + None => {} + } + + let node = follow_path(&self.map.root, *path).get_ref().get(); + //self.cache = Some((&node.key, &node.value, handle.path.clone())); + (&node.key, &node.value) + } + } -impl Eq for TreeSet { - #[inline] - fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } - #[inline] - fn ne(&self, other: &TreeSet) -> bool { self.map != other.map } -} + impl<'self, K: TotalOrd + $Clone, V: $Clone, D: TreeDir> TreeMapHandleIterator<'self, K, V, D> { + /// get a mutable reference to the element pointed to by the handle + pub fn get_mut<'a>(&'a mut self, handle: &TreeMapHandle<'self, K, V, D>) -> (&'a K, &'a mut V) { + let path = self.resolve_handle(handle); + + self.destroy_iter(); + unsafe { + let mut_map: &mut TreeMap = transmute(self.map); + let node = follow_path_mut(&mut mut_map.root, *path).get_mut_ref().cow(); + self.cache = Some((transmute(&node.key), transmute(&node.value), handle.path.clone())); + (&node.key, &mut node.value) + } + } -impl Ord for TreeSet { - #[inline] - fn lt(&self, other: &TreeSet) -> bool { self.map < other.map } - #[inline] - fn le(&self, other: &TreeSet) -> bool { self.map <= other.map } - #[inline] - fn ge(&self, other: &TreeSet) -> bool { self.map >= other.map } - #[inline] - fn gt(&self, other: &TreeSet) -> bool { self.map > other.map } -} + /// remove an item (and destroy the iterator) + pub fn remove(self, handle: TreeMapHandle<'self, K, V, D>) { + let mut this = self; + let path = this.resolve_handle(&handle); -impl Container for TreeSet { - /// Return the number of elements in the set - #[inline] - fn len(&self) -> uint { self.map.len() } + this.destroy_iter(); + unsafe { + let mut_map: &mut TreeMap = transmute(this.map); + remove_path(&mut mut_map.root, path.iter()); + } + } + } - /// Return true if the set contains no elements - #[inline] - fn is_empty(&self) -> bool { self.map.is_empty() } -} + /// Lazy forward iterator over a map that consumes the map while iterating + pub struct TreeMapMoveIterator { + priv stack: ~[TreeNode], + priv remaining: uint + } -impl Mutable for TreeSet { - /// Clear the set, removing all values. - #[inline] - fn clear(&mut self) { self.map.clear() } -} + impl Iterator<(K, V)> for TreeMapMoveIterator { + #[inline] + fn next(&mut self) -> Option<(K, V)> { + while !self.stack.is_empty() { + let TreeNode { + key: key, + value: value, + left: left, + right: right, + level: level + } = self.stack.pop(); + + match left { + Some(left) => { + let n = TreeNode { + key: key, + value: value, + left: None, + right: right, + level: level + }; + self.stack.push(n); + self.stack.push(left.value()); + } + None => { + match right { + Some(right) => self.stack.push(right.value()), + None => () + } + self.remaining -= 1; + return Some((key, value)) + } + } + } + None + } -impl Set for TreeSet { - /// Return true if the set contains a value - #[inline] - fn contains(&self, value: &T) -> bool { - self.map.contains_key(value) - } + #[inline] + fn size_hint(&self) -> (uint, Option) { + (self.remaining, Some(self.remaining)) + } - /// Return true if the set has no elements in common with `other`. - /// This is equivalent to checking for an empty intersection. - fn is_disjoint(&self, other: &TreeSet) -> bool { - self.intersection(other).next().is_none() - } + } - /// Return true if the set is a subset of another - #[inline] - fn is_subset(&self, other: &TreeSet) -> bool { - other.is_superset(self) - } + impl<'self, T> Iterator<&'self T> for TreeSetIterator<'self, T> { + /// Advance the iterator to the next node (in order). + /// If there are no more nodes, return `None`. + #[inline] + fn next(&mut self) -> Option<&'self T> { + do self.iter.next().map |(value, _)| { value } + } + } - /// Return true if the set is a superset of another - fn is_superset(&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 b.is_some() { - if a.is_none() { - return false + impl<'self, T> Iterator<&'self T> for TreeSetRevIterator<'self, T> { + /// Advance the iterator to the next node (in order). + /// If there are no more nodes, return `None`. + #[inline] + fn next(&mut self) -> Option<&'self T> { + do self.iter.next().map |(value, _)| { value } + } } - let a1 = a.unwrap(); - let b1 = b.unwrap(); + impl Iterator for TreeSetMoveIterator { + /// Advance the iterator to the next node (in order). + /// If there are no more nodes, return `None`. + #[inline] + fn next(&mut self) -> Option { + do self.iter.next().map |(value, _)| { value } + } + } - match a1.cmp(b1) { - Less => (), - Greater => return false, - Equal => b = y.next(), + /// A 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 + /// `TotalOrd` trait. + pub struct TreeSet { + priv map: TreeMap } - a = x.next(); - } - true - } -} + impl Eq for TreeSet { + #[inline] + fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } + } -impl MutableSet for TreeSet { - /// Add a value to the set. Return true if the value was not already - /// present in the set. - #[inline] - fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) } + impl Ord for TreeSet { + #[inline] + fn lt(&self, other: &TreeSet) -> bool { self.map < other.map } + } - /// Remove a value from the set. Return true if the value was - /// present in the set. - #[inline] - fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } -} + impl Container for TreeSet { + /// Return the number of elements in the set + #[inline] + fn len(&self) -> uint { self.map.len() } -impl TreeSet { - /// Create an empty TreeSet - #[inline] - pub fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } + /// Return true if the set contains no elements + #[inline] + fn is_empty(&self) -> bool { self.map.is_empty() } + } - /// Get a lazy iterator over the values in the set. - /// Requires that it be frozen (immutable). - #[inline] - pub fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> { - TreeSetIterator{iter: self.map.iter()} - } + impl Mutable for TreeSet { + /// Clear the set, removing all values. + #[inline] + fn clear(&mut self) { self.map.clear() } + } - /// Get a lazy iterator over the values in the set. - /// Requires that it be frozen (immutable). - #[inline] - pub fn rev_iter<'a>(&'a self) -> TreeSetRevIterator<'a, T> { - TreeSetRevIterator{iter: self.map.rev_iter()} - } + impl Set for TreeSet { + /// Return true if the set contains a value + #[inline] + fn contains(&self, value: &T) -> bool { + self.map.contains_key(value) + } - /// Get 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. - #[inline] - pub fn lower_bound_iter<'a>(&'a self, v: &T) -> TreeSetIterator<'a, T> { - TreeSetIterator{iter: self.map.lower_bound_iter(v)} - } + /// Return true if the set has no elements in common with `other`. + /// This is equivalent to checking for an empty intersection. + fn is_disjoint(&self, other: &TreeSet) -> bool { + self.intersection(other).next().is_none() + } - /// Get a lazy iterator pointing to the first value greater than `v`. - /// If all elements in the set are not greater than `v` empty iterator is returned. - #[inline] - pub fn upper_bound_iter<'a>(&'a self, v: &T) -> TreeSetIterator<'a, T> { - TreeSetIterator{iter: self.map.upper_bound_iter(v)} - } + /// Return true if the set is a subset of another + #[inline] + fn is_subset(&self, other: &TreeSet) -> bool { + other.is_superset(self) + } - /// Visit the values (in-order) representing the difference - pub fn difference<'a>(&'a self, other: &'a TreeSet) -> Difference<'a, T> { - Difference{a: self.iter().peekable(), b: other.iter().peekable()} - } + /// Return true if the set is a superset of another + fn is_superset(&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 b.is_some() { + if a.is_none() { + return false + } + + let a1 = a.unwrap(); + let b1 = b.unwrap(); + + match a1.cmp(b1) { + Less => (), + Greater => return false, + Equal => b = y.next(), + } + + a = x.next(); + } + true + } + } - /// Visit the values (in-order) representing the symmetric difference - pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet) - -> SymDifference<'a, T> { - SymDifference{a: self.iter().peekable(), b: other.iter().peekable()} - } + impl MutableSet for TreeSet { + /// Add a value to the set. Return true if the value was not already + /// present in the set. + #[inline] + fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) } - /// Visit the values (in-order) representing the intersection - pub fn intersection<'a>(&'a self, other: &'a TreeSet) - -> Intersection<'a, T> { - Intersection{a: self.iter().peekable(), b: other.iter().peekable()} - } + /// Remove a value from the set. Return true if the value was + /// present in the set. + #[inline] + fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } + } - /// Visit the values (in-order) representing the union - pub fn union<'a>(&'a self, other: &'a TreeSet) -> Union<'a, T> { - Union{a: self.iter().peekable(), b: other.iter().peekable()} - } -} + impl TreeSet { + /// Create an empty TreeSet + #[inline] + pub fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } -/// Lazy forward iterator over a set -pub struct TreeSetIterator<'self, T> { - priv iter: TreeMapIterator<'self, T, ()> -} + /// Get a lazy iterator over the values in the set. + /// Requires that it be frozen (immutable). + #[inline] + pub fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> { + TreeSetIterator{iter: self.map.iter()} + } -/// Lazy backward iterator over a set -pub struct TreeSetRevIterator<'self, T> { - priv iter: TreeMapRevIterator<'self, T, ()> -} + /// Get a lazy iterator over the values in the set. + /// Requires that it be frozen (immutable). + #[inline] + pub fn rev_iter<'a>(&'a self) -> TreeSetRevIterator<'a, T> { + TreeSetRevIterator{iter: self.map.rev_iter()} + } -/// Lazy iterator producing elements in the set difference (in-order) -pub struct Difference<'self, T> { - priv a: Peekable<&'self T, TreeSetIterator<'self, T>>, - priv b: Peekable<&'self T, TreeSetIterator<'self, T>>, -} + /// 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. + #[inline] + pub fn lower_bound_iter<'a>(&'a self, v: &T) -> TreeSetIterator<'a, T> { + TreeSetIterator{iter: self.map.lower_bound_iter(v)} + } -/// Lazy iterator producing elements in the set symmetric difference (in-order) -pub struct SymDifference<'self, T> { - priv a: Peekable<&'self T, TreeSetIterator<'self, T>>, - priv b: Peekable<&'self T, TreeSetIterator<'self, T>>, -} + /// Lazy iterator pointing to the first value greater than `v`. + /// If all elements in the set are not greater than `v` empty iterator is returned. + #[inline] + pub fn upper_bound_iter<'a>(&'a self, v: &T) -> TreeSetIterator<'a, T> { + TreeSetIterator{iter: self.map.upper_bound_iter(v)} + } -/// Lazy iterator producing elements in the set intersection (in-order) -pub struct Intersection<'self, T> { - priv a: Peekable<&'self T, TreeSetIterator<'self, T>>, - priv b: Peekable<&'self T, TreeSetIterator<'self, T>>, -} + /// Lazy iterator pointing to the last value not greater than `v` (less or equal). + /// If all elements in the set are greater than `v` empty iterator is returned. + #[inline] + pub fn rev_lower_bound_iter<'a>(&'a self, v: &T) -> TreeSetRevIterator<'a, T> { + TreeSetRevIterator{iter: self.map.rev_lower_bound_iter(v)} + } -/// Lazy iterator producing elements in the set intersection (in-order) -pub struct Union<'self, T> { - priv a: Peekable<&'self T, TreeSetIterator<'self, T>>, - priv b: Peekable<&'self T, TreeSetIterator<'self, T>>, -} + /// Lazy iterator pointing to the last value less than `v`. + /// If all elements in the set are not less than `v` empty iterator is returned. + #[inline] + pub fn rev_upper_bound_iter<'a>(&'a self, v: &T) -> TreeSetRevIterator<'a, T> { + TreeSetRevIterator{iter: self.map.rev_upper_bound_iter(v)} + } -/// 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), - } -} + /// Visit the values (in-order) representing the difference + pub fn difference<'a>(&'a self, other: &'a TreeSet) -> Difference<'a, T> { + Difference{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) + -> SymDifference<'a, T> { + SymDifference{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) + -> Intersection<'a, T> { + Intersection{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) -> Union<'a, T> { + Union{a: self.iter().peekable(), b: other.iter().peekable()} + } + } -impl<'self, T: TotalOrd> Iterator<&'self T> for Difference<'self, T> { - fn next(&mut self) -> Option<&'self 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 TreeSet { + /// Get a lazy iterator that consumes the TreeMap. + #[inline] + pub fn move_iter(self) -> TreeSetMoveIterator { + TreeSetMoveIterator{iter: self.map.move_iter()} + } } - } - } -} -impl<'self, T: TotalOrd> Iterator<&'self T> for SymDifference<'self, T> { - fn next(&mut self) -> Option<&'self 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(), + /// Lazy forward iterator over a set + pub struct TreeSetIterator<'self, T> { + priv iter: TreeMapIterator<'self, T, ()> + } + + /// Lazy backward iterator over a set + pub struct TreeSetRevIterator<'self, T> { + priv iter: TreeMapRevIterator<'self, T, ()> + } + + /// Move iterator over a set + pub struct TreeSetMoveIterator { + priv iter: TreeMapMoveIterator + } + + /// Lazy iterator producing elements in the set difference (in-order) + pub struct Difference<'self, T> { + priv a: Peekable<&'self T, TreeSetIterator<'self, T>>, + priv b: Peekable<&'self T, TreeSetIterator<'self, T>>, + } + + /// Lazy iterator producing elements in the set symmetric difference (in-order) + pub struct SymDifference<'self, T> { + priv a: Peekable<&'self T, TreeSetIterator<'self, T>>, + priv b: Peekable<&'self T, TreeSetIterator<'self, T>>, + } + + /// Lazy iterator producing elements in the set intersection (in-order) + pub struct Intersection<'self, T> { + priv a: Peekable<&'self T, TreeSetIterator<'self, T>>, + priv b: Peekable<&'self T, TreeSetIterator<'self, T>>, + } + + /// Lazy iterator producing elements in the set intersection (in-order) + pub struct Union<'self, T> { + priv a: Peekable<&'self T, TreeSetIterator<'self, T>>, + priv b: Peekable<&'self T, TreeSetIterator<'self, 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<'self, T: TotalOrd> Iterator<&'self T> for Difference<'self, T> { + fn next(&mut self) -> Option<&'self 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<'self, T: TotalOrd> Iterator<&'self T> for SymDifference<'self, T> { + fn next(&mut self) -> Option<&'self 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<'self, T: TotalOrd> Iterator<&'self T> for Intersection<'self, T> { + fn next(&mut self) -> Option<&'self 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<'self, T: TotalOrd> Iterator<&'self T> for Union<'self, T> { + fn next(&mut self) -> Option<&'self 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(), + } + } + } + } + + + // 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)] + struct TreeNode { + key: K, + value: V, + left: Option<$P>, + right: Option<$P>, + level: uint + } + + impl TreeNode { + fn destructure<'a>(&'a self) -> (&'a K, &'a V, &'a Option<$P>, &'a Option<$P>) { + let TreeNode {key: ref key, value: ref value, left: ref left, right: ref right, _} = *self; + (key, value, left, right) + } + + fn destructure_mut<'a>(&'a mut self) -> (&'a K, &'a mut V, &'a mut Option<$P>, &'a mut Option<$P>) { + let TreeNode {key: ref key, value: ref mut value, left: ref mut left, right: ref mut right, _} = *self; + (key, value, left, right) + } + } + + impl TreeNode { + /// Creates a new tree node. + #[inline] + pub fn new(key: K, value: V) -> TreeNode { + TreeNode{key: key, value: value, left: None, right: None, level: 1} + } + } + + #[allow(missing_doc)] + trait TreeDir + { + fn new() -> Self; + + fn is_right(&self) -> bool; + fn is_left(&self) -> bool; + } + + struct TreeLeft; + + impl TreeDir for TreeLeft { + fn new() -> TreeLeft {TreeLeft} + + fn is_right(&self) -> bool {false} + fn is_left(&self) -> bool {true} + } + + struct TreeRight; + + impl TreeDir for TreeRight { + fn new() -> TreeRight {TreeRight} + + fn is_right(&self) -> bool {true} + fn is_left(&self) -> bool {false} + } + + // Remove left horizontal link by rotating right + fn skew(mut node: $P) ->$P { + if node.get().left.as_ref().map_default(false, + |x| x.get().level == node.get().level) { + let mut left: $P; + { + let mut_left = { + let mut_node = node.cow(); + left = mut_node.left.take_unwrap(); + let mut_left = left.cow(); + swap(&mut mut_node.left, &mut mut_left.right); // left.right now None + mut_left + }; + mut_left.right = Some(node); + } + left + } else { + node + } + } + + // Remove dual horizontal link by rotating left and increasing level of + // the parent + fn split(mut node: $P) -> $P { + if node.get().right.as_ref().map_default(false, + |x| x.get().right.as_ref().map_default(false, + |y| y.get().level == node.get().level)) { + let mut right: $P; + { + let mut_right = { + let mut_node = node.cow(); + right = mut_node.right.take_unwrap(); + let mut_right = right.cow(); + mut_right.level += 1; + swap(&mut mut_node.right, &mut mut_right.left); // right.left now None + mut_right + }; + mut_right.left = Some(node); + } + right + } else { + node + } + } + + fn rebalance( + node_opt: &mut Option<$P> /* always Some in input and output */) { + let (level, left_level, right_level) = { + let ref_node = node_opt.get_ref().get(); + (ref_node.level, + ref_node.left.as_ref().map_default(0, |x| x.get().level), + ref_node.right.as_ref().map_default(0, |x| x.get().level)) + }; + + // re-balance, if necessary + if left_level < level - 1 || right_level < level - 1 { + let mut node = node_opt.take_unwrap(); + { + let mut_node = node.cow(); + mut_node.level -= 1; + + if right_level > mut_node.level { + for x in mut_node.right.mut_iter() { x.cow().level = mut_node.level } + } + } + + node = skew(node); + + node.cow().right.mutate(|mut right| { + right = skew(right); + right.cow().right.mutate(skew); + right + }); + + node = split(node); + node.cow().right.mutate(split); + *node_opt = Some(node); + } + } + + fn iterate(init: A, f: &fn(A) -> Either) -> B { + let mut accum = init; + loop { + match f(accum) { + Left(x) => { accum = x; } + Right(y) => { return y; } + } + } } - } - } -} -impl<'self, T: TotalOrd> Iterator<&'self T> for Intersection<'self, T> { - fn next(&mut self) -> Option<&'self 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(); } + fn find_mut<'r, K: TotalOrd + $Clone, V: $Clone>( + node: &'r mut Option<$P>, key: &K) -> Option<&'r mut V> { + iterate(node, |node| { + match *node { + Some(ref mut x) => { + match x.try_get_mut() { + Left(x) => { + match find_path(x, key) { + Some(path) => Right(Some(&mut follow_path_mut_inner(x, path).cow().value)), + None => Right(None) + } + }, + Right(mut_x) => { + match key.cmp(&mut_x.key) { + Less => Left(&mut mut_x.left), + Greater => Left(&mut mut_x.right), + Equal => Right(Some(&mut mut_x.value)), + } + } + } + } + None => Right(None) + } + }) } - } - } -} -impl<'self, T: TotalOrd> Iterator<&'self T> for Union<'self, T> { - fn next(&mut self) -> Option<&'self 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(), + fn follow_path<'r, K: TotalOrd + $Clone, V: $Clone>( + node: &'r Option<$P>, path: TreePath) -> &'r Option<$P> { + path.iter().fold(node, |node, dir| { + if(!dir) { + &node.get_ref().get().left + } else { + &node.get_ref().get().right + } + }) } - } - } -} + fn follow_path_mut<'r, K: TotalOrd + $Clone, V: $Clone>( + node: &'r mut Option<$P>, path: TreePath) -> &'r mut Option<$P> { + path.iter().fold(node, |node, dir| { + if(!dir) { + &mut node.get_mut_ref().cow().left + } else { + &mut node.get_mut_ref().cow().right + } + }) + } -// 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)] -struct TreeNode { - key: K, - value: V, - left: Option<~TreeNode>, - right: Option<~TreeNode>, - level: uint -} + fn follow_path_mut_inner<'r, K: TotalOrd + $Clone, V: $Clone>( + node: &'r mut $P, path: TreePath) -> &'r mut $P { + path.iter().fold(node, |node, dir| { + if(!dir) { + node.cow().left.get_mut_ref() + } else { + node.cow().right.get_mut_ref() + } + }) + } -impl TreeNode { - /// Creates a new tree node. - #[inline] - pub fn new(key: K, value: V) -> TreeNode { - TreeNode{key: key, value: value, left: None, right: None, level: 1} - } -} + fn find_path<'r, K: TotalOrd, V>( + mut node: &'r $P, key: &K) -> Option { + let mut path = TreePath::new(); + loop { + let r = node.get(); + let next = match key.cmp(&r.key) { + Less => {path.push(false); &r.left}, + Greater => {path.push(true); &r.right}, + Equal => return Some(path) + }; -fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, - f: &fn(&'r K, &'r mut V) -> bool) - -> bool { - match *node { - Some(~TreeNode{key: ref key, value: ref mut value, left: ref mut left, - right: ref mut right, _}) => { - if !mutate_values(left, |k,v| f(k,v)) { return false } - if !f(key, value) { return false } - if !mutate_values(right, |k,v| f(k,v)) { return false } - } - None => return false - } - true -} + node = match *next { + Some(ref r) => r, + None => return None + } + } + } -// Remove left horizontal link by rotating right -fn skew(node: &mut ~TreeNode) { - if node.left.as_ref().map_default(false, |x| x.level == node.level) { - let mut save = node.left.take_unwrap(); - swap(&mut node.left, &mut save.right); // save.right now None - swap(node, &mut save); - node.right = Some(save); - } -} + fn insert( + node_opt: &mut Option<$P>, key: K, value: V) -> Option { + match node_opt.take() { + Some(node_) => { + let mut node = node_; + let (node, old) = match key.cmp(&node.get().key) { + Less => { + let old = insert(&mut node.cow().left, key, value); + (split(skew(node)), old) + } + Greater => { + let old = insert(&mut node.cow().right, key, value); + (split(skew(node)), old) + } + Equal => { + let old = { + let mut_node = node.cow(); + mut_node.key = key; + Some(replace(&mut mut_node.value, value)) + }; + (node, old) + } + }; + *node_opt = Some(node); + old + } + None => { + *node_opt = Some($new(TreeNode::new(key, value))); + None + } + } + } -// Remove dual horizontal link by rotating left and increasing level of -// the parent -fn split(node: &mut ~TreeNode) { - if node.right.as_ref().map_default(false, - |x| x.right.as_ref().map_default(false, |y| y.level == node.level)) { - let mut save = node.right.take_unwrap(); - swap(&mut node.right, &mut save.left); // save.left now None - save.level += 1; - swap(node, &mut save); - node.left = Some(save); - } -} + fn remove(node_opt: &mut Option<$P>, + key: &K) -> Option { + enum RemoveResult { + Shared, + ThisNode, + Removed(V) + } -fn find_mut<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, - key: &K) - -> Option<&'r mut V> { - match *node { - Some(ref mut x) => { - match key.cmp(&x.key) { - Less => find_mut(&mut x.left, key), - Greater => find_mut(&mut x.right, key), - Equal => Some(&mut x.value), - } - } - None => None - } -} + let res = match *node_opt { + None => return None, + Some(ref mut node) => { + match node.try_get_mut() { + Left(_) => Shared, + Right(mut_node) => { + match key.cmp(&mut_node.key) { + Less => Removed(remove(&mut mut_node.left, key)), + Greater => Removed(remove(&mut mut_node.right, key)), + Equal => ThisNode + } + } + } + } + }; -fn insert(node: &mut Option<~TreeNode>, - key: K, value: V) -> Option { - match *node { - Some(ref mut save) => { - match key.cmp(&save.key) { - Less => { - let inserted = insert(&mut save.left, key, value); - skew(save); - split(save); - inserted - } - Greater => { - let inserted = insert(&mut save.right, key, value); - skew(save); - split(save); - inserted - } - Equal => { - save.key = key; - Some(replace(&mut save.value, value)) - } - } - } - None => { - *node = Some(~TreeNode::new(key, value)); - None - } - } -} + let value_opt = match res { + Shared => { + match find_path(node_opt.get_ref(), key) { + Some(path) => return Some(remove_path(node_opt, path.iter())), + None => return None + } + }, + ThisNode => return Some(remove_node(node_opt)), + Removed(value_opt) => value_opt + }; -fn remove(node: &mut Option<~TreeNode>, - key: &K) -> Option { - fn heir_swap(node: &mut ~TreeNode, - child: &mut Option<~TreeNode>) { - // *could* be done without recursion, but it won't borrow check - for x in child.mut_iter() { - if x.right.is_some() { - heir_swap(node, &mut x.right); - } else { - swap(&mut node.key, &mut x.key); - swap(&mut node.value, &mut x.value); + rebalance(node_opt); + value_opt } - } - } - match *node { - None => { - return None; // bottom of tree - } - Some(ref mut save) => { - let (ret, rebalance) = match key.cmp(&save.key) { - Less => (remove(&mut save.left, key), true), - Greater => (remove(&mut save.right, key), true), - Equal => { - if save.left.is_some() { - if save.right.is_some() { - let mut left = save.left.take_unwrap(); - if left.right.is_some() { - heir_swap(save, &mut left.right); + fn remove_node( + node_opt: &mut Option<$P> /* always Some in input */) -> V { + fn swap_max(node: &mut $P, + mut_target: &mut TreeNode) { + let mut_node = node.cow(); + if mut_node.right.is_some() { + swap_max(mut_node.right.as_mut().unwrap(), mut_target) } else { - swap(&mut save.key, &mut left.key); - swap(&mut save.value, &mut left.value); + swap(&mut mut_node.key, &mut mut_target.key); + swap(&mut mut_node.value, &mut mut_target.value); } - save.left = Some(left); - (remove(&mut save.left, key), true) - } else { - let new = save.left.take_unwrap(); - let ~TreeNode{value, _} = replace(save, new); - *save = save.left.take_unwrap(); - (Some(value), true) } - } else if save.right.is_some() { - let new = save.right.take_unwrap(); - let ~TreeNode{value, _} = replace(save, new); - (Some(value), true) - } else { - (None, false) + + let value = if node_opt.get_ref().get().left.is_some() { + if node_opt.get_ref().get().right.is_some() { + let mut_node = node_opt.get_mut_ref().cow(); + let mut left = mut_node.left.take(); + swap_max(left.as_mut().unwrap(), mut_node); + let value = remove_max(&mut left); + mut_node.left = left; + value + } else { + let TreeNode {value: value, left: left, _} = + node_opt.take_unwrap().value(); + *node_opt = left; + value + } + } else if node_opt.get_ref().get().right.is_some() { + let TreeNode {value: value, right: right, _} = + node_opt.take_unwrap().value(); + *node_opt = right; + value + } else { + let TreeNode {value: value, _} = node_opt.take_unwrap().value(); + *node_opt = None; + return value + }; + + rebalance(node_opt); + value } - } - }; - if rebalance { - let left_level = save.left.as_ref().map_default(0, |x| x.level); - let right_level = save.right.as_ref().map_default(0, |x| x.level); + fn remove_max( + node_opt: &mut Option<$P> /* always Some in input */) -> V { + let value = if node_opt.get_mut_ref().get().right.is_some() { + remove_max(&mut node_opt.get_mut_ref().cow().right) + } else { + return remove_node(node_opt) + }; + + rebalance(node_opt); + value + } - // re-balance, if necessary - if left_level < save.level - 1 || right_level < save.level - 1 { - save.level -= 1; + fn remove_path( + node_opt: &mut Option<$P> /* always Some in input */, + mut path_iter: TreePathIterator) -> V { + let value = match path_iter.next() { + None => return remove_node(node_opt), + Some(false) => remove_path(&mut node_opt.get_mut_ref().cow().left, path_iter), + Some(true) => remove_path(&mut node_opt.get_mut_ref().cow().right, path_iter) + }; + rebalance(node_opt); + value + } - if right_level > save.level { - for x in save.right.mut_iter() { x.level = save.level } + impl + FromIterator<(K, V)> for TreeMap { + fn from_iterator>(iter: &mut T) -> TreeMap { + let mut map = TreeMap::new(); + map.extend(iter); + map } + } - skew(save); + impl + Extendable<(K, V)> for TreeMap { + #[inline] + fn extend>(&mut self, iter: &mut T) { + for (k, v) in *iter { + self.insert(k, v); + } + } + } - for right in save.right.mut_iter() { - skew(right); - for x in right.right.mut_iter() { skew(x) } + impl FromIterator for TreeSet { + fn from_iterator>(iter: &mut Iter) -> TreeSet { + let mut set = TreeSet::new(); + set.extend(iter); + set } + } - split(save); - for x in save.right.mut_iter() { split(x) } + impl Extendable for TreeSet { + #[inline] + fn extend>(&mut self, iter: &mut Iter) { + for elem in *iter { + self.insert(elem); + } + } } - return ret; - } - } - } - return match node.take() { - Some(~TreeNode{value, _}) => Some(value), None => fail2!() - }; -} + #[cfg(test)] + mod test_TreeMap { -impl FromIterator<(K, V)> for TreeMap { - fn from_iterator>(iter: &mut T) -> TreeMap { - let mut map = TreeMap::new(); - map.extend(iter); - map - } -} + use super::*; -impl Extendable<(K, V)> for TreeMap { - #[inline] - fn extend>(&mut self, iter: &mut T) { - for (k, v) in *iter { - self.insert(k, v); - } - } -} + use std::rand::Rng; + use std::rand; -impl FromIterator for TreeSet { - fn from_iterator>(iter: &mut Iter) -> TreeSet { - let mut set = TreeSet::new(); - set.extend(iter); - set - } -} + #[test] + fn find_empty() { + let m: TreeMap = TreeMap::new(); + assert!(m.find(&5) == None); + } -impl Extendable for TreeSet { - #[inline] - fn extend>(&mut self, iter: &mut Iter) { - for elem in *iter { - self.insert(elem); - } - } -} + #[test] + fn find_not_found() { + let mut m = TreeMap::new(); + assert!(m.insert(1, 2)); + assert!(m.insert(5, 3)); + assert!(m.insert(9, 3)); + assert_eq!(m.find(&2), None); + } -#[cfg(test)] -mod test_treemap { + #[test] + fn test_find_mut() { + let mut m = TreeMap::new(); + assert!(m.insert(1, 12)); + assert!(m.insert(2, 8)); + assert!(m.insert(5, 14)); + let new = 100; + match m.find_mut(&5) { + None => fail2!(), Some(x) => *x = new + } + assert_eq!(m.find(&5), Some(&new)); + } - use super::*; + #[test] + fn insert_replace() { + let mut m = TreeMap::new(); + assert!(m.insert(5, 2)); + assert!(m.insert(2, 9)); + assert!(!m.insert(2, 11)); + assert_eq!(m.find(&2).unwrap(), &11); + } - use std::rand::Rng; - use std::rand; + #[test] + fn test_clear() { + let mut m = TreeMap::new(); + m.clear(); + assert!(m.insert(5, 11)); + assert!(m.insert(12, -3)); + assert!(m.insert(19, 2)); + m.clear(); + assert!(m.find(&5).is_none()); + assert!(m.find(&12).is_none()); + assert!(m.find(&19).is_none()); + assert!(m.is_empty()); + } - #[test] - fn find_empty() { - let m: TreeMap = TreeMap::new(); - assert!(m.find(&5) == None); - } + #[test] + fn u8_map() { + let mut m = TreeMap::new(); - #[test] - fn find_not_found() { - let mut m = TreeMap::new(); - assert!(m.insert(1, 2)); - assert!(m.insert(5, 3)); - assert!(m.insert(9, 3)); - assert_eq!(m.find(&2), None); - } + let k1 = "foo".as_bytes(); + let k2 = "bar".as_bytes(); + let v1 = "baz".as_bytes(); + let v2 = "foobar".as_bytes(); - #[test] - fn test_find_mut() { - let mut m = TreeMap::new(); - assert!(m.insert(1, 12)); - assert!(m.insert(2, 8)); - assert!(m.insert(5, 14)); - let new = 100; - match m.find_mut(&5) { - None => fail2!(), Some(x) => *x = new - } - assert_eq!(m.find(&5), Some(&new)); - } + m.insert(k1.clone(), v1.clone()); + m.insert(k2.clone(), v2.clone()); - #[test] - fn insert_replace() { - let mut m = TreeMap::new(); - assert!(m.insert(5, 2)); - assert!(m.insert(2, 9)); - assert!(!m.insert(2, 11)); - assert_eq!(m.find(&2).unwrap(), &11); - } + assert_eq!(m.find(&k2), Some(&v2)); + assert_eq!(m.find(&k1), Some(&v1)); + } - #[test] - fn test_clear() { - let mut m = TreeMap::new(); - m.clear(); - assert!(m.insert(5, 11)); - assert!(m.insert(12, -3)); - assert!(m.insert(19, 2)); - m.clear(); - assert!(m.find(&5).is_none()); - assert!(m.find(&12).is_none()); - assert!(m.find(&19).is_none()); - assert!(m.is_empty()); - } + fn check_equal(ctrl: &[(K, V)], + map: &TreeMap) { + assert_eq!(ctrl.is_empty(), map.is_empty()); + for x in ctrl.iter() { + let &(ref k, ref v) = x; + assert!(map.find(k).unwrap() == v) + } + for (map_k, map_v) in map.iter() { + let mut found = false; + for x in ctrl.iter() { + let &(ref ctrl_k, ref ctrl_v) = x; + if *map_k == *ctrl_k { + assert!(*map_v == *ctrl_v); + found = true; + break; + } + } + assert!(found); + } + } - #[test] - fn u8_map() { - let mut m = TreeMap::new(); + fn check_left( + node: &Option<$P>, parent: &$P) { + match *node { + Some(ref r) => { + assert_eq!(r.key.cmp(&parent.key), Less); + assert!(r.level == parent.level - 1); // left is black + check_left(&r.left, r); + check_right(&r.right, r, false); + } + None => assert!(parent.level == 1) // parent is leaf + } + } - let k1 = "foo".as_bytes(); - let k2 = "bar".as_bytes(); - let v1 = "baz".as_bytes(); - let v2 = "foobar".as_bytes(); + fn check_right( + node: &Option<$P>, parent: &$P, parent_red: bool) { + match *node { + Some(ref r) => { + assert_eq!(r.key.cmp(&parent.key), Greater); + let red = r.level == parent.level; + if parent_red { assert!(!red) } // no dual horizontal links + // Right red or black + assert!(red || r.level == parent.level - 1); + check_left(&r.left, r); + check_right(&r.right, r, red); + } + None => assert!(parent.level == 1) // parent is leaf + } + } - m.insert(k1.clone(), v1.clone()); - m.insert(k2.clone(), v2.clone()); + fn check_structure(map: &TreeMap) { + match map.root { + Some(ref r) => { + check_left(&r.left, r); + check_right(&r.right, r, false); + } + None => () + } + } - assert_eq!(m.find(&k2), Some(&v2)); - assert_eq!(m.find(&k1), Some(&v1)); - } + #[test] + fn test_rand_int() { + let mut map: TreeMap = TreeMap::new(); + let mut ctrl = ~[]; - fn check_equal(ctrl: &[(K, V)], - map: &TreeMap) { - assert_eq!(ctrl.is_empty(), map.is_empty()); - for x in ctrl.iter() { - let &(ref k, ref v) = x; - assert!(map.find(k).unwrap() == v) - } - for (map_k, map_v) in map.iter() { - let mut found = false; - for x in ctrl.iter() { - let &(ref ctrl_k, ref ctrl_v) = x; - if *map_k == *ctrl_k { - assert!(*map_v == *ctrl_v); - found = true; - break; + check_equal(ctrl, &map); + assert!(map.find(&5).is_none()); + + let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(&[42]); + + do 3.times { + do 90.times { + let k = rng.gen(); + let v = rng.gen(); + if !ctrl.iter().any(|x| x == &(k, v)) { + assert!(map.insert(k, v)); + ctrl.push((k, v)); + check_structure(&map); + check_equal(ctrl, &map); + } + } + + do 30.times { + let r = rng.gen_integer_range(0, ctrl.len()); + let (key, _) = ctrl.remove(r); + assert!(map.remove(&key)); + check_structure(&map); + check_equal(ctrl, &map); + } + } } - } - assert!(found); - } - } - fn check_left(node: &Option<~TreeNode>, - parent: &~TreeNode) { - match *node { - Some(ref r) => { - assert_eq!(r.key.cmp(&parent.key), Less); - assert!(r.level == parent.level - 1); // left is black - check_left(&r.left, r); - check_right(&r.right, r, false); - } - None => assert!(parent.level == 1) // parent is leaf - } - } + #[test] + fn test_len() { + let mut m = TreeMap::new(); + assert!(m.insert(3, 6)); + assert_eq!(m.len(), 1); + assert!(m.insert(0, 0)); + assert_eq!(m.len(), 2); + assert!(m.insert(4, 8)); + assert_eq!(m.len(), 3); + assert!(m.remove(&3)); + assert_eq!(m.len(), 2); + assert!(!m.remove(&5)); + assert_eq!(m.len(), 2); + assert!(m.insert(2, 4)); + assert_eq!(m.len(), 3); + assert!(m.insert(1, 2)); + assert_eq!(m.len(), 4); + } - fn check_right(node: &Option<~TreeNode>, - parent: &~TreeNode, - parent_red: bool) { - match *node { - Some(ref r) => { - assert_eq!(r.key.cmp(&parent.key), Greater); - let red = r.level == parent.level; - if parent_red { assert!(!red) } // no dual horizontal links - // Right red or black - assert!(red || r.level == parent.level - 1); - check_left(&r.left, r); - check_right(&r.right, r, red); - } - None => assert!(parent.level == 1) // parent is leaf - } - } + #[test] + fn test_iterator() { + let mut m = TreeMap::new(); + + assert!(m.insert(3, 6)); + assert!(m.insert(0, 0)); + assert!(m.insert(4, 8)); + assert!(m.insert(2, 4)); + assert!(m.insert(1, 2)); + + let mut n = 0; + for (k, v) in m.iter() { + assert_eq!(*k, n); + assert_eq!(*v, n * 2); + n += 1; + } + assert_eq!(n, 5); + } - fn check_structure(map: &TreeMap) { - match map.root { - Some(ref r) => { - check_left(&r.left, r); - check_right(&r.right, r, false); - } - None => () - } - } + #[test] + fn test_interval_iteration() { + let mut m = TreeMap::new(); + for i in range(1, 100) { + assert!(m.insert(i * 2, i * 4)); + } - #[test] - fn test_rand_int() { - let mut map: TreeMap = TreeMap::new(); - let mut ctrl = ~[]; - - check_equal(ctrl, &map); - assert!(map.find(&5).is_none()); - - let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(&[42]); - - do 3.times { - do 90.times { - let k = rng.gen(); - let v = rng.gen(); - if !ctrl.iter().any(|x| x == &(k, v)) { - assert!(map.insert(k, v)); - ctrl.push((k, v)); - check_structure(&map); - check_equal(ctrl, &map); + for i in range(1, 198) { + let mut lb_it = m.lower_bound_iter(&i); + let (&k, &v) = lb_it.next().unwrap(); + let lb = i + i % 2; + assert_eq!(lb, k); + assert_eq!(lb * 2, v); + + let mut ub_it = m.upper_bound_iter(&i); + let (&k, &v) = ub_it.next().unwrap(); + let ub = i + 2 - i % 2; + assert_eq!(ub, k); + assert_eq!(ub * 2, v); + } + let mut end_it = m.lower_bound_iter(&199); + assert_eq!(end_it.next(), None); } - } - do 30.times { - let r = rng.gen_integer_range(0, ctrl.len()); - let (key, _) = ctrl.remove(r); - assert!(map.remove(&key)); - check_structure(&map); - check_equal(ctrl, &map); - } - } - } + #[test] + fn test_rev_iter() { + let mut m = TreeMap::new(); + + assert!(m.insert(3, 6)); + assert!(m.insert(0, 0)); + assert!(m.insert(4, 8)); + assert!(m.insert(2, 4)); + assert!(m.insert(1, 2)); + + let mut n = 4; + for (k, v) in m.rev_iter() { + assert_eq!(*k, n); + assert_eq!(*v, n * 2); + n -= 1; + } + } - #[test] - fn test_len() { - let mut m = TreeMap::new(); - assert!(m.insert(3, 6)); - assert_eq!(m.len(), 1); - assert!(m.insert(0, 0)); - assert_eq!(m.len(), 2); - assert!(m.insert(4, 8)); - assert_eq!(m.len(), 3); - assert!(m.remove(&3)); - assert_eq!(m.len(), 2); - assert!(!m.remove(&5)); - assert_eq!(m.len(), 2); - assert!(m.insert(2, 4)); - assert_eq!(m.len(), 3); - assert!(m.insert(1, 2)); - assert_eq!(m.len(), 4); - } + #[test] + fn test_eq() { + let mut a = TreeMap::new(); + let mut b = TreeMap::new(); + + assert!(a == b); + assert!(a.insert(0, 5)); + assert!(a != b); + assert!(b.insert(0, 4)); + assert!(a != b); + assert!(a.insert(5, 19)); + assert!(a != b); + assert!(!b.insert(0, 5)); + assert!(a != b); + assert!(b.insert(5, 19)); + assert!(a == b); + } - #[test] - fn test_iterator() { - let mut m = TreeMap::new(); - - assert!(m.insert(3, 6)); - assert!(m.insert(0, 0)); - assert!(m.insert(4, 8)); - assert!(m.insert(2, 4)); - assert!(m.insert(1, 2)); - - let mut n = 0; - for (k, v) in m.iter() { - assert_eq!(*k, n); - assert_eq!(*v, n * 2); - n += 1; - } - assert_eq!(n, 5); - } + #[test] + fn test_lt() { + let mut a = TreeMap::new(); + let mut b = TreeMap::new(); + + assert!(!(a < b) && !(b < a)); + assert!(b.insert(0, 5)); + assert!(a < b); + assert!(a.insert(0, 7)); + assert!(!(a < b) && b < a); + assert!(b.insert(-2, 0)); + assert!(b < a); + assert!(a.insert(-5, 2)); + assert!(a < b); + assert!(a.insert(6, 2)); + assert!(a < b && !(b < a)); + } - #[test] - fn test_interval_iteration() { - let mut m = TreeMap::new(); - for i in range(1, 100) { - assert!(m.insert(i * 2, i * 4)); - } + #[test] + fn test_ord() { + let mut a = TreeMap::new(); + let mut b = TreeMap::new(); + + assert!(a <= b && a >= b); + assert!(a.insert(1, 1)); + assert!(a > b && a >= b); + assert!(b < a && b <= a); + assert!(b.insert(2, 2)); + assert!(b > a && b >= a); + assert!(a < b && a <= b); + } - for i in range(1, 198) { - let mut lb_it = m.lower_bound_iter(&i); - let (&k, &v) = lb_it.next().unwrap(); - let lb = i + i % 2; - assert_eq!(lb, k); - assert_eq!(lb * 2, v); - - let mut ub_it = m.upper_bound_iter(&i); - let (&k, &v) = ub_it.next().unwrap(); - let ub = i + 2 - i % 2; - assert_eq!(ub, k); - assert_eq!(ub * 2, v); - } - let mut end_it = m.lower_bound_iter(&199); - assert_eq!(end_it.next(), None); - } + #[test] + fn test_lazy_iterator() { + let mut m = TreeMap::new(); + let (x1, y1) = (2, 5); + let (x2, y2) = (9, 12); + let (x3, y3) = (20, -3); + let (x4, y4) = (29, 5); + let (x5, y5) = (103, 3); + + assert!(m.insert(x1, y1)); + assert!(m.insert(x2, y2)); + assert!(m.insert(x3, y3)); + assert!(m.insert(x4, y4)); + assert!(m.insert(x5, y5)); + + let m = m; + let mut a = m.iter(); + + assert_eq!(a.next().unwrap(), (&x1, &y1)); + assert_eq!(a.next().unwrap(), (&x2, &y2)); + assert_eq!(a.next().unwrap(), (&x3, &y3)); + assert_eq!(a.next().unwrap(), (&x4, &y4)); + assert_eq!(a.next().unwrap(), (&x5, &y5)); + + assert!(a.next().is_none()); + + let mut b = m.iter(); + + let expected = [(&x1, &y1), (&x2, &y2), (&x3, &y3), (&x4, &y4), + (&x5, &y5)]; + let mut i = 0; + + for x in b { + assert_eq!(expected[i], x); + i += 1; + + if i == 2 { + break + } + } - #[test] - fn test_rev_iter() { - let mut m = TreeMap::new(); - - assert!(m.insert(3, 6)); - assert!(m.insert(0, 0)); - assert!(m.insert(4, 8)); - assert!(m.insert(2, 4)); - assert!(m.insert(1, 2)); - - let mut n = 4; - for (k, v) in m.rev_iter() { - assert_eq!(*k, n); - assert_eq!(*v, n * 2); - n -= 1; - } - } + for x in b { + assert_eq!(expected[i], x); + i += 1; + } + } - #[test] - fn test_eq() { - let mut a = TreeMap::new(); - let mut b = TreeMap::new(); - - assert!(a == b); - assert!(a.insert(0, 5)); - assert!(a != b); - assert!(b.insert(0, 4)); - assert!(a != b); - assert!(a.insert(5, 19)); - assert!(a != b); - assert!(!b.insert(0, 5)); - assert!(a != b); - assert!(b.insert(5, 19)); - assert!(a == b); - } + #[test] + fn test_from_iter() { + let xs = ~[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; - #[test] - fn test_lt() { - let mut a = TreeMap::new(); - let mut b = TreeMap::new(); - - assert!(!(a < b) && !(b < a)); - assert!(b.insert(0, 5)); - assert!(a < b); - assert!(a.insert(0, 7)); - assert!(!(a < b) && b < a); - assert!(b.insert(-2, 0)); - assert!(b < a); - assert!(a.insert(-5, 2)); - assert!(a < b); - assert!(a.insert(6, 2)); - assert!(a < b && !(b < a)); - } + let map: TreeMap = xs.iter().map(|&x| x).collect(); - #[test] - fn test_ord() { - let mut a = TreeMap::new(); - let mut b = TreeMap::new(); - - assert!(a <= b && a >= b); - assert!(a.insert(1, 1)); - assert!(a > b && a >= b); - assert!(b < a && b <= a); - assert!(b.insert(2, 2)); - assert!(b > a && b >= a); - assert!(a < b && a <= b); - } + for &(k, v) in xs.iter() { + assert_eq!(map.find(&k), Some(&v)); + } + } - #[test] - fn test_lazy_iterator() { - let mut m = TreeMap::new(); - let (x1, y1) = (2, 5); - let (x2, y2) = (9, 12); - let (x3, y3) = (20, -3); - let (x4, y4) = (29, 5); - let (x5, y5) = (103, 3); + } - assert!(m.insert(x1, y1)); - assert!(m.insert(x2, y2)); - assert!(m.insert(x3, y3)); - assert!(m.insert(x4, y4)); - assert!(m.insert(x5, y5)); + #[cfg(test)] + mod bench { - let m = m; - let mut a = m.iter(); + use super::*; + use test::BenchHarness; + use container::bench::*; - assert_eq!(a.next().unwrap(), (&x1, &y1)); - assert_eq!(a.next().unwrap(), (&x2, &y2)); - assert_eq!(a.next().unwrap(), (&x3, &y3)); - assert_eq!(a.next().unwrap(), (&x4, &y4)); - assert_eq!(a.next().unwrap(), (&x5, &y5)); + // Find seq + #[bench] + pub fn insert_rand_100(bh: &mut BenchHarness) { + let mut m : TreeMap = TreeMap::new(); + insert_rand_n(100, &mut m, bh); + } - assert!(a.next().is_none()); + #[bench] + pub fn insert_rand_10_000(bh: &mut BenchHarness) { + let mut m : TreeMap = TreeMap::new(); + insert_rand_n(10_000, &mut m, bh); + } - let mut b = m.iter(); + // Insert seq + #[bench] + pub fn insert_seq_100(bh: &mut BenchHarness) { + let mut m : TreeMap = TreeMap::new(); + insert_seq_n(100, &mut m, bh); + } - let expected = [(&x1, &y1), (&x2, &y2), (&x3, &y3), (&x4, &y4), - (&x5, &y5)]; - let mut i = 0; + #[bench] + pub fn insert_seq_10_000(bh: &mut BenchHarness) { + let mut m : TreeMap = TreeMap::new(); + insert_seq_n(10_000, &mut m, bh); + } - for x in b { - assert_eq!(expected[i], x); - i += 1; + // Find rand + #[bench] + pub fn find_rand_100(bh: &mut BenchHarness) { + let mut m : TreeMap = TreeMap::new(); + find_rand_n(100, &mut m, bh); + } - if i == 2 { - break - } - } + #[bench] + pub fn find_rand_10_000(bh: &mut BenchHarness) { + let mut m : TreeMap = TreeMap::new(); + find_rand_n(10_000, &mut m, bh); + } - for x in b { - assert_eq!(expected[i], x); - i += 1; - } - } + // Find seq + #[bench] + pub fn find_seq_100(bh: &mut BenchHarness) { + let mut m : TreeMap = TreeMap::new(); + find_seq_n(100, &mut m, bh); + } - #[test] - fn test_from_iter() { - let xs = ~[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + #[bench] + pub fn find_seq_10_000(bh: &mut BenchHarness) { + let mut m : TreeMap = TreeMap::new(); + find_seq_n(10_000, &mut m, bh); + } + } - let map: TreeMap = xs.iter().map(|&x| x).collect(); + #[cfg(test)] + mod test_set { + + use super::*; + + #[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()); + } - for &(k, v) in xs.iter() { - assert_eq!(map.find(&k), Some(&v)); - } - } + #[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)); + } -#[cfg(test)] -mod bench { + #[test] + fn test_iterator() { + let mut m = TreeSet::new(); - use super::*; - use test::BenchHarness; - use container::bench::*; - - // Find seq - #[bench] - pub fn insert_rand_100(bh: &mut BenchHarness) { - let mut m : TreeMap = TreeMap::new(); - insert_rand_n(100, &mut m, bh); - } + assert!(m.insert(3)); + assert!(m.insert(0)); + assert!(m.insert(4)); + assert!(m.insert(2)); + assert!(m.insert(1)); - #[bench] - pub fn insert_rand_10_000(bh: &mut BenchHarness) { - let mut m : TreeMap = TreeMap::new(); - insert_rand_n(10_000, &mut m, bh); - } + let mut n = 0; + for x in m.iter() { + assert_eq!(*x, n); + n += 1 + } + } - // Insert seq - #[bench] - pub fn insert_seq_100(bh: &mut BenchHarness) { - let mut m : TreeMap = TreeMap::new(); - insert_seq_n(100, &mut m, bh); - } + #[test] + fn test_rev_iter() { + let mut m = TreeSet::new(); - #[bench] - pub fn insert_seq_10_000(bh: &mut BenchHarness) { - let mut m : TreeMap = TreeMap::new(); - insert_seq_n(10_000, &mut m, bh); - } + assert!(m.insert(3)); + assert!(m.insert(0)); + assert!(m.insert(4)); + assert!(m.insert(2)); + assert!(m.insert(1)); - // Find rand - #[bench] - pub fn find_rand_100(bh: &mut BenchHarness) { - let mut m : TreeMap = TreeMap::new(); - find_rand_n(100, &mut m, bh); - } + let mut n = 4; + for x in m.rev_iter() { + assert_eq!(*x, n); + n -= 1; + } + } - #[bench] - pub fn find_rand_10_000(bh: &mut BenchHarness) { - let mut m : TreeMap = TreeMap::new(); - find_rand_n(10_000, &mut m, bh); - } + fn check(a: &[int], b: &[int], expected: &[int], + f: &fn(&TreeSet, &TreeSet, f: &fn(&int) -> bool) -> bool) { + let mut set_a = TreeSet::new(); + let mut set_b = TreeSet::new(); - // Find seq - #[bench] - pub fn find_seq_100(bh: &mut BenchHarness) { - let mut m : TreeMap = TreeMap::new(); - find_seq_n(100, &mut m, bh); - } + for x in a.iter() { assert!(set_a.insert(*x)) } + for y in b.iter() { assert!(set_b.insert(*y)) } - #[bench] - pub fn find_seq_10_000(bh: &mut BenchHarness) { - let mut m : TreeMap = TreeMap::new(); - find_seq_n(10_000, &mut m, bh); - } -} + let mut i = 0; + do f(&set_a, &set_b) |x| { + assert_eq!(*x, expected[i]); + i += 1; + true + }; + assert_eq!(i, expected.len()); + } -#[cfg(test)] -mod test_set { + #[test] + fn test_intersection() { + fn check_intersection(a: &[int], b: &[int], expected: &[int]) { + check(a, b, expected, |x, y, f| x.intersection(y).advance(f)) + } - use super::*; + 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_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_difference() { + fn check_difference(a: &[int], b: &[int], expected: &[int]) { + check(a, b, expected, |x, y, f| x.difference(y).advance(f)) + } - #[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)); - } + 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_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_symmetric_difference() { + fn check_symmetric_difference(a: &[int], b: &[int], + expected: &[int]) { + check(a, b, expected, |x, y, f| x.symmetric_difference(y).advance(f)) + } - #[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 - } - } + 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_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_union() { + fn check_union(a: &[int], b: &[int], + expected: &[int]) { + check(a, b, expected, |x, y, f| x.union(y).advance(f)) + } - fn check(a: &[int], b: &[int], expected: &[int], - f: &fn(&TreeSet, &TreeSet, f: &fn(&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; - do f(&set_a, &set_b) |x| { - assert_eq!(*x, expected[i]); - i += 1; - true - }; - assert_eq!(i, expected.len()); - } + 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_intersection() { - fn check_intersection(a: &[int], b: &[int], expected: &[int]) { - check(a, b, expected, |x, y, f| x.intersection(y).advance(f)) - } + #[test] + fn test_zip() { + let mut x = TreeSet::new(); + x.insert(5u); + x.insert(12u); + x.insert(11u); - 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]); - } + let mut y = TreeSet::new(); + y.insert("foo"); + y.insert("bar"); - #[test] - fn test_difference() { - fn check_difference(a: &[int], b: &[int], expected: &[int]) { - check(a, b, expected, |x, y, f| x.difference(y).advance(f)) - } + let x = x; + let y = y; + let mut z = x.iter().zip(y.iter()); - 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]); - } + // FIXME: #5801: this needs a type hint to compile... + let result: Option<(&uint, & &'static str)> = z.next(); + assert_eq!(result.unwrap(), (&5u, & &"bar")); - #[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).advance(f)) - } + let result: Option<(&uint, & &'static str)> = z.next(); + assert_eq!(result.unwrap(), (&11u, & &"foo")); - 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]); - } + let result: Option<(&uint, & &'static str)> = z.next(); + assert!(result.is_none()); + } - #[test] - fn test_union() { - fn check_union(a: &[int], b: &[int], - expected: &[int]) { - check(a, b, expected, |x, y, f| x.union(y).advance(f)) - } + #[test] + fn test_swap() { + let mut m = TreeMap::new(); + assert_eq!(m.swap(1, 2), None); + assert_eq!(m.swap(1, 3), Some(2)); + assert_eq!(m.swap(1, 4), Some(3)); + } - 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_pop() { + let mut m = TreeMap::new(); + m.insert(1, 2); + assert_eq!(m.pop(&1), Some(2)); + assert_eq!(m.pop(&1), None); + } - #[test] - fn test_zip() { - let mut x = TreeSet::new(); - x.insert(5u); - x.insert(12u); - x.insert(11u); + #[test] + fn test_from_iter() { + let xs = ~[1, 2, 3, 4, 5, 6, 7, 8, 9]; - let mut y = TreeSet::new(); - y.insert("foo"); - y.insert("bar"); + let set: TreeSet = xs.iter().map(|&x| x).collect(); - let x = x; - let y = y; - let mut z = x.iter().zip(y.iter()); + for x in xs.iter() { + assert!(set.contains(x)); + } + } + } + } + } +} - // FIXME: #5801: this needs a type hint to compile... - let result: Option<(&uint, & &'static str)> = z.next(); - assert_eq!(result.unwrap(), (&5u, & &"bar")); +trait Dummy {} +impl Dummy for T {} - let result: Option<(&uint, & &'static str)> = z.next(); - assert_eq!(result.unwrap(), (&11u, & &"foo")); +treemap!(rc, Rc>, Rc::new, Clone, Freeze + Freeze) +treemap!(arc, Arc>, Arc::new, Clone, Send + Freeze) +treemap!(own, Own>, Own::new, Dummy, Dummy + Dummy) - let result: Option<(&uint, & &'static str)> = z.next(); - assert!(result.is_none()); - } +#[cfg(test)] +mod test_TreePath { + use super::*; #[test] - fn test_swap() { - let mut m = TreeMap::new(); - assert_eq!(m.swap(1, 2), None); - assert_eq!(m.swap(1, 3), Some(2)); - assert_eq!(m.swap(1, 4), Some(3)); + fn test_new_is_empty() { + let p = TreePath::new(); + assert!(p.iter().next().is_none()) } - #[test] - fn test_pop() { - let mut m = TreeMap::new(); - m.insert(1, 2); - assert_eq!(m.pop(&1), Some(2)); - assert_eq!(m.pop(&1), None); + fn test(even: bool, odd: bool, n: uint) { + let p = TreePath::new(); + for i in range(0, n) { + p.push(if (i & 1) == 0 {even} else {odd}) + } + let iter = p.iter(); + for i in range(0, uint::bits * 2 - 2) { + assert!(iter.next() == Some(if (i & 1) == 0 {even} else {odd})) + } + assert!(iter.next().is_none()) } - #[test] - fn test_from_iter() { - let xs = ~[1, 2, 3, 4, 5, 6, 7, 8, 9]; + #[test] fn test_all_zeroes_long() {test(false, false, uint::bits * 2 - 2)} + #[test] fn test_all_ones_long() {test(true, true, uint::bits * 2 - 2)} + #[test] fn test_zero_one_long() { test(false, true, uint::bits * 2 - 2)} - let set: TreeSet = xs.iter().map(|&x| x).collect(); + #[test] fn test_all_zeroes_mid() {test(false, false, uint::bits + 8)} + #[test] fn test_all_ones_mid() {test(true, true, uint::bits + 8)} + #[test] fn test_zero_one_mid() {test(false, true, uint::bits + 8)} - for x in xs.iter() { - assert!(set.contains(x)); - } - } + #[test] fn test_all_zeroes_short() {test(false, false, 8)} + #[test] fn test_all_ones_short() {test(true, true, 8)} + #[test] fn test_zero_one_short() {test(false, true, 8)} } + diff --git a/src/libstd/owned.rs b/src/libstd/owned.rs index 424c4fd6b2f44..dae0ead0de190 100644 --- a/src/libstd/owned.rs +++ b/src/libstd/owned.rs @@ -10,7 +10,9 @@ //! Operations on unique pointer types +#[allow(missing_doc)]; #[cfg(not(test))] use cmp::*; +use either::{Either, Right}; #[cfg(not(test))] impl Eq for ~T { @@ -43,3 +45,25 @@ impl TotalEq for ~T { #[inline] fn equals(&self, other: &~T) -> bool { (**self).equals(*other) } } + +#[deriving(Clone)] +pub struct Own { + priv p: ~T +} + +impl Own { + pub fn new(v: T) -> Own {Own {p: ~v}} + + pub fn get<'r>(&'r self) -> &'r T {&*self.p} + + pub fn get_mut<'r>(&'r mut self) -> &'r mut T {&mut *self.p} + pub fn unwrap(self) -> T {*self.p} + + pub fn try_get_mut<'r>(&'r mut self) -> Either<&'r mut Own, &'r mut T> { + Right(&mut *self.p) + } + pub fn try_unwrap<'r>(self) -> Either, T> {Right(*self.p)} + + pub fn cow<'r>(&'r mut self) -> &'r mut T {&mut *self.p} + pub fn value<'r>(self) -> T {*self.p} +} diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs index 41e834cf37c39..d224f631f34b6 100644 --- a/src/libstd/rc.rs +++ b/src/libstd/rc.rs @@ -21,10 +21,12 @@ reference is a unique handle and the type is marked as non-`Freeze`. */ use ptr::RawPtr; -use unstable::intrinsics::transmute; +use unstable::intrinsics::{forget, transmute}; +use cast; use ops::Drop; use kinds::{Freeze, Send}; use clone::{Clone, DeepClone}; +use either::{Either, Left, Right}; struct RcBox { value: T, @@ -61,9 +63,71 @@ impl Rc { /// Borrow the value contained in the reference-counted box #[inline] - pub fn borrow<'r>(&'r self) -> &'r T { + pub fn get<'r>(&'r self) -> &'r T { unsafe { &(*self.ptr).value } } + + /// Return a mutable reference that only alters this Rc if possible, + /// or return self + pub fn try_get_mut<'r>(&'r mut self) -> Either<&'r mut Rc, &'r mut T> { + unsafe { + if (*self.ptr).count > 1 { + Left(self) + } else { + Right(cast::copy_mut_lifetime(self, &mut (*self.ptr).value)) + } + } + } + + /// Return the contents while altering only this Rc if possible, + /// or return self + pub fn try_unwrap(self) -> Either, T> { + unsafe { + if (*self.ptr).count > 1 { + Left(self) + } else { + let box: ~RcBox = transmute(self.ptr); + forget(self); + Right(box.value) + } + } + } +} + +impl Rc { + /// Clones the content if there is more than one reference, and returns a + /// mutable reference to the data once this is the only refence + #[inline] + pub fn cow<'r>(&'r mut self) -> &'r mut T { + unsafe { + if (*self.ptr).count > 1 { + self.cow_clone() + } else { + cast::copy_mut_lifetime(self, &mut (*self.ptr).value) + } + } + } + + #[inline(never)] + unsafe fn cow_clone<'r>(&'r mut self) -> &'r mut T { + (*self.ptr).count -= 1; + self.ptr = transmute(~RcBox{value: (*self.ptr).value.clone(), count: 1}); + cast::copy_mut_lifetime(self, &mut (*self.ptr).value) + } + + /// Clones the content if there is more than one reference, or unwraps + /// the data if this is the only reference + pub fn value<'r>(self) -> T { + unsafe { + if (*self.ptr).count > 1 { + (*self.ptr).value.clone() + } else { + let box: ~RcBox = transmute(self.ptr); + forget(self); + box.value + } + } + } } impl Clone for Rc { @@ -79,7 +143,7 @@ impl Clone for Rc { impl DeepClone for Rc { #[inline] fn deep_clone(&self) -> Rc { - unsafe { Rc::new_unchecked(self.borrow().deep_clone()) } + unsafe { Rc::new_unchecked(self.get().deep_clone()) } } } @@ -107,10 +171,10 @@ mod test_rc { unsafe { let x = Rc::new_unchecked(Cell::new(5)); let y = x.clone(); - do x.borrow().with_mut_ref |inner| { + do x.get().with_mut_ref |inner| { *inner = 20; } - assert_eq!(y.borrow().take(), 20); + assert_eq!(y.get().take(), 20); } } @@ -119,34 +183,43 @@ mod test_rc { unsafe { let x = Rc::new_unchecked(Cell::new(5)); let y = x.deep_clone(); - do x.borrow().with_mut_ref |inner| { + do x.get().with_mut_ref |inner| { *inner = 20; } - assert_eq!(y.borrow().take(), 5); + assert_eq!(y.get().take(), 5); } } #[test] fn test_simple() { let x = Rc::new(5); - assert_eq!(*x.borrow(), 5); + assert_eq!(*x.get(), 5); } #[test] fn test_simple_clone() { let x = Rc::new(5); let y = x.clone(); - assert_eq!(*x.borrow(), 5); - assert_eq!(*y.borrow(), 5); + assert_eq!(*x.get(), 5); + assert_eq!(*y.get(), 5); } #[test] fn test_destructor() { unsafe { let x = Rc::new_unchecked(~5); - assert_eq!(**x.borrow(), 5); + assert_eq!(**x.get(), 5); } } + + #[test] + fn test_mut() { + let mut x = Rc::from_freeze(5); + let y = x.clone(); + *x.cow() = 9; + assert_eq!(*x.get(), 9); + assert_eq!(*y.get(), 5); + } } #[deriving(Eq)] @@ -159,7 +232,7 @@ enum Borrow { struct RcMutBox { value: T, count: uint, - borrow: Borrow + get: Borrow } /// Mutable reference counted pointer type @@ -193,32 +266,32 @@ impl RcMut { /// poorly with managed pointers. #[inline] pub unsafe fn new_unchecked(value: T) -> RcMut { - RcMut{ptr: transmute(~RcMutBox{value: value, count: 1, borrow: Nothing})} + RcMut{ptr: transmute(~RcMutBox{value: value, count: 1, get: Nothing})} } } impl RcMut { - /// Fails if there is already a mutable borrow of the box + /// Fails if there is already a mutable get of the box #[inline] - pub fn with_borrow(&self, f: &fn(&T) -> U) -> U { + pub fn with_get(&self, f: &fn(&T) -> U) -> U { unsafe { - assert!((*self.ptr).borrow != Mutable); - let previous = (*self.ptr).borrow; - (*self.ptr).borrow = Immutable; + assert!((*self.ptr).get != Mutable); + let previous = (*self.ptr).get; + (*self.ptr).get = Immutable; let res = f(&(*self.ptr).value); - (*self.ptr).borrow = previous; + (*self.ptr).get = previous; res } } - /// Fails if there is already a mutable or immutable borrow of the box + /// Fails if there is already a mutable or immutable get of the box #[inline] - pub fn with_mut_borrow(&self, f: &fn(&mut T) -> U) -> U { + pub fn with_mut_get(&self, f: &fn(&mut T) -> U) -> U { unsafe { - assert_eq!((*self.ptr).borrow, Nothing); - (*self.ptr).borrow = Mutable; + assert_eq!((*self.ptr).get, Nothing); + (*self.ptr).get = Mutable; let res = f(&mut (*self.ptr).value); - (*self.ptr).borrow = Nothing; + (*self.ptr).get = Nothing; res } } @@ -253,7 +326,7 @@ impl DeepClone for RcMut { /// Return a deep copy of the reference counted pointer. #[inline] fn deep_clone(&self) -> RcMut { - do self.with_borrow |x| { + do self.with_get |x| { // FIXME: #6497: should avoid freeze (slow) unsafe { RcMut::new_unchecked(x.deep_clone()) } } @@ -268,10 +341,10 @@ mod test_rc_mut { fn test_clone() { let x = RcMut::from_send(5); let y = x.clone(); - do x.with_mut_borrow |value| { + do x.with_mut_get |value| { *value = 20; } - do y.with_borrow |value| { + do y.with_get |value| { assert_eq!(*value, 20); } } @@ -280,24 +353,24 @@ mod test_rc_mut { fn test_deep_clone() { let x = RcMut::new(5); let y = x.deep_clone(); - do x.with_mut_borrow |value| { + do x.with_mut_get |value| { *value = 20; } - do y.with_borrow |value| { + do y.with_get |value| { assert_eq!(*value, 5); } } #[test] - fn borrow_many() { + fn get_many() { let x = RcMut::from_send(5); let y = x.clone(); - do x.with_borrow |a| { + do x.with_get |a| { assert_eq!(*a, 5); - do y.with_borrow |b| { + do y.with_get |b| { assert_eq!(*b, 5); - do x.with_borrow |c| { + do x.with_get |c| { assert_eq!(*c, 5); } } @@ -309,12 +382,12 @@ mod test_rc_mut { let x = RcMut::new(5); let y = x.clone(); - do y.with_mut_borrow |a| { + do y.with_mut_get |a| { assert_eq!(*a, 5); *a = 6; } - do x.with_borrow |a| { + do x.with_get |a| { assert_eq!(*a, 6); } } @@ -322,15 +395,15 @@ mod test_rc_mut { #[test] fn release_immutable() { let x = RcMut::from_send(5); - do x.with_borrow |_| {} - do x.with_mut_borrow |_| {} + do x.with_get |_| {} + do x.with_mut_get |_| {} } #[test] fn release_mutable() { let x = RcMut::new(5); - do x.with_mut_borrow |_| {} - do x.with_borrow |_| {} + do x.with_mut_get |_| {} + do x.with_get |_| {} } #[test] @@ -339,8 +412,8 @@ mod test_rc_mut { let x = RcMut::from_send(5); let y = x.clone(); - do x.with_borrow |_| { - do y.with_mut_borrow |_| { + do x.with_get |_| { + do y.with_mut_get |_| { } } } @@ -351,8 +424,8 @@ mod test_rc_mut { let x = RcMut::new(5); let y = x.clone(); - do x.with_mut_borrow |_| { - do y.with_mut_borrow |_| { + do x.with_mut_get |_| { + do y.with_mut_get |_| { } } } @@ -363,8 +436,8 @@ mod test_rc_mut { let x = RcMut::from_send(5); let y = x.clone(); - do x.with_mut_borrow |_| { - do y.with_borrow |_| { + do x.with_mut_get |_| { + do y.with_get |_| { } } } @@ -375,9 +448,9 @@ mod test_rc_mut { let x = RcMut::new(5); let y = x.clone(); - do x.with_borrow |_| { - do x.with_borrow |_| {} - do y.with_mut_borrow |_| {} + do x.with_get |_| { + do x.with_get |_| {} + do y.with_mut_get |_| {} } } } diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs index f3945d8f3c9d4..a9c0ac5e64e89 100644 --- a/src/libstd/unstable/sync.rs +++ b/src/libstd/unstable/sync.rs @@ -42,16 +42,23 @@ struct ArcData { data: Option, } -unsafe fn new_inner(data: T, refcount: uint) -> *mut ArcData { +unsafe fn new_inner(data: T, refcount: uint) -> *mut ArcData { let data = ~ArcData { count: AtomicUint::new(refcount), unwrapper: AtomicOption::empty(), data: Some(data) }; cast::transmute(data) } +impl UnsafeArc +{ + pub unsafe fn new_unsafe(data: T) -> UnsafeArc { + UnsafeArc { data: new_inner(data, 1) } + } +} + impl UnsafeArc { pub fn new(data: T) -> UnsafeArc { - unsafe { UnsafeArc { data: new_inner(data, 1) } } + unsafe { UnsafeArc::new_unsafe(data) } } /// As new(), but returns an extra pre-cloned handle. @@ -73,7 +80,9 @@ impl UnsafeArc { } } } +} +impl UnsafeArc { /// As newN(), but from an already-existing handle. Uses one xadd. pub fn cloneN(self, num_handles: uint) -> ~[UnsafeArc] { if num_handles == 0 { @@ -109,6 +118,17 @@ impl UnsafeArc { } } + /// Whether this is the only reference to the data + #[inline] + pub fn is_owned(&self) -> bool { + unsafe { + let mut data: ~ArcData = cast::transmute(self.data); + let r = data.count.load(Acquire) == 1 && data.unwrapper.is_empty(Acquire); + cast::forget(data); + return r; + } + } + /// Wait until all other handles are dropped, then retrieve the enclosed /// data. See extra::arc::Arc for specific semantics documentation. /// If called when the task is already unkillable, unwrap will unkillably @@ -207,7 +227,7 @@ impl UnsafeArc { } } -impl Clone for UnsafeArc { +impl Clone for UnsafeArc { fn clone(&self) -> UnsafeArc { unsafe { // This barrier might be unnecessary, but I'm not sure... @@ -559,6 +579,12 @@ mod tests { p.recv(); } + #[test] + fn arclike_new_should_be_owned() { + let x = UnsafeArc::new(~~"hello"); + assert!(x.is_owned()) + } + #[test] fn exclusive_new_unwrap_basic() { // Unlike the above, also tests no double-freeing of the LittleLock.