From aa38adf7b6cb045d6e0fe23a88ff71e02945613d Mon Sep 17 00:00:00 2001 From: Bill Myers Date: Thu, 10 Oct 2013 04:08:39 +0200 Subject: [PATCH 1/6] rc: rename borrow to get Shorter and same name used by Arc --- src/libstd/rc.rs | 94 ++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs index 41e834cf37c39..cb0e6744effc3 100644 --- a/src/libstd/rc.rs +++ b/src/libstd/rc.rs @@ -61,7 +61,7 @@ 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 } } } @@ -79,7 +79,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 +107,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,32 +119,32 @@ 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); } } } @@ -159,7 +159,7 @@ enum Borrow { struct RcMutBox { value: T, count: uint, - borrow: Borrow + get: Borrow } /// Mutable reference counted pointer type @@ -193,32 +193,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 +253,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 +268,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 +280,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 +309,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 +322,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 +339,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 +351,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 +363,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 +375,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 |_| {} } } } From 29e5b75ba6ceace13e0f0888ab1dabb808ab70a5 Mon Sep 17 00:00:00 2001 From: Bill Myers Date: Thu, 10 Oct 2013 04:23:38 +0200 Subject: [PATCH 2/6] rc, arc: add copy-on-write mutable borrowing to Rc and Arc --- src/libextra/arc.rs | 30 ++++++++++++++++++++++++++++++ src/libstd/rc.rs | 31 +++++++++++++++++++++++++++++++ src/libstd/unstable/sync.rs | 17 +++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 1cb30eaa040b2..88dc547311d1f 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -140,6 +140,27 @@ impl Arc { } } +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((*self.x.get_immut()).clone()); + &mut *self.x.get() + } +} + impl Clone for Arc { /** * Duplicate an atomically reference counted wrapper. @@ -622,6 +643,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/libstd/rc.rs b/src/libstd/rc.rs index cb0e6744effc3..de083d7a8426b 100644 --- a/src/libstd/rc.rs +++ b/src/libstd/rc.rs @@ -66,6 +66,28 @@ impl Rc { } } +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) + } +} + impl Clone for Rc { #[inline] fn clone(&self) -> Rc { @@ -147,6 +169,15 @@ mod test_rc { 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)] diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs index f3945d8f3c9d4..a5e80ce91fa27 100644 --- a/src/libstd/unstable/sync.rs +++ b/src/libstd/unstable/sync.rs @@ -109,6 +109,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 @@ -559,6 +570,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. From da7e88934cc9cb98521cba4176b40fd2c4ec696f Mon Sep 17 00:00:00 2001 From: Bill Myers Date: Thu, 10 Oct 2013 18:34:58 +0200 Subject: [PATCH 3/6] rc, arc: add support for by-value copy-on-write and try-to-write The try_ functions don't require Clone, but they do nothing if rc > 1 The try_unwrap and value take and return by-value instead of &mut --- src/libextra/arc.rs | 26 ++++++++++++++++++++++++++ src/libstd/rc.rs | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 88dc547311d1f..d78feef5d28f2 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -138,6 +138,23 @@ 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 { @@ -159,6 +176,15 @@ impl Arc { self.x = UnsafeArc::new((*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 { diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs index de083d7a8426b..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, @@ -64,6 +66,32 @@ impl Rc { 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 { @@ -86,6 +114,20 @@ impl Rc { 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 { From 034c24ad9204fdc5b7aff42869ad844358d0f525 Mon Sep 17 00:00:00 2001 From: Bill Myers Date: Sat, 12 Oct 2013 02:45:03 +0200 Subject: [PATCH 4/6] arc: relax kind bounds on non-constructor They aren't needed, since arcs without the kinds can't be created with safe code, and unsafe code should be allowed to do whatever it wants. This greatly simplifies libraries using Arc who no longer need to impose those traits unless they construct arcs. --- src/libextra/arc.rs | 8 +++++--- src/libstd/unstable/sync.rs | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index d78feef5d28f2..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() } } @@ -157,7 +159,7 @@ impl Arc { } } -impl Arc { +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] @@ -173,7 +175,7 @@ impl Arc { #[inline(never)] unsafe fn cow_clone<'r>(&'r mut self) -> &'r mut T { - self.x = UnsafeArc::new((*self.x.get_immut()).clone()); + self.x = UnsafeArc::new_unsafe((*self.x.get_immut()).clone()); &mut *self.x.get() } @@ -187,7 +189,7 @@ impl Arc { } } -impl Clone for Arc { +impl Clone for Arc { /** * Duplicate an atomically reference counted wrapper. * diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs index a5e80ce91fa27..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 { @@ -218,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... From 2cc6374b942b8a95a7f0ecffbd986b12e6e6728c Mon Sep 17 00:00:00 2001 From: Bill Myers Date: Sat, 12 Oct 2013 02:46:43 +0200 Subject: [PATCH 5/6] own: add owned pointer wrapper with API like Rc and Arc --- src/libstd/owned.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) 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} +} From d5f9c0c5ded8494c040fa0c3cb99117000e77765 Mon Sep 17 00:00:00 2001 From: Bill Myers Date: Thu, 10 Oct 2013 22:36:54 +0200 Subject: [PATCH 6/6] treemap: replace with a potentially snapshottable version --- src/libextra/treemap.rs | 3260 ++++++++++++++++++++++++--------------- 1 file changed, 1976 insertions(+), 1284 deletions(-) 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)} } +