From 6c00f9c5ff67ec1e206cd1e6e2db37df298f5d5b Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Tue, 16 Dec 2014 22:33:13 -0500 Subject: [PATCH 1/3] remove TreeMap, TreeSet, TrieMap, TrieSet, LruCache. deprecate EnumSet's std re-export --- src/libcollections/lib.rs | 22 - src/libcollections/tree/map.rs | 1961 --------------------------- src/libcollections/tree/mod.rs | 35 - src/libcollections/tree/set.rs | 1218 ----------------- src/libcollections/trie/map.rs | 1958 -------------------------- src/libcollections/trie/mod.rs | 19 - src/libcollections/trie/set.rs | 972 ------------- src/libstd/collections/lru_cache.rs | 471 ------- src/libstd/collections/mod.rs | 39 +- 9 files changed, 13 insertions(+), 6682 deletions(-) delete mode 100644 src/libcollections/tree/map.rs delete mode 100644 src/libcollections/tree/mod.rs delete mode 100644 src/libcollections/tree/set.rs delete mode 100644 src/libcollections/trie/map.rs delete mode 100644 src/libcollections/trie/mod.rs delete mode 100644 src/libcollections/trie/set.rs delete mode 100644 src/libstd/collections/lru_cache.rs diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 1d60d7612a0b7..a8eb10e51635f 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -46,10 +46,6 @@ pub use dlist::DList; pub use enum_set::EnumSet; pub use ring_buf::RingBuf; pub use string::String; -pub use tree_map::TreeMap; -pub use tree_set::TreeSet; -pub use trie_map::TrieMap; -pub use trie_set::TrieSet; pub use vec::Vec; pub use vec_map::VecMap; @@ -61,8 +57,6 @@ mod btree; pub mod dlist; pub mod enum_set; pub mod ring_buf; -mod tree; -mod trie; pub mod slice; pub mod str; pub mod string; @@ -77,22 +71,6 @@ pub mod bitv_set { pub use bit::{BitvSet, BitPositions, TwoBitPositions}; } -pub mod tree_map { - pub use tree::map::*; -} - -pub mod tree_set { - pub use tree::set::*; -} - -pub mod trie_map { - pub use trie::map::*; -} - -pub mod trie_set { - pub use trie::set::*; -} - pub mod btree_map { pub use btree::map::*; } diff --git a/src/libcollections/tree/map.rs b/src/libcollections/tree/map.rs deleted file mode 100644 index cc667285d29f3..0000000000000 --- a/src/libcollections/tree/map.rs +++ /dev/null @@ -1,1961 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use core::prelude::*; - -use alloc::boxed::Box; - -use core::borrow::BorrowFrom; -use core::default::Default; -use core::fmt; -use core::fmt::Show; -use core::iter; -use core::mem::{replace, swap}; -use core::ptr; -use std::hash::{Writer, Hash}; - -use vec::Vec; - -// FIXME(conventions): implement bounded iterators -// FIXME(conventions): replace rev_iter(_mut) by making iter(_mut) DoubleEnded - -/// 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 -/// as a right child. The time complexity is the same, and re-balancing -/// operations are more frequent but also cheaper. -/// -/// # Examples -/// -/// ``` -/// use std::collections::TreeMap; -/// -/// let mut map = TreeMap::new(); -/// -/// map.insert(2i, "bar"); -/// map.insert(1i, "foo"); -/// map.insert(3i, "quux"); -/// -/// // In ascending order by keys -/// for (key, value) in map.iter() { -/// println!("{}: {}", key, value); -/// } -/// -/// // Prints 1, 2, 3 -/// for key in map.keys() { -/// println!("{}", key); -/// } -/// -/// // Prints `foo`, `bar`, `quux` -/// for key in map.values() { -/// println!("{}", key); -/// } -/// -/// map.remove(&1); -/// assert_eq!(map.len(), 2); -/// -/// if !map.contains_key(&1) { -/// println!("1 is no more"); -/// } -/// -/// for key in range(0, 4) { -/// match map.get(&key) { -/// Some(val) => println!("{} has a value: {}", key, val), -/// None => println!("{} not in map", key), -/// } -/// } -/// -/// map.clear(); -/// assert!(map.is_empty()); -/// ``` -/// -/// The easiest way to use `TreeMap` with a custom type as keys is to implement `Ord`. -/// We must also implement `PartialEq`, `Eq` and `PartialOrd`. -/// -/// ``` -/// use std::collections::TreeMap; -/// -/// // We need `Eq` and `PartialEq`, these can be derived. -/// #[deriving(Eq, PartialEq)] -/// struct Troll<'a> { -/// name: &'a str, -/// level: uint, -/// } -/// -/// // Implement `Ord` and sort trolls by level. -/// impl<'a> Ord for Troll<'a> { -/// fn cmp(&self, other: &Troll) -> Ordering { -/// // If we swap `self` and `other`, we get descending ordering. -/// self.level.cmp(&other.level) -/// } -/// } -/// -/// // `PartialOrd` needs to be implemented as well. -/// impl<'a> PartialOrd for Troll<'a> { -/// fn partial_cmp(&self, other: &Troll) -> Option { -/// Some(self.cmp(other)) -/// } -/// } -/// -/// // Use a map to store trolls, sorted by level, and track a list of -/// // heroes slain. -/// let mut trolls = TreeMap::new(); -/// -/// trolls.insert(Troll { name: "Orgarr", level: 2 }, -/// vec!["King Karl"]); -/// trolls.insert(Troll { name: "Blargarr", level: 3 }, -/// vec!["Odd"]); -/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 }, -/// vec!["Omar the Brave", "Peter: Slayer of Trolls"]); -/// trolls.insert(Troll { name: "Wartilda", level: 1 }, -/// vec![]); -/// -/// println!("You are facing {} trolls!", trolls.len()); -/// -/// // Print the trolls, ordered by level with smallest level first -/// for (troll, heroes) in trolls.iter() { -/// let what = if heroes.len() == 1u { "hero" } -/// else { "heroes" }; -/// -/// println!("level {}: '{}' has slain {} {}", -/// troll.level, troll.name, heroes.len(), what); -/// } -/// -/// // Kill all trolls -/// trolls.clear(); -/// assert_eq!(trolls.len(), 0); -/// ``` - -// Future improvements: - -// range search - O(log n) retrieval of an iterator from some key - -// (possibly) implement the overloads Python does for sets: -// * intersection: & -// * difference: - -// * symmetric difference: ^ -// * union: | -// These would be convenient since the methods work like `each` - -#[deriving(Clone)] -pub struct TreeMap { - root: Option>>, - length: uint -} - -impl PartialEq for TreeMap { - fn eq(&self, other: &TreeMap) -> bool { - self.len() == other.len() && - self.iter().zip(other.iter()).all(|(a, b)| a == b) - } -} - -impl Eq for TreeMap {} - -impl PartialOrd for TreeMap { - #[inline] - fn partial_cmp(&self, other: &TreeMap) -> Option { - iter::order::partial_cmp(self.iter(), other.iter()) - } -} - -impl Ord for TreeMap { - #[inline] - fn cmp(&self, other: &TreeMap) -> Ordering { - iter::order::cmp(self.iter(), other.iter()) - } -} - -impl Show for TreeMap { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, (k, v)) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{}: {}", *k, *v)); - } - - write!(f, "}}") - } -} - -#[stable] -impl Default for TreeMap { - #[inline] - #[stable] - fn default() -> TreeMap { TreeMap::new() } -} - -impl Index for TreeMap where Q: BorrowFrom + Ord { - #[inline] - fn index<'a>(&'a self, i: &Q) -> &'a V { - self.get(i).expect("no entry found for key") - } -} - -impl IndexMut for TreeMap where Q: BorrowFrom + Ord { - #[inline] - fn index_mut<'a>(&'a mut self, i: &Q) -> &'a mut V { - self.get_mut(i).expect("no entry found for key") - } -} - -impl TreeMap { - /// Creates an empty `TreeMap`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// let mut map: TreeMap<&str, int> = TreeMap::new(); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } - - /// Gets a lazy iterator over the keys in the map, in ascending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// let mut map = TreeMap::new(); - /// map.insert("a", 1i); - /// map.insert("c", 3i); - /// map.insert("b", 2i); - /// - /// // Print "a", "b", "c" in order. - /// for x in map.keys() { - /// println!("{}", x); - /// } - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { - fn first((a, _): (A, B)) -> A { a } - - self.iter().map(first) - } - - /// Gets a lazy iterator over the values in the map, in ascending order - /// with respect to the corresponding keys. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// let mut map = TreeMap::new(); - /// map.insert("a", 1i); - /// map.insert("c", 3i); - /// map.insert("b", 2i); - /// - /// // Print 1, 2, 3 ordered by keys. - /// for x in map.values() { - /// println!("{}", x); - /// } - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn values<'a>(&'a self) -> Values<'a, K, V> { - fn second((_, b): (A, B)) -> B { b } - - self.iter().map(second) - } - - /// Gets a lazy iterator over the key-value pairs in the map, in ascending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// let mut map = TreeMap::new(); - /// map.insert("a", 1i); - /// map.insert("c", 3i); - /// map.insert("b", 2i); - /// - /// // Print contents in ascending order - /// for (key, value) in map.iter() { - /// println!("{}: {}", key, value); - /// } - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn iter<'a>(&'a self) -> Entries<'a, K, V> { - Entries { - stack: vec!(), - node: deref(&self.root), - remaining_min: self.length, - remaining_max: self.length - } - } - - /// Gets a lazy reverse iterator over the key-value pairs in the map, in descending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// let mut map = TreeMap::new(); - /// map.insert("a", 1i); - /// map.insert("c", 3i); - /// map.insert("b", 2i); - /// - /// // Print contents in descending order - /// for (key, value) in map.rev_iter() { - /// println!("{}: {}", key, value); - /// } - /// ``` - pub fn rev_iter<'a>(&'a self) -> RevEntries<'a, K, V> { - RevEntries{iter: self.iter()} - } - - /// Gets a lazy forward iterator over the key-value pairs in the - /// map, with the values being mutable. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// let mut map = TreeMap::new(); - /// map.insert("a", 1i); - /// map.insert("c", 3i); - /// map.insert("b", 2i); - /// - /// // Add 10 until we find "b" - /// for (key, value) in map.iter_mut() { - /// *value += 10; - /// if key == &"b" { break } - /// } - /// - /// assert_eq!(map.get(&"a"), Some(&11)); - /// assert_eq!(map.get(&"b"), Some(&12)); - /// assert_eq!(map.get(&"c"), Some(&3)); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn iter_mut<'a>(&'a mut self) -> MutEntries<'a, K, V> { - MutEntries { - stack: vec!(), - node: deref_mut(&mut self.root), - remaining_min: self.length, - remaining_max: self.length - } - } - - /// Gets a lazy reverse iterator over the key-value pairs in the - /// map, with the values being mutable. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// let mut map = TreeMap::new(); - /// map.insert("a", 1i); - /// map.insert("c", 3i); - /// map.insert("b", 2i); - /// - /// // Add 10 until we find "b" - /// for (key, value) in map.rev_iter_mut() { - /// *value += 10; - /// if key == &"b" { break } - /// } - /// - /// assert_eq!(map.get(&"a"), Some(&1)); - /// assert_eq!(map.get(&"b"), Some(&12)); - /// assert_eq!(map.get(&"c"), Some(&13)); - /// ``` - pub fn rev_iter_mut<'a>(&'a mut self) -> RevMutEntries<'a, K, V> { - RevMutEntries{iter: self.iter_mut()} - } - - /// Gets a lazy iterator that consumes the treemap. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// let mut map = TreeMap::new(); - /// map.insert("a", 1i); - /// map.insert("c", 3i); - /// map.insert("b", 2i); - /// - /// // Not possible with a regular `.iter()` - /// let vec: Vec<(&str, int)> = map.into_iter().collect(); - /// assert_eq!(vec, vec![("a", 1), ("b", 2), ("c", 3)]); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn into_iter(self) -> MoveEntries { - let TreeMap { root, length } = self; - let stk = match root { - None => vec!(), - Some(box tn) => vec!(tn) - }; - MoveEntries { - stack: stk, - remaining: length - } - } - - /// Return the number of elements in the map. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut a = TreeMap::new(); - /// assert_eq!(a.len(), 0); - /// a.insert(1u, "a"); - /// assert_eq!(a.len(), 1); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn len(&self) -> uint { self.length } - - /// Return true if the map contains no elements. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut a = TreeMap::new(); - /// assert!(a.is_empty()); - /// a.insert(1u, "a"); - /// assert!(!a.is_empty()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - #[inline] - pub fn is_empty(&self) -> bool { self.len() == 0 } - - /// Clears the map, removing all values. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut a = TreeMap::new(); - /// a.insert(1u, "a"); - /// a.clear(); - /// assert!(a.is_empty()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn clear(&mut self) { - self.root = None; - self.length = 0 - } - - /// Deprecated: Renamed to `get`. - #[deprecated = "Renamed to `get`"] - pub fn find(&self, key: &K) -> Option<&V> { - self.get(key) - } - - /// Returns a reference to the value corresponding to the key. - /// - /// The key may be any borrowed form of the map's key type, but the ordering - /// on the borrowed form *must* match the ordering on the key type. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut map = TreeMap::new(); - /// map.insert(1u, "a"); - /// assert_eq!(map.get(&1), Some(&"a")); - /// assert_eq!(map.get(&2), None); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get(&self, key: &Q) -> Option<&V> - where Q: BorrowFrom + Ord - { - tree_find_with(&self.root, |k2| key.cmp(BorrowFrom::borrow_from(k2))) - } - - /// Returns true if the map contains a value for the specified key. - /// - /// The key may be any borrowed form of the map's key type, but the ordering - /// on the borrowed form *must* match the ordering on the key type. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut map = TreeMap::new(); - /// map.insert(1u, "a"); - /// assert_eq!(map.contains_key(&1), true); - /// assert_eq!(map.contains_key(&2), false); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains_key(&self, key: &Q) -> bool - where Q: BorrowFrom + Ord - { - self.get(key).is_some() - } - - /// Deprecated: Renamed to `get_mut`. - #[deprecated = "Renamed to `get_mut`"] - pub fn find_mut(&mut self, key: &K) -> Option<&mut V> { - self.get_mut(key) - } - - /// Returns a mutable reference to the value corresponding to the key. - /// - /// The key may be any borrowed form of the map's key type, but the ordering - /// on the borrowed form *must* match the ordering on the key type. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut map = TreeMap::new(); - /// map.insert(1u, "a"); - /// match map.get_mut(&1) { - /// Some(x) => *x = "b", - /// None => (), - /// } - /// assert_eq!(map[1], "b"); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> - where Q: BorrowFrom + Ord - { - tree_find_with_mut(&mut self.root, |x| key.cmp(BorrowFrom::borrow_from(x))) - } - - /// Deprecated: Renamed to `insert`. - #[deprecated = "Renamed to `insert`"] - pub fn swap(&mut self, key: K, value: V) -> Option { - self.insert(key, value) - } - - /// Inserts 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. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut map = TreeMap::new(); - /// assert_eq!(map.insert(37u, "a"), None); - /// assert_eq!(map.is_empty(), false); - /// - /// map.insert(37, "b"); - /// assert_eq!(map.insert(37, "c"), Some("b")); - /// assert_eq!(map[37], "c"); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn insert(&mut self, key: K, value: V) -> Option { - let ret = insert(&mut self.root, key, value); - if ret.is_none() { self.length += 1 } - ret - } - - /// Deprecated: Renamed to `remove`. - #[deprecated = "Renamed to `remove`"] - pub fn pop(&mut self, key: &K) -> Option { - self.remove(key) - } - - /// Removes a key from the map, returning the value at the key if the key - /// was previously in the map. - /// - /// The key may be any borrowed form of the map's key type, but the ordering - /// on the borrowed form *must* match the ordering on the key type. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut map = TreeMap::new(); - /// map.insert(1u, "a"); - /// assert_eq!(map.remove(&1), Some("a")); - /// assert_eq!(map.remove(&1), None); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, key: &Q) -> Option - where Q: BorrowFrom + Ord - { - let ret = remove(&mut self.root, key); - if ret.is_some() { self.length -= 1 } - ret - } -} - -impl TreeMap { - /// Returns the value for which `f(key)` returns `Equal`. `f` is invoked - /// with current key and guides tree navigation. That means `f` should - /// be aware of natural ordering of the tree. - /// - /// # Examples - /// - /// ``` - /// use collections::tree_map::TreeMap; - /// - /// fn get_headers() -> TreeMap { - /// let mut result = TreeMap::new(); - /// result.insert("Content-Type".to_string(), "application/xml".to_string()); - /// result.insert("User-Agent".to_string(), "Curl-Rust/0.1".to_string()); - /// result - /// } - /// - /// let headers = get_headers(); - /// let ua_key = "User-Agent"; - /// let ua = headers.find_with(|k| { - /// ua_key.cmp(k.as_slice()) - /// }); - /// - /// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1"); - /// ``` - #[inline] - #[experimental = "likely to be renamed, may be removed"] - pub fn find_with(&self, f: F) -> Option<&V> where F: FnMut(&K) -> Ordering { - tree_find_with(&self.root, f) - } - - /// Returns the value for which `f(key)` returns `Equal`. `f` is invoked - /// with current key and guides tree navigation. That means `f` should - /// be aware of natural ordering of the tree. - /// - /// # Examples - /// - /// ``` - /// let mut t = collections::tree_map::TreeMap::new(); - /// t.insert("Content-Type", "application/xml"); - /// t.insert("User-Agent", "Curl-Rust/0.1"); - /// - /// let new_ua = "Safari/156.0"; - /// match t.find_with_mut(|&k| "User-Agent".cmp(k)) { - /// Some(x) => *x = new_ua, - /// None => panic!(), - /// } - /// - /// assert_eq!(t.get(&"User-Agent"), Some(&new_ua)); - /// ``` - #[inline] - #[experimental = "likely to be renamed, may be removed"] - pub fn find_with_mut<'a, F>(&'a mut self, f: F) -> Option<&'a mut V> where - F: FnMut(&K) -> Ordering - { - tree_find_with_mut(&mut self.root, f) - } -} - -// range iterators. - -macro_rules! bound_setup { - // initialiser of the iterator to manipulate - ($iter:expr, $k:expr, - // whether we are looking for the lower or upper bound. - $is_lower_bound:expr) => { - { - let mut iter = $iter; - loop { - if !iter.node.is_null() { - let node_k = unsafe {&(*iter.node).key}; - match $k.cmp(node_k) { - Less => iter.traverse_left(), - Greater => iter.traverse_right(), - Equal => { - if $is_lower_bound { - iter.traverse_complete(); - return iter; - } else { - iter.traverse_right() - } - } - } - } else { - iter.traverse_complete(); - return iter; - } - } - } - } -} - - -impl TreeMap { - /// Gets a lazy iterator that should be initialized using - /// `traverse_left`/`traverse_right`/`traverse_complete`. - fn iter_for_traversal<'a>(&'a self) -> Entries<'a, K, V> { - Entries { - stack: vec!(), - node: deref(&self.root), - remaining_min: 0, - remaining_max: self.length - } - } - - /// Returns 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. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut map = TreeMap::new(); - /// map.insert(2i, "a"); - /// map.insert(4, "b"); - /// map.insert(6, "c"); - /// map.insert(8, "d"); - /// - /// assert_eq!(map.lower_bound(&4).next(), Some((&4, &"b"))); - /// assert_eq!(map.lower_bound(&5).next(), Some((&6, &"c"))); - /// assert_eq!(map.lower_bound(&10).next(), None); - /// ``` - pub fn lower_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> { - bound_setup!(self.iter_for_traversal(), k, true) - } - - /// Returns a lazy iterator to the first key-value pair whose key is greater than `k` - /// If all keys in map are less than or equal to `k` an empty iterator is returned. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut map = TreeMap::new(); - /// map.insert(2i, "a"); - /// map.insert(4, "b"); - /// map.insert(6, "c"); - /// map.insert(8, "d"); - /// - /// assert_eq!(map.upper_bound(&4).next(), Some((&6, &"c"))); - /// assert_eq!(map.upper_bound(&5).next(), Some((&6, &"c"))); - /// assert_eq!(map.upper_bound(&10).next(), None); - /// ``` - pub fn upper_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> { - bound_setup!(self.iter_for_traversal(), k, false) - } - - /// Gets a lazy iterator that should be initialized using - /// `traverse_left`/`traverse_right`/`traverse_complete`. - fn iter_mut_for_traversal<'a>(&'a mut self) -> MutEntries<'a, K, V> { - MutEntries { - stack: vec!(), - node: deref_mut(&mut self.root), - remaining_min: 0, - remaining_max: self.length - } - } - - /// Returns a lazy value iterator to the first key-value pair (with - /// the value being mutable) whose key is not less than `k`. - /// - /// If all keys in map are less than `k` an empty iterator is - /// returned. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut map = TreeMap::new(); - /// map.insert(2i, "a"); - /// map.insert(4, "b"); - /// map.insert(6, "c"); - /// map.insert(8, "d"); - /// - /// assert_eq!(map.lower_bound_mut(&4).next(), Some((&4, &mut "b"))); - /// assert_eq!(map.lower_bound_mut(&5).next(), Some((&6, &mut "c"))); - /// assert_eq!(map.lower_bound_mut(&10).next(), None); - /// - /// for (key, value) in map.lower_bound_mut(&4) { - /// *value = "changed"; - /// } - /// - /// assert_eq!(map.get(&2), Some(&"a")); - /// assert_eq!(map.get(&4), Some(&"changed")); - /// assert_eq!(map.get(&6), Some(&"changed")); - /// assert_eq!(map.get(&8), Some(&"changed")); - /// ``` - pub fn lower_bound_mut<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> { - bound_setup!(self.iter_mut_for_traversal(), k, true) - } - - /// Returns a lazy iterator to the first key-value pair (with the - /// value being mutable) whose key is greater than `k`. - /// - /// If all keys in map are less than or equal to `k` an empty iterator - /// is returned. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut map = TreeMap::new(); - /// map.insert(2i, "a"); - /// map.insert(4, "b"); - /// map.insert(6, "c"); - /// map.insert(8, "d"); - /// - /// assert_eq!(map.upper_bound_mut(&4).next(), Some((&6, &mut "c"))); - /// assert_eq!(map.upper_bound_mut(&5).next(), Some((&6, &mut "c"))); - /// assert_eq!(map.upper_bound_mut(&10).next(), None); - /// - /// for (key, value) in map.upper_bound_mut(&4) { - /// *value = "changed"; - /// } - /// - /// assert_eq!(map.get(&2), Some(&"a")); - /// assert_eq!(map.get(&4), Some(&"b")); - /// assert_eq!(map.get(&6), Some(&"changed")); - /// assert_eq!(map.get(&8), Some(&"changed")); - /// ``` - pub fn upper_bound_mut<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> { - bound_setup!(self.iter_mut_for_traversal(), k, false) - } -} - -/// Lazy forward iterator over a map -pub struct Entries<'a, K:'a, V:'a> { - stack: Vec<&'a TreeNode>, - // See the comment on MutEntries; this is just to allow - // code-sharing (for this immutable-values iterator it *could* very - // well be Option<&'a TreeNode>). - node: *const TreeNode, - remaining_min: uint, - remaining_max: uint -} - -/// Lazy backward iterator over a map -pub struct RevEntries<'a, K:'a, V:'a> { - iter: Entries<'a, K, V>, -} - -/// Lazy forward iterator over a map that allows for the mutation of -/// the values. -pub struct MutEntries<'a, K:'a, V:'a> { - stack: Vec<&'a mut TreeNode>, - // Unfortunately, we require some unsafe-ness to get around the - // fact that we would be storing a reference *into* one of the - // nodes in the stack. - // - // As far as the compiler knows, this would let us invalidate the - // reference by assigning a new value to this node's position in - // its parent, which would cause this current one to be - // deallocated so this reference would be invalid. (i.e. the - // compilers complaints are 100% correct.) - // - // However, as far as you humans reading this code know (or are - // about to know, if you haven't read far enough down yet), we are - // only reading from the TreeNode.{left,right} fields. the only - // thing that is ever mutated is the .value field (although any - // actual mutation that happens is done externally, by the - // iterator consumer). So, don't be so concerned, rustc, we've got - // it under control. - // - // (This field can legitimately be null.) - node: *mut TreeNode, - remaining_min: uint, - remaining_max: uint -} - -/// Lazy backward iterator over a map -pub struct RevMutEntries<'a, K:'a, V:'a> { - iter: MutEntries<'a, K, V>, -} - -/// TreeMap keys iterator. -pub type Keys<'a, K, V> = - iter::Map<(&'a K, &'a V), &'a K, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>; - -/// TreeMap values iterator. -pub type Values<'a, K, V> = - iter::Map<(&'a K, &'a V), &'a V, Entries<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>; - - -// FIXME #5846 we want to be able to choose between &x and &mut x -// (with many different `x`) below, so we need to optionally pass mut -// as a tt, but the only thing we can do with a `tt` is pass them to -// other macros, so this takes the `& ` token -// sequence and forces their evaluation as an expression. -macro_rules! addr { ($e:expr) => { $e }} -// putting an optional mut into type signatures -macro_rules! item { ($i:item) => { $i }} - -macro_rules! define_iterator { - ($name:ident, - $rev_name:ident, - - // the function to go from &m Option> to *m TreeNode - deref = $deref:ident, - - // see comment on `addr!`, this is just an optional `mut`, but - // there's no support for 0-or-1 repeats. - addr_mut = $($addr_mut:tt)* - ) => { - // private methods on the forward iterator (item!() for the - // addr_mut in the next_ return value) - item! { impl<'a, K, V> $name<'a, K, V> { - #[inline(always)] - fn next_(&mut self, forward: bool) -> Option<(&'a K, &'a $($addr_mut)* V)> { - while !self.stack.is_empty() || !self.node.is_null() { - if !self.node.is_null() { - let node = unsafe {addr!(& $($addr_mut)* *self.node)}; - { - let next_node = if forward { - addr!(& $($addr_mut)* node.left) - } else { - addr!(& $($addr_mut)* node.right) - }; - self.node = $deref(next_node); - } - self.stack.push(node); - } else { - let node = self.stack.pop().unwrap(); - let next_node = if forward { - addr!(& $($addr_mut)* node.right) - } else { - addr!(& $($addr_mut)* node.left) - }; - self.node = $deref(next_node); - self.remaining_max -= 1; - if self.remaining_min > 0 { - self.remaining_min -= 1; - } - return Some((&node.key, addr!(& $($addr_mut)* node.value))); - } - } - None - } - - /// traverse_left, traverse_right and traverse_complete are - /// used to initialize Entries/MutEntries - /// pointing to element inside tree structure. - /// - /// They should be used in following manner: - /// - create iterator using TreeMap::[mut_]iter_for_traversal - /// - find required node using `traverse_left`/`traverse_right` - /// (current node is `Entries::node` field) - /// - complete initialization with `traverse_complete` - /// - /// After this, 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_left(&mut self) { - let node = unsafe {addr!(& $($addr_mut)* *self.node)}; - self.node = $deref(addr!(& $($addr_mut)* node.left)); - self.stack.push(node); - } - - #[inline] - fn traverse_right(&mut self) { - let node = unsafe {addr!(& $($addr_mut)* *self.node)}; - self.node = $deref(addr!(& $($addr_mut)* node.right)); - } - - #[inline] - fn traverse_complete(&mut self) { - if !self.node.is_null() { - unsafe { - self.stack.push(addr!(& $($addr_mut)* *self.node)); - } - self.node = ptr::RawPtr::null(); - } - } - } } - - // the forward Iterator impl. - item! { impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $name<'a, K, V> { - /// Advances 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<(&'a K, &'a $($addr_mut)* V)> { - self.next_(true) - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - (self.remaining_min, Some(self.remaining_max)) - } - } } - - // the reverse Iterator impl. - item! { impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $rev_name<'a, K, V> { - fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> { - self.iter.next_(false) - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - self.iter.size_hint() - } - } } - } -} // end of define_iterator - -define_iterator! { - Entries, - RevEntries, - deref = deref, - - // immutable, so no mut - addr_mut = -} -define_iterator! { - MutEntries, - RevMutEntries, - deref = deref_mut, - - addr_mut = mut -} - -fn deref<'a, K, V>(node: &'a Option>>) -> *const TreeNode { - match *node { - Some(ref n) => { - let n: &TreeNode = &**n; - n as *const TreeNode - } - None => ptr::null() - } -} - -fn deref_mut(x: &mut Option>>) - -> *mut TreeNode { - match *x { - Some(ref mut n) => { - let n: &mut TreeNode = &mut **n; - n as *mut TreeNode - } - None => ptr::null_mut() - } -} - -/// Lazy forward iterator over a map that consumes the map while iterating -pub struct MoveEntries { - stack: Vec>, - remaining: uint -} - -impl Iterator<(K, V)> for MoveEntries { - #[inline] - fn next(&mut self) -> Option<(K, V)> { - while !self.stack.is_empty() { - let TreeNode { - key, - value, - left, - right, - level, - } = self.stack.pop().unwrap(); - - match left { - Some(box left) => { - let n = TreeNode { - key: key, - value: value, - left: None, - right: right, - level: level - }; - self.stack.push(n); - self.stack.push(left); - } - None => { - match right { - Some(box right) => self.stack.push(right), - None => () - } - self.remaining -= 1; - return Some((key, value)) - } - } - } - None - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - (self.remaining, Some(self.remaining)) - } - -} - - - -// 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>>, - right: Option>>, - level: uint -} - -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} - } -} - -// Remove left horizontal link by rotating right -fn skew(node: &mut Box>) { - if node.left.as_ref().map_or(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); - } -} - -// Remove dual horizontal link by rotating left and increasing level of -// the parent -fn split(node: &mut Box>) { - if node.right.as_ref().map_or(false, - |x| x.right.as_ref().map_or(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); - } -} - -// Next 2 functions have the same convention: comparator gets -// at input current key and returns search_key cmp cur_key -// (i.e. search_key.cmp(&cur_key)) -fn tree_find_with<'r, K, V, F>( - node: &'r Option>>, - mut f: F, -) -> Option<&'r V> where - F: FnMut(&K) -> Ordering, -{ - let mut current: &'r Option>> = node; - loop { - match *current { - Some(ref r) => { - match f(&r.key) { - Less => current = &r.left, - Greater => current = &r.right, - Equal => return Some(&r.value) - } - } - None => return None - } - } -} - -// See comments above tree_find_with -fn tree_find_with_mut<'r, K, V, F>( - node: &'r mut Option>>, - mut f: F, -) -> Option<&'r mut V> where - F: FnMut(&K) -> Ordering, -{ - - let mut current = node; - loop { - let temp = current; // hack to appease borrowck - match *temp { - Some(ref mut r) => { - match f(&r.key) { - Less => current = &mut r.left, - Greater => current = &mut r.right, - Equal => return Some(&mut r.value) - } - } - None => return None - } - } -} - -fn insert(node: &mut Option>>, - 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(box TreeNode::new(key, value)); - None - } - } -} - -fn remove(node: &mut Option>>, key: &Q) -> Option - where K: Ord, Q: BorrowFrom + Ord -{ - fn heir_swap(node: &mut Box>, - child: &mut Option>>) { - // *could* be done without recursion, but it won't borrow check - for x in child.iter_mut() { - 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); - } - } - } - - match *node { - None => { - return None; // bottom of tree - } - Some(ref mut save) => { - let (ret, rebalance) = match key.cmp(BorrowFrom::borrow_from(&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); - } else { - swap(&mut save.key, &mut left.key); - swap(&mut save.value, &mut left.value); - } - save.left = Some(left); - (remove(&mut save.left, key), true) - } else { - let new = save.left.take().unwrap(); - let box 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 box TreeNode{value, ..} = replace(save, new); - (Some(value), true) - } else { - (None, false) - } - } - }; - - if rebalance { - let left_level = save.left.as_ref().map_or(0, |x| x.level); - let right_level = save.right.as_ref().map_or(0, |x| x.level); - - // re-balance, if necessary - if left_level < save.level - 1 || right_level < save.level - 1 { - save.level -= 1; - - if right_level > save.level { - let save_level = save.level; - for x in save.right.iter_mut() { x.level = save_level } - } - - skew(save); - - for right in save.right.iter_mut() { - skew(right); - for x in right.right.iter_mut() { skew(x) } - } - - split(save); - for x in save.right.iter_mut() { split(x) } - } - - return ret; - } - } - } - return match node.take() { - Some(box TreeNode{value, ..}) => Some(value), None => panic!() - }; -} - -impl FromIterator<(K, V)> for TreeMap { - fn from_iter>(iter: T) -> TreeMap { - let mut map = TreeMap::new(); - map.extend(iter); - map - } -} - -impl Extend<(K, V)> for TreeMap { - #[inline] - fn extend>(&mut self, mut iter: T) { - for (k, v) in iter { - self.insert(k, v); - } - } -} - -impl, V: Hash> Hash for TreeMap { - fn hash(&self, state: &mut S) { - for elt in self.iter() { - elt.hash(state); - } - } -} - - -#[cfg(test)] -mod test_treemap { - use std::prelude::*; - use std::rand::Rng; - use std::rand; - - use super::{TreeMap, TreeNode}; - - #[test] - fn find_empty() { - let m: TreeMap = TreeMap::new(); - assert!(m.get(&5) == None); - } - - #[test] - fn find_not_found() { - let mut m = TreeMap::new(); - assert!(m.insert(1i, 2i).is_none()); - assert!(m.insert(5i, 3i).is_none()); - assert!(m.insert(9i, 3i).is_none()); - assert_eq!(m.get(&2), None); - } - - #[test] - fn find_with_empty() { - let m: TreeMap<&'static str,int> = TreeMap::new(); - assert!(m.find_with(|&k| "test".cmp(k)) == None); - } - - #[test] - fn find_with_not_found() { - let mut m = TreeMap::new(); - assert!(m.insert("test1", 2i).is_none()); - assert!(m.insert("test2", 3i).is_none()); - assert!(m.insert("test3", 3i).is_none()); - assert_eq!(m.find_with(|&k| "test4".cmp(k)), None); - } - - #[test] - fn find_with_found() { - let mut m = TreeMap::new(); - assert!(m.insert("test1", 2i).is_none()); - assert!(m.insert("test2", 3i).is_none()); - assert!(m.insert("test3", 4i).is_none()); - assert_eq!(m.find_with(|&k| "test2".cmp(k)), Some(&3i)); - } - - #[test] - fn test_find_mut() { - let mut m = TreeMap::new(); - assert!(m.insert(1i, 12i).is_none()); - assert!(m.insert(2, 8).is_none()); - assert!(m.insert(5, 14).is_none()); - let new = 100; - match m.get_mut(&5) { - None => panic!(), Some(x) => *x = new - } - assert_eq!(m.get(&5), Some(&new)); - } - - #[test] - fn test_find_with_mut() { - let mut m = TreeMap::new(); - assert!(m.insert("t1", 12i).is_none()); - assert!(m.insert("t2", 8).is_none()); - assert!(m.insert("t5", 14).is_none()); - let new = 100; - - match m.find_with_mut(|&k| "t5".cmp(k)) { - None => panic!(), Some(x) => *x = new - } - assert_eq!(m.find_with(|&k| "t5".cmp(k)), Some(&new)); - } - - #[test] - fn insert_replace() { - let mut m = TreeMap::new(); - assert!(m.insert(5i, 2i).is_none()); - assert!(m.insert(2, 9).is_none()); - assert!(!m.insert(2, 11).is_none()); - assert_eq!(m.get(&2).unwrap(), &11); - } - - #[test] - fn test_clear() { - let mut m = TreeMap::new(); - m.clear(); - assert!(m.insert(5i, 11i).is_none()); - assert!(m.insert(12, -3).is_none()); - assert!(m.insert(19, 2).is_none()); - m.clear(); - assert!(m.get(&5).is_none()); - assert!(m.get(&12).is_none()); - assert!(m.get(&19).is_none()); - assert!(m.is_empty()); - } - - #[test] - fn u8_map() { - let mut m = TreeMap::new(); - - let k1 = "foo".as_bytes(); - let k2 = "bar".as_bytes(); - let v1 = "baz".as_bytes(); - let v2 = "foobar".as_bytes(); - - m.insert(k1.clone(), v1.clone()); - m.insert(k2.clone(), v2.clone()); - - assert_eq!(m.get(&k2), Some(&v2)); - assert_eq!(m.get(&k1), Some(&v1)); - } - - 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.get(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); - } - } - - fn check_left(node: &Option>>, - parent: &Box>) { - 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 - } - } - - fn check_right(node: &Option>>, - parent: &Box>, - 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 - } - } - - 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_rand_int() { - let mut map: TreeMap = TreeMap::new(); - let mut ctrl = vec![]; - - check_equal(ctrl.as_slice(), &map); - assert!(map.get(&5).is_none()); - - let seed: &[_] = &[42]; - let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed); - - for _ in range(0u, 3) { - for _ in range(0u, 90) { - let k = rng.gen(); - let v = rng.gen(); - if !ctrl.iter().any(|x| x == &(k, v)) { - assert!(map.insert(k, v).is_none()); - ctrl.push((k, v)); - check_structure(&map); - check_equal(ctrl.as_slice(), &map); - } - } - - for _ in range(0u, 30) { - let r = rng.gen_range(0, ctrl.len()); - let (key, _) = ctrl.remove(r).unwrap(); - assert!(map.remove(&key).is_some()); - check_structure(&map); - check_equal(ctrl.as_slice(), &map); - } - } - } - - #[test] - fn test_len() { - let mut m = TreeMap::new(); - assert!(m.insert(3i, 6i).is_none()); - assert_eq!(m.len(), 1); - assert!(m.insert(0, 0).is_none()); - assert_eq!(m.len(), 2); - assert!(m.insert(4, 8).is_none()); - assert_eq!(m.len(), 3); - assert!(m.remove(&3).is_some()); - assert_eq!(m.len(), 2); - assert!(!m.remove(&5).is_some()); - assert_eq!(m.len(), 2); - assert!(m.insert(2, 4).is_none()); - assert_eq!(m.len(), 3); - assert!(m.insert(1, 2).is_none()); - assert_eq!(m.len(), 4); - } - - #[test] - fn test_iterator() { - let mut m = TreeMap::new(); - - assert!(m.insert(3i, 6i).is_none()); - assert!(m.insert(0, 0).is_none()); - assert!(m.insert(4, 8).is_none()); - assert!(m.insert(2, 4).is_none()); - assert!(m.insert(1, 2).is_none()); - - 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_interval_iteration() { - let mut m = TreeMap::new(); - for i in range(1i, 100i) { - assert!(m.insert(i * 2, i * 4).is_none()); - } - - for i in range(1i, 198i) { - let mut lb_it = m.lower_bound(&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(&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(&199); - assert_eq!(end_it.next(), None); - } - - #[test] - fn test_rev_iter() { - let mut m = TreeMap::new(); - - assert!(m.insert(3i, 6i).is_none()); - assert!(m.insert(0, 0).is_none()); - assert!(m.insert(4, 8).is_none()); - assert!(m.insert(2, 4).is_none()); - assert!(m.insert(1, 2).is_none()); - - 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_mut_iter() { - let mut m = TreeMap::new(); - for i in range(0u, 10) { - assert!(m.insert(i, 100 * i).is_none()); - } - - for (i, (&k, v)) in m.iter_mut().enumerate() { - *v += k * 10 + i; // 000 + 00 + 0, 100 + 10 + 1, ... - } - - for (&k, &v) in m.iter() { - assert_eq!(v, 111 * k); - } - } - #[test] - fn test_mut_rev_iter() { - let mut m = TreeMap::new(); - for i in range(0u, 10) { - assert!(m.insert(i, 100 * i).is_none()); - } - - for (i, (&k, v)) in m.rev_iter_mut().enumerate() { - *v += k * 10 + (9 - i); // 900 + 90 + (9 - 0), 800 + 80 + (9 - 1), ... - } - - for (&k, &v) in m.iter() { - assert_eq!(v, 111 * k); - } - } - - #[test] - fn test_mut_interval_iter() { - let mut m_lower = TreeMap::new(); - let mut m_upper = TreeMap::new(); - for i in range(1i, 100i) { - assert!(m_lower.insert(i * 2, i * 4).is_none()); - assert!(m_upper.insert(i * 2, i * 4).is_none()); - } - - for i in range(1i, 199) { - let mut lb_it = m_lower.lower_bound_mut(&i); - let (&k, v) = lb_it.next().unwrap(); - let lb = i + i % 2; - assert_eq!(lb, k); - *v -= k; - } - for i in range(0i, 198) { - let mut ub_it = m_upper.upper_bound_mut(&i); - let (&k, v) = ub_it.next().unwrap(); - let ub = i + 2 - i % 2; - assert_eq!(ub, k); - *v -= k; - } - - assert!(m_lower.lower_bound_mut(&199).next().is_none()); - - assert!(m_upper.upper_bound_mut(&198).next().is_none()); - - assert!(m_lower.iter().all(|(_, &x)| x == 0)); - assert!(m_upper.iter().all(|(_, &x)| x == 0)); - } - - #[test] - fn test_keys() { - let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')]; - let map = vec.into_iter().collect::>(); - let keys = map.keys().map(|&k| k).collect::>(); - assert_eq!(keys.len(), 3); - assert!(keys.contains(&1)); - assert!(keys.contains(&2)); - assert!(keys.contains(&3)); - } - - #[test] - fn test_values() { - let vec = vec![(1i, 'a'), (2i, 'b'), (3i, 'c')]; - let map = vec.into_iter().collect::>(); - let values = map.values().map(|&v| v).collect::>(); - assert_eq!(values.len(), 3); - assert!(values.contains(&'a')); - assert!(values.contains(&'b')); - assert!(values.contains(&'c')); - } - - #[test] - fn test_eq() { - let mut a = TreeMap::new(); - let mut b = TreeMap::new(); - - assert!(a == b); - assert!(a.insert(0i, 5i).is_none()); - assert!(a != b); - assert!(b.insert(0, 4).is_none()); - assert!(a != b); - assert!(a.insert(5, 19).is_none()); - assert!(a != b); - assert!(!b.insert(0, 5).is_none()); - assert!(a != b); - assert!(b.insert(5, 19).is_none()); - assert!(a == b); - } - - #[test] - fn test_lt() { - let mut a = TreeMap::new(); - let mut b = TreeMap::new(); - - assert!(!(a < b) && !(b < a)); - assert!(b.insert(0i, 5i).is_none()); - assert!(a < b); - assert!(a.insert(0, 7).is_none()); - assert!(!(a < b) && b < a); - assert!(b.insert(-2, 0).is_none()); - assert!(b < a); - assert!(a.insert(-5, 2).is_none()); - assert!(a < b); - assert!(a.insert(6, 2).is_none()); - assert!(a < b && !(b < a)); - } - - #[test] - fn test_ord() { - let mut a = TreeMap::new(); - let mut b = TreeMap::new(); - - assert!(a <= b && a >= b); - assert!(a.insert(1i, 1i).is_none()); - assert!(a > b && a >= b); - assert!(b < a && b <= a); - assert!(b.insert(2, 2).is_none()); - assert!(b > a && b >= a); - assert!(a < b && a <= b); - } - - #[test] - fn test_show() { - let mut map: TreeMap = TreeMap::new(); - let empty: TreeMap = TreeMap::new(); - - map.insert(1, 2); - map.insert(3, 4); - - let map_str = format!("{}", map); - - assert!(map_str == "{1: 2, 3: 4}"); - assert_eq!(format!("{}", empty), "{}"); - } - - #[test] - fn test_lazy_iterator() { - let mut m = TreeMap::new(); - let (x1, y1) = (2i, 5i); - 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).is_none()); - assert!(m.insert(x2, y2).is_none()); - assert!(m.insert(x3, y3).is_none()); - assert!(m.insert(x4, y4).is_none()); - assert!(m.insert(x5, y5).is_none()); - - 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 - } - } - - for x in b { - assert_eq!(expected[i], x); - i += 1; - } - } - - #[test] - fn test_from_iter() { - let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; - - let map: TreeMap = xs.iter().map(|&x| x).collect(); - - for &(k, v) in xs.iter() { - assert_eq!(map.get(&k), Some(&v)); - } - } - - #[test] - fn test_index() { - let mut map: TreeMap = TreeMap::new(); - - map.insert(1, 2); - map.insert(2, 1); - map.insert(3, 4); - - assert_eq!(map[2], 1); - } - - #[test] - #[should_fail] - fn test_index_nonexistent() { - let mut map: TreeMap = TreeMap::new(); - - map.insert(1, 2); - map.insert(2, 1); - map.insert(3, 4); - - map[4]; - } - - #[test] - fn test_swap() { - let mut m = TreeMap::new(); - assert_eq!(m.insert(1u, 2i), None); - assert_eq!(m.insert(1u, 3i), Some(2)); - assert_eq!(m.insert(1u, 4i), Some(3)); - } - - #[test] - fn test_pop() { - let mut m = TreeMap::new(); - m.insert(1u, 2i); - assert_eq!(m.remove(&1), Some(2)); - assert_eq!(m.remove(&1), None); - } -} - -#[cfg(test)] -mod bench { - use std::prelude::*; - use std::rand::{weak_rng, Rng}; - use test::{Bencher, black_box}; - - use super::TreeMap; - use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n}; - - #[bench] - pub fn insert_rand_100(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - insert_rand_n(100, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.remove(&i); }); - } - - #[bench] - pub fn insert_rand_10_000(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - insert_rand_n(10_000, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.remove(&i); }); - } - - // Insert seq - #[bench] - pub fn insert_seq_100(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - insert_seq_n(100, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.remove(&i); }); - } - - #[bench] - pub fn insert_seq_10_000(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - insert_seq_n(10_000, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.remove(&i); }); - } - - // Find rand - #[bench] - pub fn find_rand_100(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - find_rand_n(100, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.get(&i); }); - } - - #[bench] - pub fn find_rand_10_000(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - find_rand_n(10_000, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.get(&i); }); - } - - // Find seq - #[bench] - pub fn find_seq_100(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - find_seq_n(100, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.get(&i); }); - } - - #[bench] - pub fn find_seq_10_000(b: &mut Bencher) { - let mut m : TreeMap = TreeMap::new(); - find_seq_n(10_000, &mut m, b, - |m, i| { m.insert(i, 1); }, - |m, i| { m.get(&i); }); - } - - fn bench_iter(b: &mut Bencher, size: uint) { - let mut map = TreeMap::::new(); - let mut rng = weak_rng(); - - for _ in range(0, size) { - map.insert(rng.gen(), rng.gen()); - } - - b.iter(|| { - for entry in map.iter() { - black_box(entry); - } - }); - } - - #[bench] - pub fn iter_20(b: &mut Bencher) { - bench_iter(b, 20); - } - - #[bench] - pub fn iter_1000(b: &mut Bencher) { - bench_iter(b, 1000); - } - - #[bench] - pub fn iter_100000(b: &mut Bencher) { - bench_iter(b, 100000); - } -} diff --git a/src/libcollections/tree/mod.rs b/src/libcollections/tree/mod.rs deleted file mode 100644 index 8c8a2c2f78ee9..0000000000000 --- a/src/libcollections/tree/mod.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Maps are collections of unique keys with corresponding values, and sets are -//! just unique keys without a corresponding value. -//! -//! This crate defines the `TreeMap` and `TreeSet` types. Their keys must implement `Ord`. -//! -//! `TreeMap`s are ordered. -//! -//! # Examples -//! -//! ```{rust} -//! use std::collections::TreeSet; -//! -//! let mut tree_set = TreeSet::new(); -//! -//! tree_set.insert(2i); -//! tree_set.insert(1i); -//! tree_set.insert(3i); -//! -//! for i in tree_set.iter() { -//! println!("{}", i) // prints 1, then 2, then 3 -//! } -//! ``` - -pub mod map; -pub mod set; diff --git a/src/libcollections/tree/set.rs b/src/libcollections/tree/set.rs deleted file mode 100644 index c3aebc2736c96..0000000000000 --- a/src/libcollections/tree/set.rs +++ /dev/null @@ -1,1218 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use core::prelude::*; - -use core::borrow::BorrowFrom; -use core::default::Default; -use core::fmt; -use core::fmt::Show; -use core::iter::Peekable; -use core::iter; -use std::hash::{Writer, Hash}; - -use tree_map::{TreeMap, Entries, RevEntries, MoveEntries}; - -// FIXME(conventions): implement bounded iterators -// FIXME(conventions): replace rev_iter(_mut) by making iter(_mut) DoubleEnded - -/// An implementation of a set on top of the `TreeMap` container. The only -/// requirement is that the type of the elements contained ascribes to the -/// `Ord` trait. -/// -/// # Examples -/// -/// ```{rust} -/// use std::collections::TreeSet; -/// -/// let mut set = TreeSet::new(); -/// -/// set.insert(2i); -/// set.insert(1i); -/// set.insert(3i); -/// -/// for i in set.iter() { -/// println!("{}", i) // prints 1, then 2, then 3 -/// } -/// -/// set.remove(&3); -/// -/// if !set.contains(&3) { -/// println!("set does not contain a 3 anymore"); -/// } -/// ``` -/// -/// The easiest way to use `TreeSet` with a custom type is to implement `Ord`. -/// We must also implement `PartialEq`, `Eq` and `PartialOrd`. -/// -/// ``` -/// use std::collections::TreeSet; -/// -/// // We need `Eq` and `PartialEq`, these can be derived. -/// #[deriving(Eq, PartialEq)] -/// struct Troll<'a> { -/// name: &'a str, -/// level: uint, -/// } -/// -/// // Implement `Ord` and sort trolls by level. -/// impl<'a> Ord for Troll<'a> { -/// fn cmp(&self, other: &Troll) -> Ordering { -/// // If we swap `self` and `other`, we get descending ordering. -/// self.level.cmp(&other.level) -/// } -/// } -/// -/// // `PartialOrd` needs to be implemented as well. -/// impl<'a> PartialOrd for Troll<'a> { -/// fn partial_cmp(&self, other: &Troll) -> Option { -/// Some(self.cmp(other)) -/// } -/// } -/// -/// let mut trolls = TreeSet::new(); -/// -/// trolls.insert(Troll { name: "Orgarr", level: 2 }); -/// trolls.insert(Troll { name: "Blargarr", level: 3 }); -/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 }); -/// trolls.insert(Troll { name: "Wartilda", level: 1 }); -/// -/// println!("You are facing {} trolls!", trolls.len()); -/// -/// // Print the trolls, ordered by level with smallest level first -/// for x in trolls.iter() { -/// println!("level {}: {}!", x.level, x.name); -/// } -/// -/// // Kill all trolls -/// trolls.clear(); -/// assert_eq!(trolls.len(), 0); -/// ``` -#[deriving(Clone)] -pub struct TreeSet { - map: TreeMap -} - -impl PartialEq for TreeSet { - #[inline] - fn eq(&self, other: &TreeSet) -> bool { self.map == other.map } -} - -impl Eq for TreeSet {} - -impl PartialOrd for TreeSet { - #[inline] - fn partial_cmp(&self, other: &TreeSet) -> Option { - self.map.partial_cmp(&other.map) - } -} - -impl Ord for TreeSet { - #[inline] - fn cmp(&self, other: &TreeSet) -> Ordering { - iter::order::cmp(self.iter(), other.iter()) - } -} - -impl Show for TreeSet { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, x) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{}", *x)); - } - - write!(f, "}}") - } -} - -#[stable] -impl Default for TreeSet { - #[inline] - #[stable] - fn default() -> TreeSet { TreeSet::new() } -} - -impl TreeSet { - /// Creates an empty `TreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// let mut set: TreeSet = TreeSet::new(); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } - - /// Gets a lazy iterator over the values in the set, in ascending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// let set: TreeSet = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect(); - /// - /// // Will print in ascending order. - /// for x in set.iter() { - /// println!("{}", x); - /// } - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn iter<'a>(&'a self) -> SetItems<'a, T> { - SetItems{iter: self.map.iter()} - } - - /// Gets a lazy iterator over the values in the set, in descending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// let set: TreeSet = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect(); - /// - /// // Will print in descending order. - /// for x in set.rev_iter() { - /// println!("{}", x); - /// } - /// ``` - #[inline] - pub fn rev_iter<'a>(&'a self) -> RevSetItems<'a, T> { - RevSetItems{iter: self.map.rev_iter()} - } - - /// Creates a consuming iterator, that is, one that moves each value out of the - /// set in ascending order. The set cannot be used after calling this. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// let set: TreeSet = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect(); - /// - /// // Not possible with a regular `.iter()` - /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![1, 2, 3, 4, 5]); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn into_iter(self) -> MoveSetItems { - fn first((a, _): (A, B)) -> A { a } - - self.map.into_iter().map(first) - } - - /// Gets a lazy iterator pointing to the first value not less than `v` (greater or equal). - /// If all elements in the set are less than `v` empty iterator is returned. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// let set: TreeSet = [2, 4, 6, 8].iter().map(|&x| x).collect(); - /// - /// assert_eq!(set.lower_bound(&4).next(), Some(&4)); - /// assert_eq!(set.lower_bound(&5).next(), Some(&6)); - /// assert_eq!(set.lower_bound(&10).next(), None); - /// ``` - #[inline] - pub fn lower_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> { - SetItems{iter: self.map.lower_bound(v)} - } - - /// Gets a lazy iterator pointing to the first value greater than `v`. - /// If all elements in the set are less than or equal to `v` an - /// empty iterator is returned. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// let set: TreeSet = [2, 4, 6, 8].iter().map(|&x| x).collect(); - /// - /// assert_eq!(set.upper_bound(&4).next(), Some(&6)); - /// assert_eq!(set.upper_bound(&5).next(), Some(&6)); - /// assert_eq!(set.upper_bound(&10).next(), None); - /// ``` - #[inline] - pub fn upper_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> { - SetItems{iter: self.map.upper_bound(v)} - } - - /// Visits the values representing the difference, in ascending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); - /// - /// // Can be seen as `a - b`. - /// for x in a.difference(&b) { - /// println!("{}", x); // Print 1 then 2 - /// } - /// - /// let diff: TreeSet = a.difference(&b).map(|&x| x).collect(); - /// assert_eq!(diff, [1, 2].iter().map(|&x| x).collect()); - /// - /// // Note that difference is not symmetric, - /// // and `b - a` means something else: - /// let diff: TreeSet = b.difference(&a).map(|&x| x).collect(); - /// assert_eq!(diff, [4, 5].iter().map(|&x| x).collect()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn difference<'a>(&'a self, other: &'a TreeSet) -> DifferenceItems<'a, T> { - DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Visits the values representing the symmetric difference, in ascending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); - /// - /// // Print 1, 2, 4, 5 in ascending order. - /// for x in a.symmetric_difference(&b) { - /// println!("{}", x); - /// } - /// - /// let diff1: TreeSet = a.symmetric_difference(&b).map(|&x| x).collect(); - /// let diff2: TreeSet = b.symmetric_difference(&a).map(|&x| x).collect(); - /// - /// assert_eq!(diff1, diff2); - /// assert_eq!(diff1, [1, 2, 4, 5].iter().map(|&x| x).collect()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet) - -> SymDifferenceItems<'a, T> { - SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Visits the values representing the intersection, in ascending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TreeSet = [2, 3, 4].iter().map(|&x| x).collect(); - /// - /// // Print 2, 3 in ascending order. - /// for x in a.intersection(&b) { - /// println!("{}", x); - /// } - /// - /// let diff: TreeSet = a.intersection(&b).map(|&x| x).collect(); - /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn intersection<'a>(&'a self, other: &'a TreeSet) - -> IntersectionItems<'a, T> { - IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Visits the values representing the union, in ascending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); - /// - /// // Print 1, 2, 3, 4, 5 in ascending order. - /// for x in a.union(&b) { - /// println!("{}", x); - /// } - /// - /// let diff: TreeSet = a.union(&b).map(|&x| x).collect(); - /// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn union<'a>(&'a self, other: &'a TreeSet) -> UnionItems<'a, T> { - UnionItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Return the number of elements in the set - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let mut v = TreeSet::new(); - /// assert_eq!(v.len(), 0); - /// v.insert(1i); - /// assert_eq!(v.len(), 1); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn len(&self) -> uint { self.map.len() } - - /// Returns true if the set contains no elements - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let mut v = TreeSet::new(); - /// assert!(v.is_empty()); - /// v.insert(1i); - /// assert!(!v.is_empty()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn is_empty(&self) -> bool { self.len() == 0 } - - /// Clears the set, removing all values. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let mut v = TreeSet::new(); - /// v.insert(1i); - /// v.clear(); - /// assert!(v.is_empty()); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn clear(&mut self) { self.map.clear() } - - /// Returns `true` if the set contains a value. - /// - /// The value may be any borrowed form of the set's value type, - /// but the ordering on the borrowed form *must* match the - /// ordering on the value type. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let set: TreeSet = [1i, 2, 3].iter().map(|&x| x).collect(); - /// assert_eq!(set.contains(&1), true); - /// assert_eq!(set.contains(&4), false); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains(&self, value: &Q) -> bool - where Q: Ord + BorrowFrom - { - self.map.contains_key(value) - } - - /// Returns `true` if the set has no elements in common with `other`. - /// This is equivalent to checking for an empty intersection. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = [1i, 2, 3].iter().map(|&x| x).collect(); - /// let mut b: TreeSet = TreeSet::new(); - /// - /// assert_eq!(a.is_disjoint(&b), true); - /// b.insert(4); - /// assert_eq!(a.is_disjoint(&b), true); - /// b.insert(1); - /// assert_eq!(a.is_disjoint(&b), false); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn is_disjoint(&self, other: &TreeSet) -> bool { - self.intersection(other).next().is_none() - } - - /// Returns `true` if the set is a subset of another. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let sup: TreeSet = [1i, 2, 3].iter().map(|&x| x).collect(); - /// let mut set: TreeSet = TreeSet::new(); - /// - /// assert_eq!(set.is_subset(&sup), true); - /// set.insert(2); - /// assert_eq!(set.is_subset(&sup), true); - /// set.insert(4); - /// assert_eq!(set.is_subset(&sup), false); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn is_subset(&self, other: &TreeSet) -> bool { - let mut x = self.iter(); - let mut y = other.iter(); - let mut a = x.next(); - let mut b = y.next(); - while a.is_some() { - if b.is_none() { - return false; - } - - let a1 = a.unwrap(); - let b1 = b.unwrap(); - - match b1.cmp(a1) { - Less => (), - Greater => return false, - Equal => a = x.next(), - } - - b = y.next(); - } - true - } - - /// Returns `true` if the set is a superset of another. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let sub: TreeSet = [1i, 2].iter().map(|&x| x).collect(); - /// let mut set: TreeSet = TreeSet::new(); - /// - /// assert_eq!(set.is_superset(&sub), false); - /// - /// set.insert(0); - /// set.insert(1); - /// assert_eq!(set.is_superset(&sub), false); - /// - /// set.insert(2); - /// assert_eq!(set.is_superset(&sub), true); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn is_superset(&self, other: &TreeSet) -> bool { - other.is_subset(self) - } - - /// Adds a value to the set. Returns `true` if the value was not already - /// present in the set. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let mut set = TreeSet::new(); - /// - /// assert_eq!(set.insert(2i), true); - /// assert_eq!(set.insert(2i), false); - /// assert_eq!(set.len(), 1); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() } - - /// Removes a value from the set. Returns `true` if the value was - /// present in the set. - /// - /// The value may be any borrowed form of the set's value type, - /// but the ordering on the borrowed form *must* match the - /// ordering on the value type. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let mut set = TreeSet::new(); - /// - /// set.insert(2i); - /// assert_eq!(set.remove(&2), true); - /// assert_eq!(set.remove(&2), false); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, value: &Q) -> bool - where Q: Ord + BorrowFrom - { - self.map.remove(value).is_some() - } -} - -/// A lazy forward iterator over a set. -pub struct SetItems<'a, T:'a> { - iter: Entries<'a, T, ()> -} - -/// A lazy backward iterator over a set. -pub struct RevSetItems<'a, T:'a> { - iter: RevEntries<'a, T, ()> -} - -/// A lazy forward iterator over a set that consumes the set while iterating. -pub type MoveSetItems = iter::Map<(T, ()), T, MoveEntries, fn((T, ())) -> T>; - -/// A lazy iterator producing elements in the set difference (in-order). -pub struct DifferenceItems<'a, T:'a> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, -} - -/// A lazy iterator producing elements in the set symmetric difference (in-order). -pub struct SymDifferenceItems<'a, T:'a> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, -} - -/// A lazy iterator producing elements in the set intersection (in-order). -pub struct IntersectionItems<'a, T:'a> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, -} - -/// A lazy iterator producing elements in the set union (in-order). -pub struct UnionItems<'a, T:'a> { - a: Peekable<&'a T, SetItems<'a, T>>, - b: Peekable<&'a T, SetItems<'a, T>>, -} - -/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None -fn cmp_opt(x: Option<&T>, y: Option<&T>, - short: Ordering, long: Ordering) -> Ordering { - match (x, y) { - (None , _ ) => short, - (_ , None ) => long, - (Some(x1), Some(y1)) => x1.cmp(y1), - } -} - - -impl<'a, T> Iterator<&'a T> for SetItems<'a, T> { - #[inline] - fn next(&mut self) -> Option<&'a T> { - self.iter.next().map(|(value, _)| value) - } -} - -impl<'a, T> Iterator<&'a T> for RevSetItems<'a, T> { - #[inline] - fn next(&mut self) -> Option<&'a T> { - self.iter.next().map(|(value, _)| value) - } -} - -impl<'a, T: Ord> Iterator<&'a T> for DifferenceItems<'a, T> { - fn next(&mut self) -> Option<&'a T> { - loop { - match cmp_opt(self.a.peek(), self.b.peek(), Less, Less) { - Less => return self.a.next(), - Equal => { self.a.next(); self.b.next(); } - Greater => { self.b.next(); } - } - } - } -} - -impl<'a, T: Ord> Iterator<&'a T> for SymDifferenceItems<'a, T> { - fn next(&mut self) -> Option<&'a T> { - loop { - match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) { - Less => return self.a.next(), - Equal => { self.a.next(); self.b.next(); } - Greater => return self.b.next(), - } - } - } -} - -impl<'a, T: Ord> Iterator<&'a T> for IntersectionItems<'a, T> { - fn next(&mut self) -> Option<&'a T> { - loop { - let o_cmp = match (self.a.peek(), self.b.peek()) { - (None , _ ) => None, - (_ , None ) => None, - (Some(a1), Some(b1)) => Some(a1.cmp(b1)), - }; - match o_cmp { - None => return None, - Some(Less) => { self.a.next(); } - Some(Equal) => { self.b.next(); return self.a.next() } - Some(Greater) => { self.b.next(); } - } - } - } -} - -impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> { - fn next(&mut self) -> Option<&'a T> { - loop { - match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) { - Less => return self.a.next(), - Equal => { self.b.next(); return self.a.next() } - Greater => return self.b.next(), - } - } - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl BitOr, TreeSet> for TreeSet { - /// Returns the union of `self` and `rhs` as a new `TreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TreeSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TreeSet = a | b; - /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![1, 2, 3, 4, 5]); - /// ``` - fn bitor(&self, rhs: &TreeSet) -> TreeSet { - self.union(rhs).cloned().collect() - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot -impl<'a, 'b, T: Ord + Clone> BitOr<&'b TreeSet, TreeSet> for &'a TreeSet { - /// Returns the union of `self` and `rhs` as a new `TreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TreeSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TreeSet = &a | &b; - /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![1, 2, 3, 4, 5]); - /// ``` - fn bitor(self, rhs: &TreeSet) -> TreeSet { - self.union(rhs).cloned().collect() - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl BitAnd, TreeSet> for TreeSet { - /// Returns the intersection of `self` and `rhs` as a new `TreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TreeSet = vec![2, 3, 4].into_iter().collect(); - /// - /// let set: TreeSet = a & b; - /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![2, 3]); - /// ``` - fn bitand(&self, rhs: &TreeSet) -> TreeSet { - self.intersection(rhs).cloned().collect() - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot -impl<'a, 'b, T: Ord + Clone> BitAnd<&'b TreeSet, TreeSet> for &'a TreeSet { - /// Returns the intersection of `self` and `rhs` as a new `TreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TreeSet = vec![2, 3, 4].into_iter().collect(); - /// - /// let set: TreeSet = &a & &b; - /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![2, 3]); - /// ``` - fn bitand(self, rhs: &TreeSet) -> TreeSet { - self.intersection(rhs).cloned().collect() - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl BitXor, TreeSet> for TreeSet { - /// Returns the symmetric difference of `self` and `rhs` as a new `TreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TreeSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TreeSet = a ^ b; - /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![1, 2, 4, 5]); - /// ``` - fn bitxor(&self, rhs: &TreeSet) -> TreeSet { - self.symmetric_difference(rhs).cloned().collect() - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot -impl<'a, 'b, T: Ord + Clone> BitXor<&'b TreeSet, TreeSet> for &'a TreeSet { - /// Returns the symmetric difference of `self` and `rhs` as a new `TreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TreeSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TreeSet = &a ^ &b; - /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![1, 2, 4, 5]); - /// ``` - fn bitxor(self, rhs: &TreeSet) -> TreeSet { - self.symmetric_difference(rhs).cloned().collect() - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -impl Sub, TreeSet> for TreeSet { - /// Returns the difference of `self` and `rhs` as a new `TreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TreeSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TreeSet = a - b; - /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![1, 2]); - /// ``` - fn sub(&self, rhs: &TreeSet) -> TreeSet { - self.difference(rhs).cloned().collect() - } -} - -#[unstable = "matches collection reform specification, waiting for dust to settle"] -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot -impl<'a, 'b, T: Ord + Clone> Sub<&'b TreeSet, TreeSet> for &'a TreeSet { - /// Returns the difference of `self` and `rhs` as a new `TreeSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TreeSet; - /// - /// let a: TreeSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TreeSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TreeSet = &a - &b; - /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![1, 2]); - /// ``` - fn sub(self, rhs: &TreeSet) -> TreeSet { - self.difference(rhs).cloned().collect() - } -} - -impl FromIterator for TreeSet { - fn from_iter>(iter: Iter) -> TreeSet { - let mut set = TreeSet::new(); - set.extend(iter); - set - } -} - -impl Extend for TreeSet { - #[inline] - fn extend>(&mut self, mut iter: Iter) { - for elem in iter { - self.insert(elem); - } - } -} - -impl> Hash for TreeSet { - fn hash(&self, state: &mut S) { - for elt in self.iter() { - elt.hash(state); - } - } -} - -#[cfg(test)] -mod test { - use std::prelude::*; - use std::hash; - use vec::Vec; - - use super::TreeSet; - - #[test] - fn test_clear() { - let mut s = TreeSet::new(); - s.clear(); - assert!(s.insert(5i)); - assert!(s.insert(12)); - assert!(s.insert(19)); - s.clear(); - assert!(!s.contains(&5)); - assert!(!s.contains(&12)); - assert!(!s.contains(&19)); - assert!(s.is_empty()); - } - - #[test] - fn test_disjoint() { - let mut xs = TreeSet::new(); - let mut ys = TreeSet::new(); - assert!(xs.is_disjoint(&ys)); - assert!(ys.is_disjoint(&xs)); - assert!(xs.insert(5i)); - assert!(ys.insert(11i)); - assert!(xs.is_disjoint(&ys)); - assert!(ys.is_disjoint(&xs)); - assert!(xs.insert(7)); - assert!(xs.insert(19)); - assert!(xs.insert(4)); - assert!(ys.insert(2)); - assert!(ys.insert(-11)); - assert!(xs.is_disjoint(&ys)); - assert!(ys.is_disjoint(&xs)); - assert!(ys.insert(7)); - assert!(!xs.is_disjoint(&ys)); - assert!(!ys.is_disjoint(&xs)); - } - - #[test] - fn test_subset_and_superset() { - let mut a = TreeSet::new(); - assert!(a.insert(0i)); - assert!(a.insert(5)); - assert!(a.insert(11)); - assert!(a.insert(7)); - - let mut b = TreeSet::new(); - assert!(b.insert(0i)); - assert!(b.insert(7)); - assert!(b.insert(19)); - assert!(b.insert(250)); - assert!(b.insert(11)); - assert!(b.insert(200)); - - assert!(!a.is_subset(&b)); - assert!(!a.is_superset(&b)); - assert!(!b.is_subset(&a)); - assert!(!b.is_superset(&a)); - - assert!(b.insert(5)); - - assert!(a.is_subset(&b)); - assert!(!a.is_superset(&b)); - assert!(!b.is_subset(&a)); - assert!(b.is_superset(&a)); - } - - #[test] - fn test_iterator() { - let mut m = TreeSet::new(); - - assert!(m.insert(3i)); - assert!(m.insert(0)); - assert!(m.insert(4)); - assert!(m.insert(2)); - assert!(m.insert(1)); - - let mut n = 0; - for x in m.iter() { - assert_eq!(*x, n); - n += 1 - } - } - - #[test] - fn test_rev_iter() { - let mut m = TreeSet::new(); - - assert!(m.insert(3i)); - assert!(m.insert(0)); - assert!(m.insert(4)); - assert!(m.insert(2)); - assert!(m.insert(1)); - - let mut n = 4; - for x in m.rev_iter() { - assert_eq!(*x, n); - n -= 1; - } - } - - #[test] - fn test_move_iter() { - let s: TreeSet = range(0i, 5).collect(); - - let mut n = 0; - for x in s.into_iter() { - assert_eq!(x, n); - n += 1; - } - } - - #[test] - fn test_move_iter_size_hint() { - let s: TreeSet = vec!(0i, 1).into_iter().collect(); - - let mut it = s.into_iter(); - - assert_eq!(it.size_hint(), (2, Some(2))); - assert!(it.next() != None); - - assert_eq!(it.size_hint(), (1, Some(1))); - assert!(it.next() != None); - - assert_eq!(it.size_hint(), (0, Some(0))); - assert_eq!(it.next(), None); - } - - #[test] - fn test_clone_eq() { - let mut m = TreeSet::new(); - - m.insert(1i); - m.insert(2); - - assert!(m.clone() == m); - } - - #[test] - fn test_hash() { - let mut x = TreeSet::new(); - let mut y = TreeSet::new(); - - x.insert(1i); - x.insert(2); - x.insert(3); - - y.insert(3i); - y.insert(2); - y.insert(1); - - assert!(hash::hash(&x) == hash::hash(&y)); - } - - struct Counter<'a, 'b> { - i: &'a mut uint, - expected: &'b [int], - } - - impl<'a, 'b> FnMut(&int) -> bool for Counter<'a, 'b> { - extern "rust-call" fn call_mut(&mut self, (&x,): (&int,)) -> bool { - assert_eq!(x, self.expected[*self.i]); - *self.i += 1; - true - } - } - - fn check(a: &[int], b: &[int], expected: &[int], f: F) where - // FIXME Replace `Counter` with `Box bool>` - F: FnOnce(&TreeSet, &TreeSet, Counter) -> bool, - { - let mut set_a = TreeSet::new(); - let mut set_b = TreeSet::new(); - - for x in a.iter() { assert!(set_a.insert(*x)) } - for y in b.iter() { assert!(set_b.insert(*y)) } - - let mut i = 0; - f(&set_a, &set_b, Counter { i: &mut i, expected: expected }); - assert_eq!(i, expected.len()); - } - - #[test] - fn test_intersection() { - fn check_intersection(a: &[int], b: &[int], expected: &[int]) { - check(a, b, expected, |x, y, f| x.intersection(y).all(f)) - } - - check_intersection(&[], &[], &[]); - check_intersection(&[1, 2, 3], &[], &[]); - check_intersection(&[], &[1, 2, 3], &[]); - check_intersection(&[2], &[1, 2, 3], &[2]); - check_intersection(&[1, 2, 3], &[2], &[2]); - check_intersection(&[11, 1, 3, 77, 103, 5, -5], - &[2, 11, 77, -9, -42, 5, 3], - &[3, 5, 11, 77]); - } - - #[test] - fn test_difference() { - fn check_difference(a: &[int], b: &[int], expected: &[int]) { - check(a, b, expected, |x, y, f| x.difference(y).all(f)) - } - - check_difference(&[], &[], &[]); - check_difference(&[1, 12], &[], &[1, 12]); - check_difference(&[], &[1, 2, 3, 9], &[]); - check_difference(&[1, 3, 5, 9, 11], - &[3, 9], - &[1, 5, 11]); - check_difference(&[-5, 11, 22, 33, 40, 42], - &[-12, -5, 14, 23, 34, 38, 39, 50], - &[11, 22, 33, 40, 42]); - } - - #[test] - fn test_symmetric_difference() { - fn check_symmetric_difference(a: &[int], b: &[int], - expected: &[int]) { - check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f)) - } - - check_symmetric_difference(&[], &[], &[]); - check_symmetric_difference(&[1, 2, 3], &[2], &[1, 3]); - check_symmetric_difference(&[2], &[1, 2, 3], &[1, 3]); - check_symmetric_difference(&[1, 3, 5, 9, 11], - &[-2, 3, 9, 14, 22], - &[-2, 1, 5, 11, 14, 22]); - } - - #[test] - fn test_union() { - fn check_union(a: &[int], b: &[int], - expected: &[int]) { - check(a, b, expected, |x, y, f| x.union(y).all(f)) - } - - check_union(&[], &[], &[]); - check_union(&[1, 2, 3], &[2], &[1, 2, 3]); - check_union(&[2], &[1, 2, 3], &[1, 2, 3]); - check_union(&[1, 3, 5, 9, 11, 16, 19, 24], - &[-2, 1, 5, 9, 13, 19], - &[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]); - } - - #[test] - fn test_bit_or() { - let a: TreeSet = vec![1, 3, 5, 9, 11, 16, 19, 24].into_iter().collect(); - let b: TreeSet = vec![-2, 1, 5, 9, 13, 19].into_iter().collect(); - - let set: TreeSet = &a | &b; - let v: Vec = set.into_iter().collect(); - assert_eq!(v, vec![-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]); - } - - #[test] - fn test_bit_and() { - let a: TreeSet = vec![11, 1, 3, 77, 103, 5, -5].into_iter().collect(); - let b: TreeSet = vec![2, 11, 77, -9, -42, 5, 3].into_iter().collect(); - - let set: TreeSet = &a & &b; - let v: Vec = set.into_iter().collect(); - assert_eq!(v, vec![3, 5, 11, 77]); - } - - #[test] - fn test_bit_xor() { - let a: TreeSet = vec![1, 3, 5, 9, 11].into_iter().collect(); - let b: TreeSet = vec![-2, 3, 9, 14, 22].into_iter().collect(); - - let set: TreeSet = &a ^ &b; - let v: Vec = set.into_iter().collect(); - assert_eq!(v, vec![-2, 1, 5, 11, 14, 22]); - } - - #[test] - fn test_sub() { - let a: TreeSet = vec![-5, 11, 22, 33, 40, 42].into_iter().collect(); - let b: TreeSet = vec![-12, -5, 14, 23, 34, 38, 39, 50].into_iter().collect(); - - let set: TreeSet = &a - &b; - let v: Vec = set.into_iter().collect(); - assert_eq!(v, vec![11, 22, 33, 40, 42]); - } - - #[test] - fn test_zip() { - let mut x = TreeSet::new(); - x.insert(5u); - x.insert(12u); - x.insert(11u); - - let mut y = TreeSet::new(); - y.insert("foo"); - y.insert("bar"); - - let x = x; - let y = y; - let mut z = x.iter().zip(y.iter()); - - // FIXME: #5801: this needs a type hint to compile... - let result: Option<(&uint, & &'static str)> = z.next(); - assert_eq!(result.unwrap(), (&5u, &("bar"))); - - let result: Option<(&uint, & &'static str)> = z.next(); - assert_eq!(result.unwrap(), (&11u, &("foo"))); - - let result: Option<(&uint, & &'static str)> = z.next(); - assert!(result.is_none()); - } - - #[test] - fn test_from_iter() { - let xs = [1i, 2, 3, 4, 5, 6, 7, 8, 9]; - - let set: TreeSet = xs.iter().map(|&x| x).collect(); - - for x in xs.iter() { - assert!(set.contains(x)); - } - } - - #[test] - fn test_show() { - let mut set: TreeSet = TreeSet::new(); - let empty: TreeSet = TreeSet::new(); - - set.insert(1); - set.insert(2); - - let set_str = format!("{}", set); - - assert!(set_str == "{1, 2}"); - assert_eq!(format!("{}", empty), "{}"); - } -} diff --git a/src/libcollections/trie/map.rs b/src/libcollections/trie/map.rs deleted file mode 100644 index 9a9ac6a3c5829..0000000000000 --- a/src/libcollections/trie/map.rs +++ /dev/null @@ -1,1958 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Ordered maps and sets, implemented as simple tries. -use core::prelude::*; - -pub use self::Entry::*; -use self::TrieNode::*; -use alloc::boxed::Box; -use core::default::Default; -use core::fmt; -use core::fmt::Show; -use core::mem::zeroed; -use core::mem; -use core::ops::{Slice, SliceMut}; -use core::uint; -use core::iter; -use core::ptr; -use std::hash::{Writer, Hash}; - -use slice::{Items, MutItems}; -use slice; - -// FIXME(conventions): implement bounded iterators -// FIXME(conventions): implement into_iter -// FIXME(conventions): replace each_reverse by making iter DoubleEnded - -// FIXME: #5244: need to manually update the InternalNode constructor -const SHIFT: uint = 4; -const SIZE: uint = 1 << SHIFT; -const MASK: uint = SIZE - 1; -// The number of chunks that the key is divided into. Also the maximum depth of the TrieMap. -const MAX_DEPTH: uint = uint::BITS / SHIFT; - -/// A map implemented as a radix trie. -/// -/// Keys are split into sequences of 4 bits, which are used to place elements in -/// 16-entry arrays which are nested to form a tree structure. Inserted elements are placed -/// as close to the top of the tree as possible. The most significant bits of the key are used to -/// assign the key to a node/bucket in the first layer. If there are no other elements keyed by -/// the same 4 bits in the first layer, a leaf node will be created in the first layer. -/// When keys coincide, the next 4 bits are used to assign the node to a bucket in the next layer, -/// with this process continuing until an empty spot is found or there are no more bits left in the -/// key. As a result, the maximum depth using 32-bit `uint` keys is 8. The worst collisions occur -/// for very small numbers. For example, 1 and 2 are identical in all but their least significant -/// 4 bits. If both numbers are used as keys, a chain of maximum length will be created to -/// differentiate them. -/// -/// # Examples -/// -/// ``` -/// use std::collections::TrieMap; -/// -/// let mut map = TrieMap::new(); -/// map.insert(27, "Olaf"); -/// map.insert(1, "Edgar"); -/// map.insert(13, "Ruth"); -/// map.insert(1, "Martin"); -/// -/// assert_eq!(map.len(), 3); -/// assert_eq!(map.get(&1), Some(&"Martin")); -/// -/// if !map.contains_key(&90) { -/// println!("Nobody is keyed 90"); -/// } -/// -/// // Update a key -/// match map.get_mut(&1) { -/// Some(value) => *value = "Olga", -/// None => (), -/// } -/// -/// map.remove(&13); -/// assert_eq!(map.len(), 2); -/// -/// // Print the key value pairs, ordered by key. -/// for (key, value) in map.iter() { -/// // Prints `1: Olga` then `27: Olaf` -/// println!("{}: {}", key, value); -/// } -/// -/// map.clear(); -/// assert!(map.is_empty()); -/// ``` -#[deriving(Clone)] -pub struct TrieMap { - root: InternalNode, - length: uint -} - -// An internal node holds SIZE child nodes, which may themselves contain more internal nodes. -// -// Throughout this implementation, "idx" is used to refer to a section of key that is used -// to access a node. The layer of the tree directly below the root corresponds to idx 0. -struct InternalNode { - // The number of direct children which are external (i.e. that store a value). - count: uint, - children: [TrieNode, ..SIZE] -} - -// Each child of an InternalNode may be internal, in which case nesting continues, -// external (containing a value), or empty -#[deriving(Clone)] -enum TrieNode { - Internal(Box>), - External(uint, T), - Nothing -} - -impl PartialEq for TrieMap { - fn eq(&self, other: &TrieMap) -> bool { - self.len() == other.len() && - self.iter().zip(other.iter()).all(|(a, b)| a == b) - } -} - -impl Eq for TrieMap {} - -impl PartialOrd for TrieMap { - #[inline] - fn partial_cmp(&self, other: &TrieMap) -> Option { - iter::order::partial_cmp(self.iter(), other.iter()) - } -} - -impl Ord for TrieMap { - #[inline] - fn cmp(&self, other: &TrieMap) -> Ordering { - iter::order::cmp(self.iter(), other.iter()) - } -} - -impl Show for TrieMap { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, (k, v)) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{}: {}", k, *v)); - } - - write!(f, "}}") - } -} - -#[stable] -impl Default for TrieMap { - #[inline] - #[stable] - fn default() -> TrieMap { TrieMap::new() } -} - -impl TrieMap { - /// Creates an empty `TrieMap`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// let mut map: TrieMap<&str> = TrieMap::new(); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn new() -> TrieMap { - TrieMap{root: InternalNode::new(), length: 0} - } - - /// Visits all key-value pairs in reverse order. Aborts traversal when `f` returns `false`. - /// Returns `true` if `f` returns `true` for all elements. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// let map: TrieMap<&str> = [(1, "a"), (2, "b"), (3, "c")].iter().map(|&x| x).collect(); - /// - /// let mut vec = Vec::new(); - /// assert_eq!(true, map.each_reverse(|&key, &value| { vec.push((key, value)); true })); - /// assert_eq!(vec, vec![(3, "c"), (2, "b"), (1, "a")]); - /// - /// // Stop when we reach 2 - /// let mut vec = Vec::new(); - /// assert_eq!(false, map.each_reverse(|&key, &value| { vec.push(value); key != 2 })); - /// assert_eq!(vec, vec!["c", "b"]); - /// ``` - #[inline] - pub fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool { - self.root.each_reverse(f) - } - - /// Gets an iterator visiting all keys in ascending order by the keys. - /// The iterator's element type is `uint`. - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn keys<'r>(&'r self) -> Keys<'r, T> { - fn first((a, _): (A, B)) -> A { a } - - self.iter().map(first) - } - - /// Gets an iterator visiting all values in ascending order by the keys. - /// The iterator's element type is `&'r T`. - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn values<'r>(&'r self) -> Values<'r, T> { - fn second((_, b): (A, B)) -> B { b } - - self.iter().map(second) - } - - /// Gets an iterator over the key-value pairs in the map, ordered by keys. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// let map: TrieMap<&str> = [(3, "c"), (1, "a"), (2, "b")].iter().map(|&x| x).collect(); - /// - /// for (key, value) in map.iter() { - /// println!("{}: {}", key, value); - /// } - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn iter<'a>(&'a self) -> Entries<'a, T> { - let mut iter = unsafe {Entries::new()}; - iter.stack[0] = self.root.children.iter(); - iter.length = 1; - iter.remaining_min = self.length; - iter.remaining_max = self.length; - - iter - } - - /// Gets an iterator over the key-value pairs in the map, with the - /// ability to mutate the values. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// let mut map: TrieMap = [(1, 2), (2, 4), (3, 6)].iter().map(|&x| x).collect(); - /// - /// for (key, value) in map.iter_mut() { - /// *value = -(key as int); - /// } - /// - /// assert_eq!(map.get(&1), Some(&-1)); - /// assert_eq!(map.get(&2), Some(&-2)); - /// assert_eq!(map.get(&3), Some(&-3)); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn iter_mut<'a>(&'a mut self) -> MutEntries<'a, T> { - let mut iter = unsafe {MutEntries::new()}; - iter.stack[0] = self.root.children.iter_mut(); - iter.length = 1; - iter.remaining_min = self.length; - iter.remaining_max = self.length; - - iter - } - - /// Return the number of elements in the map. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// - /// let mut a = TrieMap::new(); - /// assert_eq!(a.len(), 0); - /// a.insert(1, "a"); - /// assert_eq!(a.len(), 1); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn len(&self) -> uint { self.length } - - /// Return true if the map contains no elements. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// - /// let mut a = TrieMap::new(); - /// assert!(a.is_empty()); - /// a.insert(1, "a"); - /// assert!(!a.is_empty()); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn is_empty(&self) -> bool { self.len() == 0 } - - /// Clears the map, removing all values. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// - /// let mut a = TrieMap::new(); - /// a.insert(1, "a"); - /// a.clear(); - /// assert!(a.is_empty()); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn clear(&mut self) { - self.root = InternalNode::new(); - self.length = 0; - } - - /// Deprecated: renamed to `get`. - #[deprecated = "renamed to `get`"] - pub fn find(&self, key: &uint) -> Option<&T> { - self.get(key) - } - - /// Returns a reference to the value corresponding to the key. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// - /// let mut map = TrieMap::new(); - /// map.insert(1, "a"); - /// assert_eq!(map.get(&1), Some(&"a")); - /// assert_eq!(map.get(&2), None); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get(&self, key: &uint) -> Option<&T> { - let mut node = &self.root; - let mut idx = 0; - loop { - match node.children[chunk(*key, idx)] { - Internal(ref x) => node = &**x, - External(stored, ref value) => { - if stored == *key { - return Some(value) - } else { - return None - } - } - Nothing => return None - } - idx += 1; - } - } - - /// Returns true if the map contains a value for the specified key. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// - /// let mut map = TrieMap::new(); - /// map.insert(1, "a"); - /// assert_eq!(map.contains_key(&1), true); - /// assert_eq!(map.contains_key(&2), false); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains_key(&self, key: &uint) -> bool { - self.get(key).is_some() - } - - /// Deprecated: renamed to `get_mut`. - #[deprecated = "renamed to `get_mut`"] - pub fn find_mut(&mut self, key: &uint) -> Option<&mut T> { - self.get_mut(key) - } - - /// Returns a mutable reference to the value corresponding to the key. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// - /// let mut map = TrieMap::new(); - /// map.insert(1, "a"); - /// match map.get_mut(&1) { - /// Some(x) => *x = "b", - /// None => (), - /// } - /// assert_eq!(map[1], "b"); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> { - find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1) - } - - /// Deprecated: Renamed to `insert`. - #[deprecated = "Renamed to `insert`"] - pub fn swap(&mut self, key: uint, value: T) -> Option { - self.insert(key, value) - } - - /// Inserts 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. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// - /// let mut map = TrieMap::new(); - /// assert_eq!(map.insert(37, "a"), None); - /// assert_eq!(map.is_empty(), false); - /// - /// map.insert(37, "b"); - /// assert_eq!(map.insert(37, "c"), Some("b")); - /// assert_eq!(map[37], "c"); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn insert(&mut self, key: uint, value: T) -> Option { - let (_, old_val) = insert(&mut self.root.count, - &mut self.root.children[chunk(key, 0)], - key, value, 1); - if old_val.is_none() { self.length += 1 } - old_val - } - - /// Deprecated: Renamed to `remove`. - #[deprecated = "Renamed to `remove`"] - pub fn pop(&mut self, key: &uint) -> Option { - self.remove(key) - } - - /// Removes a key from the map, returning the value at the key if the key - /// was previously in the map. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// - /// let mut map = TrieMap::new(); - /// map.insert(1, "a"); - /// assert_eq!(map.remove(&1), Some("a")); - /// assert_eq!(map.remove(&1), None); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, key: &uint) -> Option { - let ret = remove(&mut self.root.count, - &mut self.root.children[chunk(*key, 0)], - *key, 1); - if ret.is_some() { self.length -= 1 } - ret - } -} - -// FIXME #5846 we want to be able to choose between &x and &mut x -// (with many different `x`) below, so we need to optionally pass mut -// as a tt, but the only thing we can do with a `tt` is pass them to -// other macros, so this takes the `& ` token -// sequence and forces their evaluation as an expression. (see also -// `item!` below.) -macro_rules! addr { ($e:expr) => { $e } } - -macro_rules! bound { - ($iterator_name:ident, - // the current treemap - self = $this:expr, - // the key to look for - key = $key:expr, - // are we looking at the upper bound? - is_upper = $upper:expr, - - // method names for slicing/iterating. - slice_from = $slice_from:ident, - iter = $iter:ident, - - // see the comment on `addr!`, this is just an optional mut, but - // there's no 0-or-1 repeats yet. - mutability = $($mut_:tt)*) => { - { - // # For `mut` - // We need an unsafe pointer here because we are borrowing - // mutable references to the internals of each of these - // mutable nodes, while still using the outer node. - // - // However, we're allowed to flaunt rustc like this because we - // never actually modify the "shape" of the nodes. The only - // place that mutation is can actually occur is of the actual - // values of the TrieMap (as the return value of the - // iterator), i.e. we can never cause a deallocation of any - // InternalNodes so the raw pointer is always valid. - // - // # For non-`mut` - // We like sharing code so much that even a little unsafe won't - // stop us. - let this = $this; - let mut node = unsafe { - mem::transmute::<_, uint>(&this.root) as *mut InternalNode - }; - - let key = $key; - - let mut it = unsafe {$iterator_name::new()}; - // everything else is zero'd, as we want. - it.remaining_max = this.length; - - // this addr is necessary for the `Internal` pattern. - addr!(loop { - let children = unsafe {addr!(& $($mut_)* (*node).children)}; - // it.length is the current depth in the iterator and the - // current depth through the `uint` key we've traversed. - let child_id = chunk(key, it.length); - let (slice_idx, ret) = match children[child_id] { - Internal(ref $($mut_)* n) => { - node = unsafe { - mem::transmute::<_, uint>(&**n) - as *mut InternalNode - }; - (child_id + 1, false) - } - External(stored, _) => { - (if stored < key || ($upper && stored == key) { - child_id + 1 - } else { - child_id - }, true) - } - Nothing => { - (child_id + 1, true) - } - }; - // push to the stack. - it.stack[it.length] = children.$slice_from(&slice_idx).$iter(); - it.length += 1; - if ret { return it } - }) - } - } -} - -impl TrieMap { - // If `upper` is true then returns upper_bound else returns lower_bound. - #[inline] - fn bound<'a>(&'a self, key: uint, upper: bool) -> Entries<'a, T> { - bound!(Entries, self = self, - key = key, is_upper = upper, - slice_from = slice_from_or_fail, iter = iter, - mutability = ) - } - - /// Gets an iterator pointing to the first key-value pair whose key is not less than `key`. - /// If all keys in the map are less than `key` an empty iterator is returned. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// let map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect(); - /// - /// assert_eq!(map.lower_bound(4).next(), Some((4, &"b"))); - /// assert_eq!(map.lower_bound(5).next(), Some((6, &"c"))); - /// assert_eq!(map.lower_bound(10).next(), None); - /// ``` - pub fn lower_bound<'a>(&'a self, key: uint) -> Entries<'a, T> { - self.bound(key, false) - } - - /// Gets an iterator pointing to the first key-value pair whose key is greater than `key`. - /// If all keys in the map are not greater than `key` an empty iterator is returned. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// let map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect(); - /// - /// assert_eq!(map.upper_bound(4).next(), Some((6, &"c"))); - /// assert_eq!(map.upper_bound(5).next(), Some((6, &"c"))); - /// assert_eq!(map.upper_bound(10).next(), None); - /// ``` - pub fn upper_bound<'a>(&'a self, key: uint) -> Entries<'a, T> { - self.bound(key, true) - } - // If `upper` is true then returns upper_bound else returns lower_bound. - #[inline] - fn bound_mut<'a>(&'a mut self, key: uint, upper: bool) -> MutEntries<'a, T> { - bound!(MutEntries, self = self, - key = key, is_upper = upper, - slice_from = slice_from_or_fail_mut, iter = iter_mut, - mutability = mut) - } - - /// Gets an iterator pointing to the first key-value pair whose key is not less than `key`. - /// If all keys in the map are less than `key` an empty iterator is returned. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// let mut map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect(); - /// - /// assert_eq!(map.lower_bound_mut(4).next(), Some((4, &mut "b"))); - /// assert_eq!(map.lower_bound_mut(5).next(), Some((6, &mut "c"))); - /// assert_eq!(map.lower_bound_mut(10).next(), None); - /// - /// for (key, value) in map.lower_bound_mut(4) { - /// *value = "changed"; - /// } - /// - /// assert_eq!(map.get(&2), Some(&"a")); - /// assert_eq!(map.get(&4), Some(&"changed")); - /// assert_eq!(map.get(&6), Some(&"changed")); - /// ``` - pub fn lower_bound_mut<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> { - self.bound_mut(key, false) - } - - /// Gets an iterator pointing to the first key-value pair whose key is greater than `key`. - /// If all keys in the map are not greater than `key` an empty iterator is returned. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieMap; - /// let mut map: TrieMap<&str> = [(2, "a"), (4, "b"), (6, "c")].iter().map(|&x| x).collect(); - /// - /// assert_eq!(map.upper_bound_mut(4).next(), Some((6, &mut "c"))); - /// assert_eq!(map.upper_bound_mut(5).next(), Some((6, &mut "c"))); - /// assert_eq!(map.upper_bound_mut(10).next(), None); - /// - /// for (key, value) in map.upper_bound_mut(4) { - /// *value = "changed"; - /// } - /// - /// assert_eq!(map.get(&2), Some(&"a")); - /// assert_eq!(map.get(&4), Some(&"b")); - /// assert_eq!(map.get(&6), Some(&"changed")); - /// ``` - pub fn upper_bound_mut<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> { - self.bound_mut(key, true) - } -} - -impl FromIterator<(uint, T)> for TrieMap { - fn from_iter>(iter: Iter) -> TrieMap { - let mut map = TrieMap::new(); - map.extend(iter); - map - } -} - -impl Extend<(uint, T)> for TrieMap { - fn extend>(&mut self, mut iter: Iter) { - for (k, v) in iter { - self.insert(k, v); - } - } -} - -impl> Hash for TrieMap { - fn hash(&self, state: &mut S) { - for elt in self.iter() { - elt.hash(state); - } - } -} - -impl Index for TrieMap { - #[inline] - fn index<'a>(&'a self, i: &uint) -> &'a T { - self.get(i).expect("key not present") - } -} - -impl IndexMut for TrieMap { - #[inline] - fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut T { - self.get_mut(i).expect("key not present") - } -} - -impl Clone for InternalNode { - #[inline] - fn clone(&self) -> InternalNode { - let ch = &self.children; - InternalNode { - count: self.count, - children: [ch[0].clone(), ch[1].clone(), ch[2].clone(), ch[3].clone(), - ch[4].clone(), ch[5].clone(), ch[6].clone(), ch[7].clone(), - ch[8].clone(), ch[9].clone(), ch[10].clone(), ch[11].clone(), - ch[12].clone(), ch[13].clone(), ch[14].clone(), ch[15].clone()]} - } -} - -impl InternalNode { - #[inline] - fn new() -> InternalNode { - // FIXME: #5244: [Nothing, ..SIZE] should be possible without implicit - // copyability - InternalNode{count: 0, - children: [Nothing, Nothing, Nothing, Nothing, - Nothing, Nothing, Nothing, Nothing, - Nothing, Nothing, Nothing, Nothing, - Nothing, Nothing, Nothing, Nothing]} - } -} - -impl InternalNode { - fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool { - for elt in self.children.iter().rev() { - match *elt { - Internal(ref x) => if !x.each_reverse(|i,t| f(i,t)) { return false }, - External(k, ref v) => if !f(&k, v) { return false }, - Nothing => () - } - } - true - } -} - -// if this was done via a trait, the key could be generic -#[inline] -fn chunk(n: uint, idx: uint) -> uint { - let sh = uint::BITS - (SHIFT * (idx + 1)); - (n >> sh) & MASK -} - -fn find_mut<'r, T>(child: &'r mut TrieNode, key: uint, idx: uint) -> Option<&'r mut T> { - match *child { - External(stored, ref mut value) if stored == key => Some(value), - External(..) => None, - Internal(ref mut x) => find_mut(&mut x.children[chunk(key, idx)], key, idx + 1), - Nothing => None - } -} - -/// Inserts a new node for the given key and value, at or below `start_node`. -/// -/// The index (`idx`) is the index of the next node, such that the start node -/// was accessed via parent.children[chunk(key, idx - 1)]. -/// -/// The count is the external node counter for the start node's parent, -/// which will be incremented only if `start_node` is transformed into a *new* external node. -/// -/// Returns a mutable reference to the inserted value and an optional previous value. -fn insert<'a, T>(count: &mut uint, start_node: &'a mut TrieNode, key: uint, value: T, idx: uint) - -> (&'a mut T, Option) { - // We branch twice to avoid having to do the `replace` when we - // don't need to; this is much faster, especially for keys that - // have long shared prefixes. - match *start_node { - Nothing => { - *count += 1; - *start_node = External(key, value); - match *start_node { - External(_, ref mut value_ref) => return (value_ref, None), - _ => unreachable!() - } - } - Internal(box ref mut x) => { - return insert(&mut x.count, &mut x.children[chunk(key, idx)], key, value, idx + 1); - } - External(stored_key, ref mut stored_value) if stored_key == key => { - // Swap in the new value and return the old. - let old_value = mem::replace(stored_value, value); - return (stored_value, Some(old_value)); - } - _ => {} - } - - // Conflict, an external node with differing keys. - // We replace the old node by an internal one, then re-insert the two values beneath it. - match mem::replace(start_node, Internal(box InternalNode::new())) { - External(stored_key, stored_value) => { - match *start_node { - Internal(box ref mut new_node) => { - // Re-insert the old value. - insert(&mut new_node.count, - &mut new_node.children[chunk(stored_key, idx)], - stored_key, stored_value, idx + 1); - - // Insert the new value, and return a reference to it directly. - insert(&mut new_node.count, - &mut new_node.children[chunk(key, idx)], - key, value, idx + 1) - } - // Value that was just copied disappeared. - _ => unreachable!() - } - } - // Logic error in previous match. - _ => unreachable!(), - } -} - -fn remove(count: &mut uint, child: &mut TrieNode, key: uint, - idx: uint) -> Option { - let (ret, this) = match *child { - External(stored, _) if stored == key => { - match mem::replace(child, Nothing) { - External(_, value) => (Some(value), true), - _ => unreachable!() - } - } - External(..) => (None, false), - Internal(box ref mut x) => { - let ret = remove(&mut x.count, &mut x.children[chunk(key, idx)], - key, idx + 1); - (ret, x.count == 0) - } - Nothing => (None, false) - }; - - if this { - *child = Nothing; - *count -= 1; - } - return ret; -} - -/// A view into a single entry in a TrieMap, which may be vacant or occupied. -pub enum Entry<'a, T: 'a> { - /// An occupied entry. - Occupied(OccupiedEntry<'a, T>), - /// A vacant entry. - Vacant(VacantEntry<'a, T>) -} - -/// A view into an occupied entry in a TrieMap. -pub struct OccupiedEntry<'a, T: 'a> { - search_stack: SearchStack<'a, T> -} - -/// A view into a vacant entry in a TrieMap. -pub struct VacantEntry<'a, T: 'a> { - search_stack: SearchStack<'a, T> -} - -/// A list of nodes encoding a path from the root of a TrieMap to a node. -/// -/// Invariants: -/// * The last node is either `External` or `Nothing`. -/// * Pointers at indexes less than `length` can be safely dereferenced. -struct SearchStack<'a, T: 'a> { - map: &'a mut TrieMap, - length: uint, - key: uint, - items: [*mut TrieNode, ..MAX_DEPTH] -} - -impl<'a, T> SearchStack<'a, T> { - /// Creates a new search-stack with empty entries. - fn new(map: &'a mut TrieMap, key: uint) -> SearchStack<'a, T> { - SearchStack { - map: map, - length: 0, - key: key, - items: [ptr::null_mut(), ..MAX_DEPTH] - } - } - - fn push(&mut self, node: *mut TrieNode) { - self.length += 1; - self.items[self.length - 1] = node; - } - - fn peek(&self) -> *mut TrieNode { - self.items[self.length - 1] - } - - fn peek_ref(&self) -> &'a mut TrieNode { - unsafe { - &mut *self.items[self.length - 1] - } - } - - fn pop_ref(&mut self) -> &'a mut TrieNode { - self.length -= 1; - unsafe { - &mut *self.items[self.length] - } - } - - fn is_empty(&self) -> bool { - self.length == 0 - } - - fn get_ref(&self, idx: uint) -> &'a mut TrieNode { - assert!(idx < self.length); - unsafe { - &mut *self.items[idx] - } - } -} - -// Implementation of SearchStack creation logic. -// Once a SearchStack has been created the Entry methods are relatively straight-forward. -impl TrieMap { - /// Gets the given key's corresponding entry in the map for in-place manipulation. - #[inline] - pub fn entry<'a>(&'a mut self, key: uint) -> Entry<'a, T> { - // Create an empty search stack. - let mut search_stack = SearchStack::new(self, key); - - // Unconditionally add the corresponding node from the first layer. - let first_node = &mut search_stack.map.root.children[chunk(key, 0)] as *mut _; - search_stack.push(first_node); - - // While no appropriate slot is found, keep descending down the Trie, - // adding nodes to the search stack. - let search_successful: bool; - loop { - match unsafe { next_child(search_stack.peek(), key, search_stack.length) } { - (Some(child), _) => search_stack.push(child), - (None, success) => { - search_successful = success; - break; - } - } - } - - if search_successful { - Occupied(OccupiedEntry { search_stack: search_stack }) - } else { - Vacant(VacantEntry { search_stack: search_stack }) - } - } -} - -/// Get a mutable pointer to the next child of a node, given a key and an idx. -/// -/// The idx is the index of the next child, such that `node` was accessed via -/// parent.children[chunk(key, idx - 1)]. -/// -/// Returns a tuple with an optional mutable pointer to the next child, and -/// a boolean flag to indicate whether the external key node was found. -/// -/// This function is safe only if `node` points to a valid `TrieNode`. -#[inline] -unsafe fn next_child<'a, T>(node: *mut TrieNode, key: uint, idx: uint) - -> (Option<*mut TrieNode>, bool) { - match *node { - // If the node is internal, tell the caller to descend further. - Internal(box ref mut node_internal) => { - (Some(&mut node_internal.children[chunk(key, idx)] as *mut _), false) - }, - // If the node is external or empty, the search is complete. - // If the key doesn't match, node expansion will be done upon - // insertion. If it does match, we've found our node. - External(stored_key, _) if stored_key == key => (None, true), - External(..) | Nothing => (None, false) - } -} - -// NB: All these methods assume a correctly constructed occupied entry (matching the given key). -impl<'a, T> OccupiedEntry<'a, T> { - /// Gets a reference to the value in the entry. - #[inline] - pub fn get(&self) -> &T { - match *self.search_stack.peek_ref() { - External(_, ref value) => value, - // Invalid SearchStack, non-external last node. - _ => unreachable!() - } - } - - /// Gets a mutable reference to the value in the entry. - #[inline] - pub fn get_mut(&mut self) -> &mut T { - match *self.search_stack.peek_ref() { - External(_, ref mut value) => value, - // Invalid SearchStack, non-external last node. - _ => unreachable!() - } - } - - /// Converts the OccupiedEntry into a mutable reference to the value in the entry, - /// with a lifetime bound to the map itself. - #[inline] - pub fn into_mut(self) -> &'a mut T { - match *self.search_stack.peek_ref() { - External(_, ref mut value) => value, - // Invalid SearchStack, non-external last node. - _ => unreachable!() - } - } - - /// Sets the value of the entry, and returns the entry's old value. - #[inline] - pub fn set(&mut self, value: T) -> T { - match *self.search_stack.peek_ref() { - External(_, ref mut stored_value) => { - mem::replace(stored_value, value) - } - // Invalid SearchStack, non-external last node. - _ => unreachable!() - } - } - - /// Takes the value out of the entry, and returns it. - #[inline] - pub fn take(self) -> T { - // This function removes the external leaf-node, then unwinds the search-stack - // deleting now-childless ancestors. - let mut search_stack = self.search_stack; - - // Extract the value from the leaf-node of interest. - let leaf_node = mem::replace(search_stack.pop_ref(), Nothing); - - let value = match leaf_node { - External(_, value) => value, - // Invalid SearchStack, non-external last node. - _ => unreachable!() - }; - - // Iterate backwards through the search stack, deleting nodes if they are childless. - // We compare each ancestor's parent count to 1 because each ancestor reached has just - // had one of its children deleted. - while !search_stack.is_empty() { - let ancestor = search_stack.pop_ref(); - match *ancestor { - Internal(ref mut internal) => { - // If stopping deletion, update the child count and break. - if internal.count != 1 { - internal.count -= 1; - break; - } - } - // Invalid SearchStack, non-internal ancestor node. - _ => unreachable!() - } - *ancestor = Nothing; - } - - // Decrement the length of the entire TrieMap, for the removed node. - search_stack.map.length -= 1; - - value - } -} - -impl<'a, T> VacantEntry<'a, T> { - /// Set the vacant entry to the given value. - pub fn set(self, value: T) -> &'a mut T { - let search_stack = self.search_stack; - let old_length = search_stack.length; - let key = search_stack.key; - - // Update the TrieMap's length for the new element. - search_stack.map.length += 1; - - // If there's only 1 node in the search stack, insert a new node below it at idx 1. - if old_length == 1 { - // Note: Small hack to appease the borrow checker. Can't mutably borrow root.count - let mut temp = search_stack.map.root.count; - let (value_ref, _) = insert(&mut temp, search_stack.get_ref(0), key, value, 1); - search_stack.map.root.count = temp; - value_ref - } - // Otherwise, find the predecessor of the last stack node, and insert as normal. - else { - match *search_stack.get_ref(old_length - 2) { - Internal(box ref mut parent) => { - let (value_ref, _) = insert(&mut parent.count, - &mut parent.children[chunk(key, old_length - 1)], - key, value, old_length); - value_ref - } - // Invalid SearchStack, non-internal ancestor node. - _ => unreachable!() - } - } - } -} - -/// A forward iterator over a map. -pub struct Entries<'a, T:'a> { - stack: [slice::Items<'a, TrieNode>, .. MAX_DEPTH], - length: uint, - remaining_min: uint, - remaining_max: uint -} - -/// A forward iterator over the key-value pairs of a map, with the -/// values being mutable. -pub struct MutEntries<'a, T:'a> { - stack: [slice::MutItems<'a, TrieNode>, .. MAX_DEPTH], - length: uint, - remaining_min: uint, - remaining_max: uint -} - -/// A forward iterator over the keys of a map. -pub type Keys<'a, T> = iter::Map<(uint, &'a T), uint, Entries<'a, T>, fn((uint, &'a T)) -> uint>; - -/// A forward iterator over the values of a map. -pub type Values<'a, T> = - iter::Map<(uint, &'a T), &'a T, Entries<'a, T>, fn((uint, &'a T)) -> &'a T>; - -// FIXME #5846: see `addr!` above. -macro_rules! item { ($i:item) => {$i}} - -macro_rules! iterator_impl { - ($name:ident, - iter = $iter:ident, - mutability = $($mut_:tt)*) => { - impl<'a, T> $name<'a, T> { - // Create new zero'd iterator. We have a thin gilding of safety by - // using init rather than uninit, so that the worst that can happen - // from failing to initialise correctly after calling these is a - // segfault. - #[cfg(target_word_size="32")] - unsafe fn new() -> $name<'a, T> { - $name { - remaining_min: 0, - remaining_max: 0, - length: 0, - // ick :( ... at least the compiler will tell us if we screwed up. - stack: [zeroed(), zeroed(), zeroed(), zeroed(), zeroed(), - zeroed(), zeroed(), zeroed()] - } - } - - #[cfg(target_word_size="64")] - unsafe fn new() -> $name<'a, T> { - $name { - remaining_min: 0, - remaining_max: 0, - length: 0, - stack: [zeroed(), zeroed(), zeroed(), zeroed(), - zeroed(), zeroed(), zeroed(), zeroed(), - zeroed(), zeroed(), zeroed(), zeroed(), - zeroed(), zeroed(), zeroed(), zeroed()] - } - } - } - - item! { impl<'a, T> Iterator<(uint, &'a $($mut_)* T)> for $name<'a, T> { - // you might wonder why we're not even trying to act within the - // rules, and are just manipulating raw pointers like there's no - // such thing as invalid pointers and memory unsafety. The - // reason is performance, without doing this we can get the - // (now replaced) bench_iter_large microbenchmark down to about - // 30000 ns/iter (using .unsafe_get to index self.stack directly, 38000 - // ns/iter with [] checked indexing), but this smashes that down - // to 13500 ns/iter. - // - // Fortunately, it's still safe... - // - // We have an invariant that every Internal node - // corresponds to one push to self.stack, and one pop, - // nested appropriately. self.stack has enough storage - // to store the maximum depth of Internal nodes in the - // trie (8 on 32-bit platforms, 16 on 64-bit). - fn next(&mut self) -> Option<(uint, &'a $($mut_)* T)> { - let start_ptr = self.stack.as_mut_ptr(); - - unsafe { - // write_ptr is the next place to write to the stack. - // invariant: start_ptr <= write_ptr < end of the - // vector. - let mut write_ptr = start_ptr.offset(self.length as int); - while write_ptr != start_ptr { - // indexing back one is safe, since write_ptr > - // start_ptr now. - match (*write_ptr.offset(-1)).next() { - // exhausted this iterator (i.e. finished this - // Internal node), so pop from the stack. - // - // don't bother clearing the memory, because the - // next time we use it we'll've written to it - // first. - None => write_ptr = write_ptr.offset(-1), - Some(child) => { - addr!(match *child { - Internal(ref $($mut_)* node) => { - // going down a level, so push - // to the stack (this is the - // write referenced above) - *write_ptr = node.children.$iter(); - write_ptr = write_ptr.offset(1); - } - External(key, ref $($mut_)* value) => { - self.remaining_max -= 1; - if self.remaining_min > 0 { - self.remaining_min -= 1; - } - // store the new length of the - // stack, based on our current - // position. - self.length = (write_ptr as uint - - start_ptr as uint) / - mem::size_of_val(&*write_ptr); - - return Some((key, value)); - } - Nothing => {} - }) - } - } - } - } - return None; - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - (self.remaining_min, Some(self.remaining_max)) - } - } } - } -} - -iterator_impl! { Entries, iter = iter, mutability = } -iterator_impl! { MutEntries, iter = iter_mut, mutability = mut } - -#[cfg(test)] -mod test { - use std::prelude::*; - use std::iter::range_step; - use std::uint; - use std::hash; - - use super::{TrieMap, InternalNode}; - use super::Entry::*; - use super::TrieNode::*; - - fn check_integrity(trie: &InternalNode) { - assert!(trie.count != 0); - - let mut sum = 0; - - for x in trie.children.iter() { - match *x { - Nothing => (), - Internal(ref y) => { - check_integrity(&**y); - sum += 1 - } - External(_, _) => { sum += 1 } - } - } - - assert_eq!(sum, trie.count); - } - - #[test] - fn test_find_mut() { - let mut m = TrieMap::new(); - assert!(m.insert(1u, 12i).is_none()); - assert!(m.insert(2u, 8i).is_none()); - assert!(m.insert(5u, 14i).is_none()); - let new = 100; - match m.get_mut(&5) { - None => panic!(), Some(x) => *x = new - } - assert_eq!(m.get(&5), Some(&new)); - } - - #[test] - fn test_find_mut_missing() { - let mut m = TrieMap::new(); - assert!(m.get_mut(&0).is_none()); - assert!(m.insert(1u, 12i).is_none()); - assert!(m.get_mut(&0).is_none()); - assert!(m.insert(2, 8).is_none()); - assert!(m.get_mut(&0).is_none()); - } - - #[test] - fn test_step() { - let mut trie = TrieMap::new(); - let n = 300u; - - for x in range_step(1u, n, 2) { - assert!(trie.insert(x, x + 1).is_none()); - assert!(trie.contains_key(&x)); - check_integrity(&trie.root); - } - - for x in range_step(0u, n, 2) { - assert!(!trie.contains_key(&x)); - assert!(trie.insert(x, x + 1).is_none()); - check_integrity(&trie.root); - } - - for x in range(0u, n) { - assert!(trie.contains_key(&x)); - assert!(!trie.insert(x, x + 1).is_none()); - check_integrity(&trie.root); - } - - for x in range_step(1u, n, 2) { - assert!(trie.remove(&x).is_some()); - assert!(!trie.contains_key(&x)); - check_integrity(&trie.root); - } - - for x in range_step(0u, n, 2) { - assert!(trie.contains_key(&x)); - assert!(!trie.insert(x, x + 1).is_none()); - check_integrity(&trie.root); - } - } - - #[test] - fn test_each_reverse() { - let mut m = TrieMap::new(); - - assert!(m.insert(3, 6).is_none()); - assert!(m.insert(0, 0).is_none()); - assert!(m.insert(4, 8).is_none()); - assert!(m.insert(2, 4).is_none()); - assert!(m.insert(1, 2).is_none()); - - let mut n = 4; - m.each_reverse(|k, v| { - assert_eq!(*k, n); - assert_eq!(*v, n * 2); - n -= 1; - true - }); - } - - #[test] - fn test_each_reverse_break() { - let mut m = TrieMap::new(); - - for x in range(uint::MAX - 10000, uint::MAX).rev() { - m.insert(x, x / 2); - } - - let mut n = uint::MAX - 1; - m.each_reverse(|k, v| { - if n == uint::MAX - 5000 { false } else { - assert!(n > uint::MAX - 5000); - - assert_eq!(*k, n); - assert_eq!(*v, n / 2); - n -= 1; - true - } - }); - } - - #[test] - fn test_insert() { - let mut m = TrieMap::new(); - assert_eq!(m.insert(1u, 2i), None); - assert_eq!(m.insert(1u, 3i), Some(2)); - assert_eq!(m.insert(1u, 4i), Some(3)); - } - - #[test] - fn test_remove() { - let mut m = TrieMap::new(); - m.insert(1u, 2i); - assert_eq!(m.remove(&1), Some(2)); - assert_eq!(m.remove(&1), None); - } - - #[test] - fn test_from_iter() { - let xs = vec![(1u, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; - - let map: TrieMap = xs.iter().map(|&x| x).collect(); - - for &(k, v) in xs.iter() { - assert_eq!(map.get(&k), Some(&v)); - } - } - - #[test] - fn test_keys() { - let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; - let map = vec.into_iter().collect::>(); - let keys = map.keys().collect::>(); - assert_eq!(keys.len(), 3); - assert!(keys.contains(&1)); - assert!(keys.contains(&2)); - assert!(keys.contains(&3)); - } - - #[test] - fn test_values() { - let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; - let map = vec.into_iter().collect::>(); - let values = map.values().map(|&v| v).collect::>(); - assert_eq!(values.len(), 3); - assert!(values.contains(&'a')); - assert!(values.contains(&'b')); - assert!(values.contains(&'c')); - } - - #[test] - fn test_iteration() { - let empty_map : TrieMap = TrieMap::new(); - assert_eq!(empty_map.iter().next(), None); - - let first = uint::MAX - 10000; - let last = uint::MAX; - - let mut map = TrieMap::new(); - for x in range(first, last).rev() { - map.insert(x, x / 2); - } - - let mut i = 0; - for (k, &v) in map.iter() { - assert_eq!(k, first + i); - assert_eq!(v, k / 2); - i += 1; - } - assert_eq!(i, last - first); - } - - #[test] - fn test_mut_iter() { - let mut empty_map : TrieMap = TrieMap::new(); - assert!(empty_map.iter_mut().next().is_none()); - - let first = uint::MAX - 10000; - let last = uint::MAX; - - let mut map = TrieMap::new(); - for x in range(first, last).rev() { - map.insert(x, x / 2); - } - - let mut i = 0; - for (k, v) in map.iter_mut() { - assert_eq!(k, first + i); - *v -= k / 2; - i += 1; - } - assert_eq!(i, last - first); - - assert!(map.iter().all(|(_, &v)| v == 0)); - } - - #[test] - fn test_bound() { - let empty_map : TrieMap = TrieMap::new(); - assert_eq!(empty_map.lower_bound(0).next(), None); - assert_eq!(empty_map.upper_bound(0).next(), None); - - let last = 999u; - let step = 3u; - let value = 42u; - - let mut map : TrieMap = TrieMap::new(); - for x in range_step(0u, last, step) { - assert!(x % step == 0); - map.insert(x, value); - } - - for i in range(0u, last - step) { - let mut lb = map.lower_bound(i); - let mut ub = map.upper_bound(i); - let next_key = i - i % step + step; - let next_pair = (next_key, &value); - if i % step == 0 { - assert_eq!(lb.next(), Some((i, &value))); - } else { - assert_eq!(lb.next(), Some(next_pair)); - } - assert_eq!(ub.next(), Some(next_pair)); - } - - let mut lb = map.lower_bound(last - step); - assert_eq!(lb.next(), Some((last - step, &value))); - let mut ub = map.upper_bound(last - step); - assert_eq!(ub.next(), None); - - for i in range(last - step + 1, last) { - let mut lb = map.lower_bound(i); - assert_eq!(lb.next(), None); - let mut ub = map.upper_bound(i); - assert_eq!(ub.next(), None); - } - } - - #[test] - fn test_mut_bound() { - let empty_map : TrieMap = TrieMap::new(); - assert_eq!(empty_map.lower_bound(0).next(), None); - assert_eq!(empty_map.upper_bound(0).next(), None); - - let mut m_lower = TrieMap::new(); - let mut m_upper = TrieMap::new(); - for i in range(0u, 100) { - m_lower.insert(2 * i, 4 * i); - m_upper.insert(2 * i, 4 * i); - } - - for i in range(0u, 199) { - let mut lb_it = m_lower.lower_bound_mut(i); - let (k, v) = lb_it.next().unwrap(); - let lb = i + i % 2; - assert_eq!(lb, k); - *v -= k; - } - - for i in range(0u, 198) { - let mut ub_it = m_upper.upper_bound_mut(i); - let (k, v) = ub_it.next().unwrap(); - let ub = i + 2 - i % 2; - assert_eq!(ub, k); - *v -= k; - } - - assert!(m_lower.lower_bound_mut(199).next().is_none()); - assert!(m_upper.upper_bound_mut(198).next().is_none()); - - assert!(m_lower.iter().all(|(_, &x)| x == 0)); - assert!(m_upper.iter().all(|(_, &x)| x == 0)); - } - - #[test] - fn test_clone() { - let mut a = TrieMap::new(); - - a.insert(1, 'a'); - a.insert(2, 'b'); - a.insert(3, 'c'); - - assert!(a.clone() == a); - } - - #[test] - fn test_eq() { - let mut a = TrieMap::new(); - let mut b = TrieMap::new(); - - assert!(a == b); - assert!(a.insert(0, 5i).is_none()); - assert!(a != b); - assert!(b.insert(0, 4i).is_none()); - assert!(a != b); - assert!(a.insert(5, 19).is_none()); - assert!(a != b); - assert!(!b.insert(0, 5).is_none()); - assert!(a != b); - assert!(b.insert(5, 19).is_none()); - assert!(a == b); - } - - #[test] - fn test_lt() { - let mut a = TrieMap::new(); - let mut b = TrieMap::new(); - - assert!(!(a < b) && !(b < a)); - assert!(b.insert(2u, 5i).is_none()); - assert!(a < b); - assert!(a.insert(2, 7).is_none()); - assert!(!(a < b) && b < a); - assert!(b.insert(1, 0).is_none()); - assert!(b < a); - assert!(a.insert(0, 6).is_none()); - assert!(a < b); - assert!(a.insert(6, 2).is_none()); - assert!(a < b && !(b < a)); - } - - #[test] - fn test_ord() { - let mut a = TrieMap::new(); - let mut b = TrieMap::new(); - - assert!(a <= b && a >= b); - assert!(a.insert(1u, 1i).is_none()); - assert!(a > b && a >= b); - assert!(b < a && b <= a); - assert!(b.insert(2, 2).is_none()); - assert!(b > a && b >= a); - assert!(a < b && a <= b); - } - - #[test] - fn test_hash() { - let mut x = TrieMap::new(); - let mut y = TrieMap::new(); - - assert!(hash::hash(&x) == hash::hash(&y)); - x.insert(1, 'a'); - x.insert(2, 'b'); - x.insert(3, 'c'); - - y.insert(3, 'c'); - y.insert(2, 'b'); - y.insert(1, 'a'); - - assert!(hash::hash(&x) == hash::hash(&y)); - } - - #[test] - fn test_show() { - let mut map = TrieMap::new(); - let empty: TrieMap = TrieMap::new(); - - map.insert(1, 'a'); - map.insert(2, 'b'); - - let map_str = format!("{}", map); - - assert!(map_str == "{1: a, 2: b}"); - assert_eq!(format!("{}", empty), "{}"); - } - - #[test] - fn test_index() { - let mut map = TrieMap::new(); - - map.insert(1, 2i); - map.insert(2, 1i); - map.insert(3, 4i); - - assert_eq!(map[2], 1); - } - - #[test] - #[should_fail] - fn test_index_nonexistent() { - let mut map = TrieMap::new(); - - map.insert(1, 2i); - map.insert(2, 1i); - map.insert(3, 4i); - - map[4]; - } - - // Number of items to insert into the map during entry tests. - // The tests rely on it being even. - const SQUARES_UPPER_LIM: uint = 128; - - /// Make a TrieMap storing i^2 for i in [0, 128) - fn squares_map() -> TrieMap { - let mut map = TrieMap::new(); - for i in range(0, SQUARES_UPPER_LIM) { - map.insert(i, i * i); - } - map - } - - #[test] - fn test_entry_get() { - let mut map = squares_map(); - - for i in range(0, SQUARES_UPPER_LIM) { - match map.entry(i) { - Occupied(slot) => assert_eq!(slot.get(), &(i * i)), - Vacant(_) => panic!("Key not found.") - } - } - check_integrity(&map.root); - } - - #[test] - fn test_entry_get_mut() { - let mut map = squares_map(); - - // Change the entries to cubes. - for i in range(0, SQUARES_UPPER_LIM) { - match map.entry(i) { - Occupied(mut e) => { - *e.get_mut() = i * i * i; - } - Vacant(_) => panic!("Key not found.") - } - assert_eq!(map.get(&i).unwrap(), &(i * i * i)); - } - - check_integrity(&map.root); - } - - #[test] - fn test_entry_into_mut() { - let mut map = TrieMap::new(); - map.insert(3, 6u); - - let value_ref = match map.entry(3) { - Occupied(e) => e.into_mut(), - Vacant(_) => panic!("Entry not found.") - }; - - assert_eq!(*value_ref, 6u); - } - - #[test] - fn test_entry_take() { - let mut map = squares_map(); - assert_eq!(map.len(), SQUARES_UPPER_LIM); - - // Remove every odd key, checking that the correct value is returned. - for i in range_step(1, SQUARES_UPPER_LIM, 2) { - match map.entry(i) { - Occupied(e) => assert_eq!(e.take(), i * i), - Vacant(_) => panic!("Key not found.") - } - } - - check_integrity(&map.root); - - // Check that the values for even keys remain unmodified. - for i in range_step(0, SQUARES_UPPER_LIM, 2) { - assert_eq!(map.get(&i).unwrap(), &(i * i)); - } - - assert_eq!(map.len(), SQUARES_UPPER_LIM / 2); - } - - #[test] - fn test_occupied_entry_set() { - let mut map = squares_map(); - - // Change all the entries to cubes. - for i in range(0, SQUARES_UPPER_LIM) { - match map.entry(i) { - Occupied(mut e) => assert_eq!(e.set(i * i * i), i * i), - Vacant(_) => panic!("Key not found.") - } - assert_eq!(map.get(&i).unwrap(), &(i * i * i)); - } - check_integrity(&map.root); - } - - #[test] - fn test_vacant_entry_set() { - let mut map = TrieMap::new(); - - for i in range(0, SQUARES_UPPER_LIM) { - match map.entry(i) { - Vacant(e) => { - // Insert i^2. - let inserted_val = e.set(i * i); - assert_eq!(*inserted_val, i * i); - - // Update it to i^3 using the returned mutable reference. - *inserted_val = i * i * i; - }, - _ => panic!("Non-existent key found.") - } - assert_eq!(map.get(&i).unwrap(), &(i * i * i)); - } - - check_integrity(&map.root); - assert_eq!(map.len(), SQUARES_UPPER_LIM); - } - - #[test] - fn test_single_key() { - let mut map = TrieMap::new(); - map.insert(1, 2u); - - match map.entry(1) { - Occupied(e) => { e.take(); }, - _ => () - } - } -} - -#[cfg(test)] -mod bench { - use std::prelude::*; - use std::rand::{weak_rng, Rng}; - use test::{Bencher, black_box}; - - use super::{TrieMap, Occupied, Vacant}; - - const MAP_SIZE: uint = 1000; - - fn random_map(size: uint) -> TrieMap { - let mut map = TrieMap::::new(); - let mut rng = weak_rng(); - - for _ in range(0, size) { - map.insert(rng.gen(), rng.gen()); - } - map - } - - fn bench_iter(b: &mut Bencher, size: uint) { - let map = random_map(size); - b.iter(|| { - for entry in map.iter() { - black_box(entry); - } - }); - } - - #[bench] - pub fn iter_20(b: &mut Bencher) { - bench_iter(b, 20); - } - - #[bench] - pub fn iter_1000(b: &mut Bencher) { - bench_iter(b, 1000); - } - - #[bench] - pub fn iter_100000(b: &mut Bencher) { - bench_iter(b, 100000); - } - - #[bench] - fn bench_lower_bound(b: &mut Bencher) { - let mut m = TrieMap::::new(); - let mut rng = weak_rng(); - for _ in range(0u, MAP_SIZE) { - m.insert(rng.gen(), rng.gen()); - } - - b.iter(|| { - for _ in range(0u, 10) { - m.lower_bound(rng.gen()); - } - }); - } - - #[bench] - fn bench_upper_bound(b: &mut Bencher) { - let mut m = TrieMap::::new(); - let mut rng = weak_rng(); - for _ in range(0u, MAP_SIZE) { - m.insert(rng.gen(), rng.gen()); - } - - b.iter(|| { - for _ in range(0u, 10) { - m.upper_bound(rng.gen()); - } - }); - } - - #[bench] - fn bench_insert_large(b: &mut Bencher) { - let mut m = TrieMap::<[uint, .. 10]>::new(); - let mut rng = weak_rng(); - - b.iter(|| { - for _ in range(0u, MAP_SIZE) { - m.insert(rng.gen(), [1, .. 10]); - } - }); - } - - #[bench] - fn bench_insert_large_entry(b: &mut Bencher) { - let mut m = TrieMap::<[uint, .. 10]>::new(); - let mut rng = weak_rng(); - - b.iter(|| { - for _ in range(0u, MAP_SIZE) { - match m.entry(rng.gen()) { - Occupied(mut e) => { e.set([1, ..10]); }, - Vacant(e) => { e.set([1, ..10]); } - } - } - }); - } - - #[bench] - fn bench_insert_large_low_bits(b: &mut Bencher) { - let mut m = TrieMap::<[uint, .. 10]>::new(); - let mut rng = weak_rng(); - - b.iter(|| { - for _ in range(0u, MAP_SIZE) { - // only have the last few bits set. - m.insert(rng.gen::() & 0xff_ff, [1, .. 10]); - } - }); - } - - #[bench] - fn bench_insert_small(b: &mut Bencher) { - let mut m = TrieMap::<()>::new(); - let mut rng = weak_rng(); - - b.iter(|| { - for _ in range(0u, MAP_SIZE) { - m.insert(rng.gen(), ()); - } - }); - } - - #[bench] - fn bench_insert_small_low_bits(b: &mut Bencher) { - let mut m = TrieMap::<()>::new(); - let mut rng = weak_rng(); - - b.iter(|| { - for _ in range(0u, MAP_SIZE) { - // only have the last few bits set. - m.insert(rng.gen::() & 0xff_ff, ()); - } - }); - } - - #[bench] - fn bench_get(b: &mut Bencher) { - let map = random_map(MAP_SIZE); - let keys: Vec = map.keys().collect(); - b.iter(|| { - for key in keys.iter() { - black_box(map.get(key)); - } - }); - } - - #[bench] - fn bench_get_entry(b: &mut Bencher) { - let mut map = random_map(MAP_SIZE); - let keys: Vec = map.keys().collect(); - b.iter(|| { - for key in keys.iter() { - match map.entry(*key) { - Occupied(e) => { black_box(e.get()); }, - _ => () - } - } - }); - } - - #[bench] - fn bench_remove(b: &mut Bencher) { - b.iter(|| { - let mut map = random_map(MAP_SIZE); - let keys: Vec = map.keys().collect(); - for key in keys.iter() { - black_box(map.remove(key)); - } - }); - } - - #[bench] - fn bench_remove_entry(b: &mut Bencher) { - b.iter(|| { - let mut map = random_map(MAP_SIZE); - let keys: Vec = map.keys().collect(); - for key in keys.iter() { - match map.entry(*key) { - Occupied(e) => { black_box(e.take()); }, - _ => () - } - } - }); - } -} diff --git a/src/libcollections/trie/mod.rs b/src/libcollections/trie/mod.rs deleted file mode 100644 index 4d9191a65b695..0000000000000 --- a/src/libcollections/trie/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Maps are collections of unique keys with corresponding values, and sets are -//! just unique keys without a corresponding value. -//! -//! This crate defines `TrieMap` and `TrieSet`, which require `uint` keys. -//! -//! `TrieMap` is ordered. - -pub mod map; -pub mod set; diff --git a/src/libcollections/trie/set.rs b/src/libcollections/trie/set.rs deleted file mode 100644 index 5d24673ae751c..0000000000000 --- a/src/libcollections/trie/set.rs +++ /dev/null @@ -1,972 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// FIXME(conventions): implement bounded iterators -// FIXME(conventions): replace each_reverse by making iter DoubleEnded -// FIXME(conventions): implement iter_mut and into_iter - -use core::prelude::*; - -use core::default::Default; -use core::fmt; -use core::fmt::Show; -use core::iter::Peekable; -use std::hash::Hash; - -use trie_map::{TrieMap, Entries}; - -/// A set implemented as a radix trie. -/// -/// # Examples -/// -/// ``` -/// use std::collections::TrieSet; -/// -/// let mut set = TrieSet::new(); -/// set.insert(6); -/// set.insert(28); -/// set.insert(6); -/// -/// assert_eq!(set.len(), 2); -/// -/// if !set.contains(&3) { -/// println!("3 is not in the set"); -/// } -/// -/// // Print contents in order -/// for x in set.iter() { -/// println!("{}", x); -/// } -/// -/// set.remove(&6); -/// assert_eq!(set.len(), 1); -/// -/// set.clear(); -/// assert!(set.is_empty()); -/// ``` -#[deriving(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -pub struct TrieSet { - map: TrieMap<()> -} - -impl Show for TrieSet { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, x) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{}", x)); - } - - write!(f, "}}") - } -} - -#[stable] -impl Default for TrieSet { - #[inline] - #[stable] - fn default() -> TrieSet { TrieSet::new() } -} - -impl TrieSet { - /// Creates an empty TrieSet. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// let mut set = TrieSet::new(); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn new() -> TrieSet { - TrieSet{map: TrieMap::new()} - } - - /// Visits all values in reverse order. Aborts traversal when `f` returns `false`. - /// Returns `true` if `f` returns `true` for all elements. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let set: TrieSet = [1, 2, 3, 4, 5].iter().map(|&x| x).collect(); - /// - /// let mut vec = Vec::new(); - /// assert_eq!(true, set.each_reverse(|&x| { vec.push(x); true })); - /// assert_eq!(vec, vec![5, 4, 3, 2, 1]); - /// - /// // Stop when we reach 3 - /// let mut vec = Vec::new(); - /// assert_eq!(false, set.each_reverse(|&x| { vec.push(x); x != 3 })); - /// assert_eq!(vec, vec![5, 4, 3]); - /// ``` - #[inline] - pub fn each_reverse(&self, f: |&uint| -> bool) -> bool { - self.map.each_reverse(|k, _| f(k)) - } - - /// Gets an iterator over the values in the set, in sorted order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let mut set = TrieSet::new(); - /// set.insert(3); - /// set.insert(2); - /// set.insert(1); - /// set.insert(2); - /// - /// // Print 1, 2, 3 - /// for x in set.iter() { - /// println!("{}", x); - /// } - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn iter<'a>(&'a self) -> SetItems<'a> { - SetItems{iter: self.map.iter()} - } - - /// Gets an iterator pointing to the first value that is not less than `val`. - /// If all values in the set are less than `val` an empty iterator is returned. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect(); - /// assert_eq!(set.lower_bound(4).next(), Some(4)); - /// assert_eq!(set.lower_bound(5).next(), Some(6)); - /// assert_eq!(set.lower_bound(10).next(), None); - /// ``` - pub fn lower_bound<'a>(&'a self, val: uint) -> SetItems<'a> { - SetItems{iter: self.map.lower_bound(val)} - } - - /// Gets an iterator pointing to the first value that key is greater than `val`. - /// If all values in the set are less than or equal to `val` an empty iterator is returned. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect(); - /// assert_eq!(set.upper_bound(4).next(), Some(6)); - /// assert_eq!(set.upper_bound(5).next(), Some(6)); - /// assert_eq!(set.upper_bound(10).next(), None); - /// ``` - pub fn upper_bound<'a>(&'a self, val: uint) -> SetItems<'a> { - SetItems{iter: self.map.upper_bound(val)} - } - - /// Visits the values representing the difference, in ascending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TrieSet = [3, 4, 5].iter().map(|&x| x).collect(); - /// - /// // Can be seen as `a - b`. - /// for x in a.difference(&b) { - /// println!("{}", x); // Print 1 then 2 - /// } - /// - /// let diff1: TrieSet = a.difference(&b).collect(); - /// assert_eq!(diff1, [1, 2].iter().map(|&x| x).collect()); - /// - /// // Note that difference is not symmetric, - /// // and `b - a` means something else: - /// let diff2: TrieSet = b.difference(&a).collect(); - /// assert_eq!(diff2, [4, 5].iter().map(|&x| x).collect()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn difference<'a>(&'a self, other: &'a TrieSet) -> DifferenceItems<'a> { - DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Visits the values representing the symmetric difference, in ascending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TrieSet = [3, 4, 5].iter().map(|&x| x).collect(); - /// - /// // Print 1, 2, 4, 5 in ascending order. - /// for x in a.symmetric_difference(&b) { - /// println!("{}", x); - /// } - /// - /// let diff1: TrieSet = a.symmetric_difference(&b).collect(); - /// let diff2: TrieSet = b.symmetric_difference(&a).collect(); - /// - /// assert_eq!(diff1, diff2); - /// assert_eq!(diff1, [1, 2, 4, 5].iter().map(|&x| x).collect()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle."] - pub fn symmetric_difference<'a>(&'a self, other: &'a TrieSet) -> SymDifferenceItems<'a> { - SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Visits the values representing the intersection, in ascending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TrieSet = [2, 3, 4].iter().map(|&x| x).collect(); - /// - /// // Print 2, 3 in ascending order. - /// for x in a.intersection(&b) { - /// println!("{}", x); - /// } - /// - /// let diff: TrieSet = a.intersection(&b).collect(); - /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn intersection<'a>(&'a self, other: &'a TrieSet) -> IntersectionItems<'a> { - IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Visits the values representing the union, in ascending order. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: TrieSet = [3, 4, 5].iter().map(|&x| x).collect(); - /// - /// // Print 1, 2, 3, 4, 5 in ascending order. - /// for x in a.union(&b) { - /// println!("{}", x); - /// } - /// - /// let diff: TrieSet = a.union(&b).collect(); - /// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn union<'a>(&'a self, other: &'a TrieSet) -> UnionItems<'a> { - UnionItems{a: self.iter().peekable(), b: other.iter().peekable()} - } - - /// Return the number of elements in the set - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let mut v = TrieSet::new(); - /// assert_eq!(v.len(), 0); - /// v.insert(1); - /// assert_eq!(v.len(), 1); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn len(&self) -> uint { self.map.len() } - - /// Returns true if the set contains no elements - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let mut v = TrieSet::new(); - /// assert!(v.is_empty()); - /// v.insert(1); - /// assert!(!v.is_empty()); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn is_empty(&self) -> bool { self.len() == 0 } - - /// Clears the set, removing all values. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let mut v = TrieSet::new(); - /// v.insert(1); - /// v.clear(); - /// assert!(v.is_empty()); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn clear(&mut self) { self.map.clear() } - - /// Returns `true` if the set contains a value. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let set: TrieSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// assert_eq!(set.contains(&1), true); - /// assert_eq!(set.contains(&4), false); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains(&self, value: &uint) -> bool { - self.map.contains_key(value) - } - - /// Returns `true` if the set has no elements in common with `other`. - /// This is equivalent to checking for an empty intersection. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let mut b: TrieSet = TrieSet::new(); - /// - /// assert_eq!(a.is_disjoint(&b), true); - /// b.insert(4); - /// assert_eq!(a.is_disjoint(&b), true); - /// b.insert(1); - /// assert_eq!(a.is_disjoint(&b), false); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn is_disjoint(&self, other: &TrieSet) -> bool { - self.iter().all(|v| !other.contains(&v)) - } - - /// Returns `true` if the set is a subset of another. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let sup: TrieSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let mut set: TrieSet = TrieSet::new(); - /// - /// assert_eq!(set.is_subset(&sup), true); - /// set.insert(2); - /// assert_eq!(set.is_subset(&sup), true); - /// set.insert(4); - /// assert_eq!(set.is_subset(&sup), false); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn is_subset(&self, other: &TrieSet) -> bool { - self.iter().all(|v| other.contains(&v)) - } - - /// Returns `true` if the set is a superset of another. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let sub: TrieSet = [1, 2].iter().map(|&x| x).collect(); - /// let mut set: TrieSet = TrieSet::new(); - /// - /// assert_eq!(set.is_superset(&sub), false); - /// - /// set.insert(0); - /// set.insert(1); - /// assert_eq!(set.is_superset(&sub), false); - /// - /// set.insert(2); - /// assert_eq!(set.is_superset(&sub), true); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn is_superset(&self, other: &TrieSet) -> bool { - other.is_subset(self) - } - - /// Adds a value to the set. Returns `true` if the value was not already - /// present in the set. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let mut set = TrieSet::new(); - /// - /// assert_eq!(set.insert(2), true); - /// assert_eq!(set.insert(2), false); - /// assert_eq!(set.len(), 1); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn insert(&mut self, value: uint) -> bool { - self.map.insert(value, ()).is_none() - } - - /// Removes a value from the set. Returns `true` if the value was - /// present in the set. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let mut set = TrieSet::new(); - /// - /// set.insert(2); - /// assert_eq!(set.remove(&2), true); - /// assert_eq!(set.remove(&2), false); - /// ``` - #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, value: &uint) -> bool { - self.map.remove(value).is_some() - } -} - -impl FromIterator for TrieSet { - fn from_iter>(iter: Iter) -> TrieSet { - let mut set = TrieSet::new(); - set.extend(iter); - set - } -} - -impl Extend for TrieSet { - fn extend>(&mut self, mut iter: Iter) { - for elem in iter { - self.insert(elem); - } - } -} - -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -#[unstable = "matches collection reform specification, waiting for dust to settle"] -impl BitOr for TrieSet { - /// Returns the union of `self` and `rhs` as a new `TrieSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TrieSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TrieSet = a | b; - /// let v: Vec = set.iter().collect(); - /// assert_eq!(v, vec![1u, 2, 3, 4, 5]); - /// ``` - fn bitor(&self, rhs: &TrieSet) -> TrieSet { - self.union(rhs).collect() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot -#[unstable = "matches collection reform specification, waiting for dust to settle"] -impl<'a, 'b> BitOr<&'b TrieSet, TrieSet> for &'a TrieSet { - /// Returns the union of `self` and `rhs` as a new `TrieSet`. - /// - /// # Example - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TrieSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TrieSet = &a | &b; - /// let v: Vec = set.iter().collect(); - /// assert_eq!(v, vec![1u, 2, 3, 4, 5]); - /// ``` - fn bitor(self, rhs: &TrieSet) -> TrieSet { - self.union(rhs).collect() - } -} - -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -#[unstable = "matches collection reform specification, waiting for dust to settle"] -impl BitAnd for TrieSet { - /// Returns the intersection of `self` and `rhs` as a new `TrieSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TrieSet = vec![2, 3, 4].into_iter().collect(); - /// - /// let set: TrieSet = a & b; - /// let v: Vec = set.iter().collect(); - /// assert_eq!(v, vec![2u, 3]); - /// ``` - fn bitand(&self, rhs: &TrieSet) -> TrieSet { - self.intersection(rhs).collect() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot -#[unstable = "matches collection reform specification, waiting for dust to settle"] -impl<'a, 'b> BitAnd<&'b TrieSet, TrieSet> for &'a TrieSet { - /// Returns the intersection of `self` and `rhs` as a new `TrieSet`. - /// - /// # Example - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TrieSet = vec![2, 3, 4].into_iter().collect(); - /// - /// let set: TrieSet = &a & &b; - /// let v: Vec = set.iter().collect(); - /// assert_eq!(v, vec![2u, 3]); - /// ``` - fn bitand(self, rhs: &TrieSet) -> TrieSet { - self.intersection(rhs).collect() - } -} - -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -#[unstable = "matches collection reform specification, waiting for dust to settle"] -impl BitXor for TrieSet { - /// Returns the symmetric difference of `self` and `rhs` as a new `TrieSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TrieSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TrieSet = a ^ b; - /// let v: Vec = set.iter().collect(); - /// assert_eq!(v, vec![1u, 2, 4, 5]); - /// ``` - fn bitxor(&self, rhs: &TrieSet) -> TrieSet { - self.symmetric_difference(rhs).collect() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot -#[unstable = "matches collection reform specification, waiting for dust to settle"] -impl<'a, 'b> BitXor<&'b TrieSet, TrieSet> for &'a TrieSet { - /// Returns the symmetric difference of `self` and `rhs` as a new `TrieSet`. - /// - /// # Example - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TrieSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TrieSet = &a ^ &b; - /// let v: Vec = set.iter().collect(); - /// assert_eq!(v, vec![1u, 2, 4, 5]); - /// ``` - fn bitxor(self, rhs: &TrieSet) -> TrieSet { - self.symmetric_difference(rhs).collect() - } -} - -// NOTE(stage0): Remove impl after a snapshot -#[cfg(stage0)] -#[unstable = "matches collection reform specification, waiting for dust to settle"] -impl Sub for TrieSet { - /// Returns the difference of `self` and `rhs` as a new `TrieSet`. - /// - /// # Examples - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TrieSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TrieSet = a - b; - /// let v: Vec = set.iter().collect(); - /// assert_eq!(v, vec![1u, 2]); - /// ``` - fn sub(&self, rhs: &TrieSet) -> TrieSet { - self.difference(rhs).collect() - } -} - -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot -#[unstable = "matches collection reform specification, waiting for dust to settle"] -impl<'a, 'b> Sub<&'b TrieSet, TrieSet> for &'a TrieSet { - /// Returns the difference of `self` and `rhs` as a new `TrieSet`. - /// - /// # Example - /// - /// ``` - /// use std::collections::TrieSet; - /// - /// let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - /// let b: TrieSet = vec![3, 4, 5].into_iter().collect(); - /// - /// let set: TrieSet = &a - &b; - /// let v: Vec = set.iter().collect(); - /// assert_eq!(v, vec![1u, 2]); - /// ``` - fn sub(self, rhs: &TrieSet) -> TrieSet { - self.difference(rhs).collect() - } -} - -/// A forward iterator over a set. -pub struct SetItems<'a> { - iter: Entries<'a, ()> -} - -/// An iterator producing elements in the set difference (in-order). -pub struct DifferenceItems<'a> { - a: Peekable>, - b: Peekable>, -} - -/// An iterator producing elements in the set symmetric difference (in-order). -pub struct SymDifferenceItems<'a> { - a: Peekable>, - b: Peekable>, -} - -/// An iterator producing elements in the set intersection (in-order). -pub struct IntersectionItems<'a> { - a: Peekable>, - b: Peekable>, -} - -/// An iterator producing elements in the set union (in-order). -pub struct UnionItems<'a> { - a: Peekable>, - b: Peekable>, -} - -/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None -fn cmp_opt(x: Option<&uint>, y: Option<&uint>, short: Ordering, long: Ordering) -> Ordering { - match (x, y) { - (None , _ ) => short, - (_ , None ) => long, - (Some(x1), Some(y1)) => x1.cmp(y1), - } -} - -impl<'a> Iterator for SetItems<'a> { - fn next(&mut self) -> Option { - self.iter.next().map(|(key, _)| key) - } - - fn size_hint(&self) -> (uint, Option) { - self.iter.size_hint() - } -} - -impl<'a> Iterator for DifferenceItems<'a> { - fn next(&mut self) -> Option { - loop { - match cmp_opt(self.a.peek(), self.b.peek(), Less, Less) { - Less => return self.a.next(), - Equal => { self.a.next(); self.b.next(); } - Greater => { self.b.next(); } - } - } - } -} - -impl<'a> Iterator for SymDifferenceItems<'a> { - fn next(&mut self) -> Option { - loop { - match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) { - Less => return self.a.next(), - Equal => { self.a.next(); self.b.next(); } - Greater => return self.b.next(), - } - } - } -} - -impl<'a> Iterator for IntersectionItems<'a> { - fn next(&mut self) -> Option { - loop { - let o_cmp = match (self.a.peek(), self.b.peek()) { - (None , _ ) => None, - (_ , None ) => None, - (Some(a1), Some(b1)) => Some(a1.cmp(b1)), - }; - match o_cmp { - None => return None, - Some(Less) => { self.a.next(); } - Some(Equal) => { self.b.next(); return self.a.next() } - Some(Greater) => { self.b.next(); } - } - } - } -} - -impl<'a> Iterator for UnionItems<'a> { - fn next(&mut self) -> Option { - 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(), - } - } - } -} - -#[cfg(test)] -mod test { - use std::prelude::*; - use std::uint; - use vec::Vec; - - use super::TrieSet; - - #[test] - fn test_sane_chunk() { - let x = 1; - let y = 1 << (uint::BITS - 1); - - let mut trie = TrieSet::new(); - - assert!(trie.insert(x)); - assert!(trie.insert(y)); - - assert_eq!(trie.len(), 2); - - let expected = [x, y]; - - for (i, x) in trie.iter().enumerate() { - assert_eq!(expected[i], x); - } - } - - #[test] - fn test_from_iter() { - let xs = vec![9u, 8, 7, 6, 5, 4, 3, 2, 1]; - - let set: TrieSet = xs.iter().map(|&x| x).collect(); - - for x in xs.iter() { - assert!(set.contains(x)); - } - } - - #[test] - fn test_show() { - let mut set = TrieSet::new(); - let empty = TrieSet::new(); - - set.insert(1); - set.insert(2); - - let set_str = format!("{}", set); - - assert!(set_str == "{1, 2}"); - assert_eq!(format!("{}", empty), "{}"); - } - - #[test] - fn test_clone() { - let mut a = TrieSet::new(); - - a.insert(1); - a.insert(2); - a.insert(3); - - assert!(a.clone() == a); - } - - #[test] - fn test_lt() { - let mut a = TrieSet::new(); - let mut b = TrieSet::new(); - - assert!(!(a < b) && !(b < a)); - assert!(b.insert(2u)); - assert!(a < b); - assert!(a.insert(3u)); - assert!(!(a < b) && b < a); - assert!(b.insert(1)); - assert!(b < a); - assert!(a.insert(0)); - assert!(a < b); - assert!(a.insert(6)); - assert!(a < b && !(b < a)); - } - - #[test] - fn test_ord() { - let mut a = TrieSet::new(); - let mut b = TrieSet::new(); - - assert!(a <= b && a >= b); - assert!(a.insert(1u)); - assert!(a > b && a >= b); - assert!(b < a && b <= a); - assert!(b.insert(2u)); - assert!(b > a && b >= a); - assert!(a < b && a <= b); - } - - struct Counter<'a, 'b> { - i: &'a mut uint, - expected: &'b [uint], - } - - impl<'a, 'b> FnMut(uint) -> bool for Counter<'a, 'b> { - extern "rust-call" fn call_mut(&mut self, (x,): (uint,)) -> bool { - assert_eq!(x, self.expected[*self.i]); - *self.i += 1; - true - } - } - - fn check(a: &[uint], b: &[uint], expected: &[uint], f: F) where - // FIXME Replace `Counter` with `Box bool>` - F: FnOnce(&TrieSet, &TrieSet, Counter) -> bool, - { - let mut set_a = TrieSet::new(); - let mut set_b = TrieSet::new(); - - for x in a.iter() { assert!(set_a.insert(*x)) } - for y in b.iter() { assert!(set_b.insert(*y)) } - - let mut i = 0; - f(&set_a, &set_b, Counter { i: &mut i, expected: expected }); - assert_eq!(i, expected.len()); - } - - #[test] - fn test_intersection() { - fn check_intersection(a: &[uint], b: &[uint], expected: &[uint]) { - check(a, b, expected, |x, y, f| x.intersection(y).all(f)) - } - - check_intersection(&[], &[], &[]); - check_intersection(&[1, 2, 3], &[], &[]); - check_intersection(&[], &[1, 2, 3], &[]); - check_intersection(&[2], &[1, 2, 3], &[2]); - check_intersection(&[1, 2, 3], &[2], &[2]); - check_intersection(&[11, 1, 3, 77, 103, 5], - &[2, 11, 77, 5, 3], - &[3, 5, 11, 77]); - } - - #[test] - fn test_difference() { - fn check_difference(a: &[uint], b: &[uint], expected: &[uint]) { - check(a, b, expected, |x, y, f| x.difference(y).all(f)) - } - - check_difference(&[], &[], &[]); - check_difference(&[1, 12], &[], &[1, 12]); - check_difference(&[], &[1, 2, 3, 9], &[]); - check_difference(&[1, 3, 5, 9, 11], - &[3, 9], - &[1, 5, 11]); - check_difference(&[11, 22, 33, 40, 42], - &[14, 23, 34, 38, 39, 50], - &[11, 22, 33, 40, 42]); - } - - #[test] - fn test_symmetric_difference() { - fn check_symmetric_difference(a: &[uint], b: &[uint], expected: &[uint]) { - check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f)) - } - - check_symmetric_difference(&[], &[], &[]); - check_symmetric_difference(&[1, 2, 3], &[2], &[1, 3]); - check_symmetric_difference(&[2], &[1, 2, 3], &[1, 3]); - check_symmetric_difference(&[1, 3, 5, 9, 11], - &[3, 9, 14, 22], - &[1, 5, 11, 14, 22]); - } - - #[test] - fn test_union() { - fn check_union(a: &[uint], b: &[uint], expected: &[uint]) { - check(a, b, expected, |x, y, f| x.union(y).all(f)) - } - - check_union(&[], &[], &[]); - check_union(&[1, 2, 3], &[2], &[1, 2, 3]); - check_union(&[2], &[1, 2, 3], &[1, 2, 3]); - check_union(&[1, 3, 5, 9, 11, 16, 19, 24], - &[1, 5, 9, 13, 19], - &[1, 3, 5, 9, 11, 13, 16, 19, 24]); - } - - #[test] - fn test_bit_or() { - let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - let b: TrieSet = vec![3, 4, 5].into_iter().collect(); - - let set: TrieSet = &a | &b; - let v: Vec = set.iter().collect(); - assert_eq!(v, vec![1u, 2, 3, 4, 5]); - } - - #[test] - fn test_bit_and() { - let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - let b: TrieSet = vec![2, 3, 4].into_iter().collect(); - - let set: TrieSet = &a & &b; - let v: Vec = set.iter().collect(); - assert_eq!(v, vec![2u, 3]); - } - - #[test] - fn test_bit_xor() { - let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - let b: TrieSet = vec![3, 4, 5].into_iter().collect(); - - let set: TrieSet = &a ^ &b; - let v: Vec = set.iter().collect(); - assert_eq!(v, vec![1u, 2, 4, 5]); - } - - #[test] - fn test_sub() { - let a: TrieSet = vec![1, 2, 3].into_iter().collect(); - let b: TrieSet = vec![3, 4, 5].into_iter().collect(); - - let set: TrieSet = &a - &b; - let v: Vec = set.iter().collect(); - assert_eq!(v, vec![1u, 2]); - } -} diff --git a/src/libstd/collections/lru_cache.rs b/src/libstd/collections/lru_cache.rs deleted file mode 100644 index 6caa2f7b4da6a..0000000000000 --- a/src/libstd/collections/lru_cache.rs +++ /dev/null @@ -1,471 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - -//! A cache that holds a limited number of key-value pairs. When the -//! capacity of the cache is exceeded, the least-recently-used -//! (where "used" means a look-up or putting the pair into the cache) -//! pair is automatically removed. -//! -//! # Example -//! -//! ```rust -//! use std::collections::LruCache; -//! -//! let mut cache: LruCache = LruCache::new(2); -//! cache.insert(1, 10); -//! cache.insert(2, 20); -//! cache.insert(3, 30); -//! assert!(cache.get(&1).is_none()); -//! assert_eq!(*cache.get(&2).unwrap(), 20); -//! assert_eq!(*cache.get(&3).unwrap(), 30); -//! -//! cache.insert(2, 22); -//! assert_eq!(*cache.get(&2).unwrap(), 22); -//! -//! cache.insert(6, 60); -//! assert!(cache.get(&3).is_none()); -//! -//! cache.set_capacity(1); -//! assert!(cache.get(&2).is_none()); -//! ``` - -use cmp::{PartialEq, Eq}; -use collections::HashMap; -use fmt; -use hash::Hash; -use iter::{range, Iterator, Extend}; -use mem; -use ops::Drop; -use option::Option; -use option::Option::{Some, None}; -use boxed::Box; -use ptr; -use result::Result::{Ok, Err}; - -// FIXME(conventions): implement iterators? -// FIXME(conventions): implement indexing? - -struct KeyRef { k: *const K } - -struct LruEntry { - next: *mut LruEntry, - prev: *mut LruEntry, - key: K, - value: V, -} - -/// An LRU Cache. -pub struct LruCache { - map: HashMap, Box>>, - max_size: uint, - head: *mut LruEntry, -} - -impl> Hash for KeyRef { - fn hash(&self, state: &mut S) { - unsafe { (*self.k).hash(state) } - } -} - -impl PartialEq for KeyRef { - fn eq(&self, other: &KeyRef) -> bool { - unsafe{ (*self.k).eq(&*other.k) } - } -} - -impl Eq for KeyRef {} - -impl LruEntry { - fn new(k: K, v: V) -> LruEntry { - LruEntry { - key: k, - value: v, - next: ptr::null_mut(), - prev: ptr::null_mut(), - } - } -} - -impl LruCache { - /// Create an LRU Cache that holds at most `capacity` items. - /// - /// # Example - /// - /// ``` - /// use std::collections::LruCache; - /// let mut cache: LruCache = LruCache::new(10); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn new(capacity: uint) -> LruCache { - let cache = LruCache { - map: HashMap::new(), - max_size: capacity, - head: unsafe{ mem::transmute(box mem::uninitialized::>()) }, - }; - unsafe { - (*cache.head).next = cache.head; - (*cache.head).prev = cache.head; - } - return cache; - } - - /// Deprecated: Replaced with `insert`. - #[deprecated = "Replaced with `insert`"] - pub fn put(&mut self, k: K, v: V) { - self.insert(k, v); - } - - /// Inserts a key-value pair into the cache. If the key already existed, the old value is - /// returned. - /// - /// # Example - /// - /// ``` - /// use std::collections::LruCache; - /// let mut cache = LruCache::new(2); - /// - /// cache.insert(1i, "a"); - /// cache.insert(2, "b"); - /// assert_eq!(cache.get(&1), Some(&"a")); - /// assert_eq!(cache.get(&2), Some(&"b")); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn insert(&mut self, k: K, v: V) -> Option { - let (node_ptr, node_opt, old_val) = match self.map.get_mut(&KeyRef{k: &k}) { - Some(node) => { - let old_val = mem::replace(&mut node.value, v); - let node_ptr: *mut LruEntry = &mut **node; - (node_ptr, None, Some(old_val)) - } - None => { - let mut node = box LruEntry::new(k, v); - let node_ptr: *mut LruEntry = &mut *node; - (node_ptr, Some(node), None) - } - }; - match node_opt { - None => { - // Existing node, just update LRU position - self.detach(node_ptr); - self.attach(node_ptr); - } - Some(node) => { - let keyref = unsafe { &(*node_ptr).key }; - self.map.insert(KeyRef{k: keyref}, node); - self.attach(node_ptr); - if self.len() > self.capacity() { - self.remove_lru(); - } - } - } - old_val - } - - /// Return a value corresponding to the key in the cache. - /// - /// # Example - /// - /// ``` - /// use std::collections::LruCache; - /// let mut cache = LruCache::new(2); - /// - /// cache.insert(1i, "a"); - /// cache.insert(2, "b"); - /// cache.insert(2, "c"); - /// cache.insert(3, "d"); - /// - /// assert_eq!(cache.get(&1), None); - /// assert_eq!(cache.get(&2), Some(&"c")); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get(&mut self, k: &K) -> Option<&V> { - let (value, node_ptr_opt) = match self.map.get_mut(&KeyRef{k: k}) { - None => (None, None), - Some(node) => { - let node_ptr: *mut LruEntry = &mut **node; - (Some(unsafe { &(*node_ptr).value }), Some(node_ptr)) - } - }; - match node_ptr_opt { - None => (), - Some(node_ptr) => { - self.detach(node_ptr); - self.attach(node_ptr); - } - } - return value; - } - - /// Deprecated: Renamed to `remove`. - #[deprecated = "Renamed to `remove`"] - pub fn pop(&mut self, k: &K) -> Option { - self.remove(k) - } - - /// Remove and return a value corresponding to the key from the cache. - /// - /// # Example - /// - /// ``` - /// use std::collections::LruCache; - /// let mut cache = LruCache::new(2); - /// - /// cache.insert(2i, "a"); - /// - /// assert_eq!(cache.remove(&1), None); - /// assert_eq!(cache.remove(&2), Some("a")); - /// assert_eq!(cache.remove(&2), None); - /// assert_eq!(cache.len(), 0); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, k: &K) -> Option { - match self.map.remove(&KeyRef{k: k}) { - None => None, - Some(lru_entry) => Some(lru_entry.value) - } - } - - /// Return the maximum number of key-value pairs the cache can hold. - /// - /// # Example - /// - /// ``` - /// use std::collections::LruCache; - /// let mut cache: LruCache = LruCache::new(2); - /// assert_eq!(cache.capacity(), 2); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn capacity(&self) -> uint { - self.max_size - } - - /// Deprecated: Renamed to `set_capacity`. - #[deprecated = "Renamed to `set_capacity`"] - pub fn change_capacity(&mut self, capacity: uint) { - self.set_capacity(capacity) - } - - /// Change the number of key-value pairs the cache can hold. Remove - /// least-recently-used key-value pairs if necessary. - /// - /// # Example - /// - /// ``` - /// use std::collections::LruCache; - /// let mut cache = LruCache::new(2); - /// - /// cache.insert(1i, "a"); - /// cache.insert(2, "b"); - /// cache.insert(3, "c"); - /// - /// assert_eq!(cache.get(&1), None); - /// assert_eq!(cache.get(&2), Some(&"b")); - /// assert_eq!(cache.get(&3), Some(&"c")); - /// - /// cache.set_capacity(3); - /// cache.insert(1i, "a"); - /// cache.insert(2, "b"); - /// - /// assert_eq!(cache.get(&1), Some(&"a")); - /// assert_eq!(cache.get(&2), Some(&"b")); - /// assert_eq!(cache.get(&3), Some(&"c")); - /// - /// cache.set_capacity(1); - /// - /// assert_eq!(cache.get(&1), None); - /// assert_eq!(cache.get(&2), None); - /// assert_eq!(cache.get(&3), Some(&"c")); - /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn set_capacity(&mut self, capacity: uint) { - for _ in range(capacity, self.len()) { - self.remove_lru(); - } - self.max_size = capacity; - } - - #[inline] - fn remove_lru(&mut self) { - if self.len() > 0 { - let lru = unsafe { (*self.head).prev }; - self.detach(lru); - self.map.remove(&KeyRef{k: unsafe { &(*lru).key }}); - } - } - - #[inline] - fn detach(&mut self, node: *mut LruEntry) { - unsafe { - (*(*node).prev).next = (*node).next; - (*(*node).next).prev = (*node).prev; - } - } - - #[inline] - fn attach(&mut self, node: *mut LruEntry) { - unsafe { - (*node).next = (*self.head).next; - (*node).prev = self.head; - (*self.head).next = node; - (*(*node).next).prev = node; - } - } - - /// Return the number of key-value pairs in the cache. - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn len(&self) -> uint { self.map.len() } - - /// Returns whether the cache is currently empty. - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn is_empty(&self) -> bool { self.len() == 0 } - - /// Clear the cache of all key-value pairs. - #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn clear(&mut self) { self.map.clear(); } - -} - -impl Extend<(K, V)> for LruCache { - fn extend>(&mut self, mut iter: T) { - for (k, v) in iter{ - self.insert(k, v); - } - } -} - -impl fmt::Show for LruCache { - /// Return a string that lists the key-value pairs from most-recently - /// used to least-recently used. - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - let mut cur = self.head; - for i in range(0, self.len()) { - if i > 0 { try!(write!(f, ", ")) } - unsafe { - cur = (*cur).next; - try!(write!(f, "{}", (*cur).key)); - } - try!(write!(f, ": ")); - unsafe { - try!(write!(f, "{}", (*cur).value)); - } - } - write!(f, r"}}") - } -} - -#[unsafe_destructor] -impl Drop for LruCache { - fn drop(&mut self) { - unsafe { - let node: Box> = mem::transmute(self.head); - // Prevent compiler from trying to drop the un-initialized field in the sigil node. - let box internal_node = node; - let LruEntry { next: _, prev: _, key: k, value: v } = internal_node; - mem::forget(k); - mem::forget(v); - } - } -} - -#[cfg(test)] -mod tests { - use prelude::*; - use super::LruCache; - - fn assert_opt_eq(opt: Option<&V>, v: V) { - assert!(opt.is_some()); - assert!(opt.unwrap() == &v); - } - - #[test] - fn test_put_and_get() { - let mut cache: LruCache = LruCache::new(2); - cache.insert(1, 10); - cache.insert(2, 20); - assert_opt_eq(cache.get(&1), 10); - assert_opt_eq(cache.get(&2), 20); - assert_eq!(cache.len(), 2); - } - - #[test] - fn test_put_update() { - let mut cache: LruCache> = LruCache::new(1); - cache.insert("1".to_string(), vec![10, 10]); - cache.insert("1".to_string(), vec![10, 19]); - assert_opt_eq(cache.get(&"1".to_string()), vec![10, 19]); - assert_eq!(cache.len(), 1); - } - - #[test] - fn test_expire_lru() { - let mut cache: LruCache = LruCache::new(2); - cache.insert("foo1".to_string(), "bar1".to_string()); - cache.insert("foo2".to_string(), "bar2".to_string()); - cache.insert("foo3".to_string(), "bar3".to_string()); - assert!(cache.get(&"foo1".to_string()).is_none()); - cache.insert("foo2".to_string(), "bar2update".to_string()); - cache.insert("foo4".to_string(), "bar4".to_string()); - assert!(cache.get(&"foo3".to_string()).is_none()); - } - - #[test] - fn test_pop() { - let mut cache: LruCache = LruCache::new(2); - cache.insert(1, 10); - cache.insert(2, 20); - assert_eq!(cache.len(), 2); - let opt1 = cache.remove(&1); - assert!(opt1.is_some()); - assert_eq!(opt1.unwrap(), 10); - assert!(cache.get(&1).is_none()); - assert_eq!(cache.len(), 1); - } - - #[test] - fn test_change_capacity() { - let mut cache: LruCache = LruCache::new(2); - assert_eq!(cache.capacity(), 2); - cache.insert(1, 10); - cache.insert(2, 20); - cache.set_capacity(1); - assert!(cache.get(&1).is_none()); - assert_eq!(cache.capacity(), 1); - } - - #[test] - fn test_to_string() { - let mut cache: LruCache = LruCache::new(3); - cache.insert(1, 10); - cache.insert(2, 20); - cache.insert(3, 30); - assert_eq!(cache.to_string(), "{3: 30, 2: 20, 1: 10}"); - cache.insert(2, 22); - assert_eq!(cache.to_string(), "{2: 22, 3: 30, 1: 10}"); - cache.insert(6, 60); - assert_eq!(cache.to_string(), "{6: 60, 2: 22, 3: 30}"); - cache.get(&3); - assert_eq!(cache.to_string(), "{3: 30, 6: 60, 2: 22}"); - cache.set_capacity(2); - assert_eq!(cache.to_string(), "{3: 30, 6: 60}"); - } - - #[test] - fn test_clear() { - let mut cache: LruCache = LruCache::new(2); - cache.insert(1, 10); - cache.insert(2, 20); - cache.clear(); - assert!(cache.get(&1).is_none()); - assert!(cache.get(&2).is_none()); - assert_eq!(cache.to_string(), "{}"); - } -} diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index 3419a3d98a154..0d44e6d869ab1 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -24,8 +24,8 @@ //! Rust's collections can be grouped into four major categories: //! //! * Sequences: `Vec`, `RingBuf`, `DList`, `BitV` -//! * Maps: `HashMap`, `BTreeMap`, `TreeMap`, `TrieMap`, `VecMap`, `LruCache` -//! * Sets: `HashSet`, `BTreeSet`, `TreeSet`, `TrieSet`, `BitVSet`, `EnumSet` +//! * Maps: `HashMap`, `BTreeMap`, `VecMap` +//! * Sets: `HashSet`, `BTreeSet`, `BitVSet` //! * Misc: `BinaryHeap` //! //! # When Should You Use Which Collection? @@ -64,16 +64,6 @@ //! * You want to be able to get all of the entries in order on-demand. //! * You want a sorted map. //! -//! ### Use a `TreeMap` when: -//! * You want a `BTreeMap`, but can't tolerate inconsistent performance. -//! * You want a `BTreeMap`, but have *very large* keys or values. -//! * You want a `BTreeMap`, but have keys that are expensive to compare. -//! * You want a `BTreeMap`, but you accept arbitrary untrusted inputs. -//! -//! ### Use a `TrieMap` when: -//! * You want a `HashMap`, but with many potentially large `uint` keys. -//! * You want a `BTreeMap`, but with potentially large `uint` keys. -//! //! ### Use a `VecMap` when: //! * You want a `HashMap` but with known to be small `uint` keys. //! * You want a `BTreeMap`, but with known to be small `uint` keys. @@ -90,18 +80,11 @@ //! ### Use a `BitVSet` when: //! * You want a `VecSet`. //! -//! ### Use an `EnumSet` when: -//! * You want a C-like enum, stored in a single `uint`. -//! //! ### Use a `BinaryHeap` when: //! * You want to store a bunch of elements, but only ever want to process the "biggest" //! or "most important" one at any given time. //! * You want a priority queue. //! -//! ### Use an `LruCache` when: -//! * You want a cache that discards infrequently used items when it becomes full. -//! * You want a least-recently-used cache. -//! //! # Correct and Efficient Usage of Collections //! //! Of course, knowing which collection is the right one for the job doesn't instantly @@ -329,15 +312,21 @@ #![experimental] pub use core_collections::{BinaryHeap, Bitv, BitvSet, BTreeMap, BTreeSet}; -pub use core_collections::{DList, EnumSet, RingBuf}; -pub use core_collections::{TreeMap, TreeSet, TrieMap, TrieSet, VecMap}; +pub use core_collections::{DList, RingBuf, VecMap}; -pub use core_collections::{binary_heap, bitv, bitv_set, btree_map, btree_set, dlist, enum_set}; -pub use core_collections::{ring_buf, tree_map, tree_set, trie_map, trie_set, vec_map}; +/// Deprecated: Moved to collect-rs: https://github.com/Gankro/collect-rs/ +#[deprecated = "Moved to collect-rs: https://github.com/Gankro/collect-rs/"] +pub use core_collections::EnumSet; + +pub use core_collections::{binary_heap, bitv, bitv_set, btree_map, btree_set}; +pub use core_collections::{dlist, ring_buf, vec_map}; + +/// Deprecated: Moved to collect-rs: https://github.com/Gankro/collect-rs/ +#[deprecated = "Moved to collect-rs: https://github.com/Gankro/collect-rs/"] +pub use core_collections::enum_set; pub use self::hash_map::HashMap; pub use self::hash_set::HashSet; -pub use self::lru_cache::LruCache; mod hash; @@ -350,5 +339,3 @@ pub mod hash_set { //! A hashset pub use super::hash::set::*; } - -pub mod lru_cache; From 0bd4dc68e6f45a4ffe8e12642aa557638ab2f5bd Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Tue, 16 Dec 2014 23:09:16 -0500 Subject: [PATCH 2/3] s/Tree/BTree --- src/libserialize/collection_impls.rs | 14 +++++------ src/libserialize/json.rs | 34 ++++++++++++------------- src/libtest/lib.rs | 4 +-- src/test/bench/core-map.rs | 36 +++++---------------------- src/test/bench/core-set.rs | 10 ++++---- src/test/run-pass/issue-16278.rs | 4 +-- src/test/run-pass/send_str_treemap.rs | 2 +- 7 files changed, 40 insertions(+), 64 deletions(-) diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index ffeb190ddf87c..8fb025623d478 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -15,7 +15,7 @@ use std::default::Default; use std::hash::{Hash, Hasher}; use {Decodable, Encodable, Decoder, Encoder}; -use std::collections::{DList, RingBuf, TreeMap, TreeSet, HashMap, HashSet, +use std::collections::{DList, RingBuf, BTreeMap, BTreeSet, HashMap, HashSet, TrieMap, TrieSet, VecMap}; use std::collections::enum_set::{EnumSet, CLike}; @@ -78,7 +78,7 @@ impl< S: Encoder, K: Encodable + PartialEq + Ord, V: Encodable + PartialEq -> Encodable for TreeMap { +> Encodable for BTreeMap { fn encode(&self, e: &mut S) -> Result<(), E> { e.emit_map(self.len(), |e| { let mut i = 0; @@ -97,10 +97,10 @@ impl< D: Decoder, K: Decodable + PartialEq + Ord, V: Decodable + PartialEq -> Decodable for TreeMap { +> Decodable for BTreeMap { fn decode(d: &mut D) -> Result, E> { d.read_map(|d, len| { - let mut map = TreeMap::new(); + let mut map = BTreeMap::new(); for i in range(0u, len) { let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d))); let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d))); @@ -115,7 +115,7 @@ impl< E, S: Encoder, T: Encodable + PartialEq + Ord -> Encodable for TreeSet { +> Encodable for BTreeSet { fn encode(&self, s: &mut S) -> Result<(), E> { s.emit_seq(self.len(), |s| { let mut i = 0; @@ -132,10 +132,10 @@ impl< E, D: Decoder, T: Decodable + PartialEq + Ord -> Decodable for TreeSet { +> Decodable for BTreeSet { fn decode(d: &mut D) -> Result, E> { d.read_seq(|d, len| { - let mut set = TreeSet::new(); + let mut set = BTreeSet::new(); for i in range(0u, len) { set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); } diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index e7b2d0c8eba0e..6d143329b0c30 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -151,7 +151,7 @@ //! //! ```rust //! extern crate serialize; -//! use std::collections::TreeMap; +//! use std::collections::BTreeMap; //! use serialize::json::{mod, Json, ToJson}; //! //! // Only generate `Decodable` trait implementation @@ -165,7 +165,7 @@ //! // Specify encoding method manually //! impl ToJson for TestStruct { //! fn to_json(&self) -> Json { -//! let mut d = TreeMap::new(); +//! let mut d = BTreeMap::new(); //! // All standard types implement `to_json()`, so use it //! d.insert("data_int".to_string(), self.data_int.to_json()); //! d.insert("data_str".to_string(), self.data_str.to_json()); @@ -198,7 +198,7 @@ use self::ParserState::*; use self::InternalStackElement::*; use std; -use std::collections::{HashMap, TreeMap}; +use std::collections::{HashMap, BTreeMap}; use std::{char, f64, fmt, io, num, str}; use std::mem::{swap, transmute}; use std::num::{Float, FPNaN, FPInfinite, Int}; @@ -223,7 +223,7 @@ pub enum Json { } pub type Array = Vec; -pub type Object = TreeMap; +pub type Object = BTreeMap; /// The errors that can arise while parsing a JSON stream. #[deriving(Clone, PartialEq)] @@ -973,7 +973,7 @@ impl Json { self.as_object().is_some() } - /// If the Json value is an Object, returns the associated TreeMap. + /// If the Json value is an Object, returns the associated BTreeMap. /// Returns None otherwise. pub fn as_object<'a>(&'a self) -> Option<&'a Object> { match self { @@ -1909,7 +1909,7 @@ impl> Builder { fn build_object(&mut self) -> Result { self.bump(); - let mut values = TreeMap::new(); + let mut values = BTreeMap::new(); loop { match self.token { @@ -2391,9 +2391,9 @@ impl ToJson for Vec { fn to_json(&self) -> Json { Json::Array(self.iter().map(|elt| elt.to_json()).collect()) } } -impl ToJson for TreeMap { +impl ToJson for BTreeMap { fn to_json(&self) -> Json { - let mut d = TreeMap::new(); + let mut d = BTreeMap::new(); for (key, value) in self.iter() { d.insert((*key).clone(), value.to_json()); } @@ -2403,7 +2403,7 @@ impl ToJson for TreeMap { impl ToJson for HashMap { fn to_json(&self) -> Json { - let mut d = TreeMap::new(); + let mut d = BTreeMap::new(); for (key, value) in self.iter() { d.insert((*key).clone(), value.to_json()); } @@ -2451,7 +2451,7 @@ mod tests { use super::{PrettyEncoder, Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser, StackElement, Stack, Encoder, Decoder}; use std::{i64, u64, f32, f64, io}; - use std::collections::TreeMap; + use std::collections::BTreeMap; use std::num::Float; use std::string; @@ -2501,7 +2501,7 @@ mod tests { } fn mk_object(items: &[(string::String, Json)]) -> Json { - let mut d = TreeMap::new(); + let mut d = BTreeMap::new(); for item in items.iter() { match *item { @@ -3075,7 +3075,7 @@ mod tests { fn test_decode_map() { let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\ \"fields\":[\"Henry\", 349]}}"; - let mut map: TreeMap = super::decode(s).unwrap(); + let mut map: BTreeMap = super::decode(s).unwrap(); assert_eq!(map.remove(&"a".into_string()), Some(Dog)); assert_eq!(map.remove(&"b".into_string()), Some(Frog("Henry".into_string(), 349))); @@ -3350,9 +3350,9 @@ mod tests { #[test] fn test_prettyencoder_indent_level_param() { use std::str::from_utf8; - use std::collections::TreeMap; + use std::collections::BTreeMap; - let mut tree = TreeMap::new(); + let mut tree = BTreeMap::new(); tree.insert("hello".into_string(), String("guten tag".into_string())); tree.insert("goodbye".into_string(), String("sayonara".into_string())); @@ -3719,13 +3719,13 @@ mod tests { #[test] fn test_to_json() { - use std::collections::{HashMap,TreeMap}; + use std::collections::{HashMap,BTreeMap}; use super::ToJson; let array2 = Array(vec!(U64(1), U64(2))); let array3 = Array(vec!(U64(1), U64(2), U64(3))); let object = { - let mut tree_map = TreeMap::new(); + let mut tree_map = BTreeMap::new(); tree_map.insert("a".into_string(), U64(1)); tree_map.insert("b".into_string(), U64(2)); Object(tree_map) @@ -3758,7 +3758,7 @@ mod tests { assert_eq!((&[1u, 2, 3]).to_json(), array3); assert_eq!((vec![1u, 2]).to_json(), array2); assert_eq!(vec!(1u, 2, 3).to_json(), array3); - let mut tree_map = TreeMap::new(); + let mut tree_map = BTreeMap::new(); tree_map.insert("a".into_string(), 1u); tree_map.insert("b".into_string(), 2); assert_eq!(tree_map.to_json(), object); diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 211c5906f4533..02b266b8fe0b8 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -251,7 +251,7 @@ pub enum MetricChange { impl Copy for MetricChange {} -pub type MetricDiff = TreeMap; +pub type MetricDiff = BTreeMap; // The default console test runner. It accepts the command line // arguments and a vector of test_descs. @@ -1227,7 +1227,7 @@ impl MetricMap { /// map. pub fn compare_to_old(&self, old: &MetricMap, noise_pct: Option) -> MetricDiff { - let mut diff : MetricDiff = TreeMap::new(); + let mut diff : MetricDiff = BTreeMap::new(); let MetricMap(ref selfmap) = *self; let MetricMap(ref old) = *old; for (k, vold) in old.iter() { diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index 112d4fd0912d4..60331dfb5505a 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -10,7 +10,7 @@ #![feature(unboxed_closures)] -use std::collections::{TrieMap, TreeMap, HashMap, HashSet}; +use std::collections::{BTreeMap, HashMap, HashSet}; use std::os; use std::rand::{Rng, IsaacRng, SeedableRng}; use std::time::Duration; @@ -26,7 +26,7 @@ trait MutableMap { fn find(&self, k: &uint) -> Option<&uint>; } -impl MutableMap for TreeMap { +impl MutableMap for BTreeMap { fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); } fn remove(&mut self, k: &uint) -> bool { self.remove(k).is_some() } fn find(&self, k: &uint) -> Option<&uint> { self.get(k) } @@ -36,11 +36,6 @@ impl MutableMap for HashMap { fn remove(&mut self, k: &uint) -> bool { self.remove(k).is_some() } fn find(&self, k: &uint) -> Option<&uint> { self.get(k) } } -impl MutableMap for TrieMap { - fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); } - fn remove(&mut self, k: &uint) -> bool { self.remove(k).is_some() } - fn find(&self, k: &uint) -> Option<&uint> { self.get(k) } -} fn ascending(map: &mut M, n_keys: uint) { println!(" Ascending integers:"); @@ -134,21 +129,21 @@ fn main() { println!("{} keys", n_keys); // FIXME: #9970 - println!("{}", "\nTreeMap:"); + println!("{}", "\nBTreeMap:"); { - let mut map: TreeMap = TreeMap::new(); + let mut map: BTreeMap = BTreeMap::new(); ascending(&mut map, n_keys); } { - let mut map: TreeMap = TreeMap::new(); + let mut map: BTreeMap = BTreeMap::new(); descending(&mut map, n_keys); } { println!(" Random integers:"); - let mut map: TreeMap = TreeMap::new(); + let mut map: BTreeMap = BTreeMap::new(); vector(&mut map, n_keys, rand.as_slice()); } @@ -170,23 +165,4 @@ fn main() { let mut map: HashMap = HashMap::new(); vector(&mut map, n_keys, rand.as_slice()); } - - // FIXME: #9970 - println!("{}", "\nTrieMap:"); - - { - let mut map: TrieMap = TrieMap::new(); - ascending(&mut map, n_keys); - } - - { - let mut map: TrieMap = TrieMap::new(); - descending(&mut map, n_keys); - } - - { - println!(" Random integers:"); - let mut map: TrieMap = TrieMap::new(); - vector(&mut map, n_keys, rand.as_slice()); - } } diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index 6ba642cc47b75..49f5c7751d9a0 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -17,7 +17,7 @@ extern crate rand; use std::collections::BitvSet; use std::collections::HashSet; -use std::collections::TreeSet; +use std::collections::BTreeSet; use std::hash::Hash; use std::os; use std::time::Duration; @@ -48,7 +48,7 @@ impl MutableSet for HashSet { fn remove(&mut self, k: &T) -> bool { self.remove(k) } fn contains(&self, k: &T) -> bool { self.contains(k) } } -impl MutableSet for TreeSet { +impl MutableSet for BTreeSet { fn insert(&mut self, k: T) { self.insert(k); } fn remove(&mut self, k: &T) -> bool { self.remove(k) } fn contains(&self, k: &T) -> bool { self.contains(k) } @@ -207,14 +207,14 @@ fn main() { let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed); let mut results = empty_results(); results.bench_int(&mut rng, num_keys, max, || { - let s: TreeSet = TreeSet::new(); + let s: BTreeSet = BTreeSet::new(); s }); results.bench_str(&mut rng, num_keys, || { - let s: TreeSet = TreeSet::new(); + let s: BTreeSet = BTreeSet::new(); s }); - write_results("collections::TreeSet", &results); + write_results("collections::BTreeSet", &results); } { diff --git a/src/test/run-pass/issue-16278.rs b/src/test/run-pass/issue-16278.rs index f92426d204c0d..ade312da21b70 100644 --- a/src/test/run-pass/issue-16278.rs +++ b/src/test/run-pass/issue-16278.rs @@ -12,9 +12,9 @@ // this file has some special \r\n endings (use xxd to see them) -fn main() {assert_eq!(b"", b"\ +fn main() {assert_eq!(b"", b"\ "); -assert_eq!(b"\n", b" +assert_eq!(b"\n", b" "); } diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs index 9334b673b515e..ee57d01c36d36 100644 --- a/src/test/run-pass/send_str_treemap.rs +++ b/src/test/run-pass/send_str_treemap.rs @@ -16,7 +16,7 @@ use std::str::SendStr; use std::string::ToString; pub fn main() { - let mut map: TreeMap = TreeMap::new(); + let mut map: BTreeMap = BTreeMap::new(); assert!(map.insert("foo".into_cow(), 42).is_none()); assert!(map.insert("foo".to_string().into_cow(), 42).is_some()); assert!(map.insert("foo".into_cow(), 42).is_some()); From 67d3823fc3ffa8b4e86a2d7cb007339a042605e7 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Wed, 17 Dec 2014 10:16:10 -0500 Subject: [PATCH 3/3] enumset fallout --- src/librustc/lib.rs | 1 + src/librustc/middle/ty.rs | 2 +- src/librustdoc/lib.rs | 2 +- src/libserialize/collection_impls.rs | 66 ++------------------------- src/libserialize/lib.rs | 2 + src/libtest/lib.rs | 6 +-- src/test/run-pass/send_str_treemap.rs | 2 +- 7 files changed, 13 insertions(+), 68 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index d87fbb016208a..90e9973c3f302 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -36,6 +36,7 @@ extern crate rustc_llvm; extern crate rustc_back; extern crate serialize; extern crate rbml; +extern crate collections; #[phase(plugin, link)] extern crate log; #[phase(plugin, link)] extern crate syntax; diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index b349b5ca0bf23..0ad07bed7d923 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -77,7 +77,7 @@ use std::hash::{Hash, sip, Writer}; use std::mem; use std::ops; use std::rc::Rc; -use std::collections::enum_set::{EnumSet, CLike}; +use collections::enum_set::{EnumSet, CLike}; use std::collections::hash_map::{HashMap, Occupied, Vacant}; use syntax::abi; use syntax::ast::{CrateNum, DefId, DUMMY_NODE_ID, Ident, ItemTrait, LOCAL_CRATE}; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 5a91298acdf25..3d51a6d6ab077 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -472,7 +472,7 @@ fn json_output(krate: clean::Crate, res: Vec , // "crate": { parsed crate ... }, // "plugins": { output of plugins ... } // } - let mut json = std::collections::TreeMap::new(); + let mut json = std::collections::BTreeMap::new(); json.insert("schema".to_string(), Json::String(SCHEMA_VERSION.to_string())); let plugins_json = res.into_iter() .filter_map(|opt| { diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index 8fb025623d478..f2d79b1334699 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -15,9 +15,8 @@ use std::default::Default; use std::hash::{Hash, Hasher}; use {Decodable, Encodable, Decoder, Encoder}; -use std::collections::{DList, RingBuf, BTreeMap, BTreeSet, HashMap, HashSet, - TrieMap, TrieSet, VecMap}; -use std::collections::enum_set::{EnumSet, CLike}; +use std::collections::{DList, RingBuf, BTreeMap, BTreeSet, HashMap, HashSet, VecMap}; +use collections::enum_set::{EnumSet, CLike}; impl< E, @@ -98,7 +97,7 @@ impl< K: Decodable + PartialEq + Ord, V: Decodable + PartialEq > Decodable for BTreeMap { - fn decode(d: &mut D) -> Result, E> { + fn decode(d: &mut D) -> Result, E> { d.read_map(|d, len| { let mut map = BTreeMap::new(); for i in range(0u, len) { @@ -133,7 +132,7 @@ impl< D: Decoder, T: Decodable + PartialEq + Ord > Decodable for BTreeSet { - fn decode(d: &mut D) -> Result, E> { + fn decode(d: &mut D) -> Result, E> { d.read_seq(|d, len| { let mut set = BTreeSet::new(); for i in range(0u, len) { @@ -255,63 +254,6 @@ impl< } } -impl< - E, - S: Encoder, - V: Encodable -> Encodable for TrieMap { - fn encode(&self, e: &mut S) -> Result<(), E> { - e.emit_map(self.len(), |e| { - for (i, (key, val)) in self.iter().enumerate() { - try!(e.emit_map_elt_key(i, |e| key.encode(e))); - try!(e.emit_map_elt_val(i, |e| val.encode(e))); - } - Ok(()) - }) - } -} - -impl< - E, - D: Decoder, - V: Decodable -> Decodable for TrieMap { - fn decode(d: &mut D) -> Result, E> { - d.read_map(|d, len| { - let mut map = TrieMap::new(); - for i in range(0u, len) { - let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d))); - let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d))); - map.insert(key, val); - } - Ok(map) - }) - } -} - -impl> Encodable for TrieSet { - fn encode(&self, s: &mut S) -> Result<(), E> { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - try!(s.emit_seq_elt(i, |s| e.encode(s))); - } - Ok(()) - }) - } -} - -impl> Decodable for TrieSet { - fn decode(d: &mut D) -> Result { - d.read_seq(|d, len| { - let mut set = TrieSet::new(); - for i in range(0u, len) { - set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); - } - Ok(set) - }) - } -} - impl< E, S: Encoder, diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 390b3976562ff..e700d102fefda 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -33,6 +33,8 @@ extern crate test; #[phase(plugin, link)] extern crate log; +extern crate collections; + pub use self::serialize::{Decoder, Encoder, Decodable, Encodable, DecoderHelpers, EncoderHelpers}; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 02b266b8fe0b8..d786409e895b2 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -49,7 +49,7 @@ use self::NamePadding::*; use self::OutputLocation::*; use std::any::{Any, AnyRefExt}; -use std::collections::TreeMap; +use std::collections::BTreeMap; use stats::Stats; use getopts::{OptGroup, optflag, optopt}; use regex::Regex; @@ -230,7 +230,7 @@ impl Metric { } #[deriving(PartialEq)] -pub struct MetricMap(TreeMap); +pub struct MetricMap(BTreeMap); impl Clone for MetricMap { fn clone(&self) -> MetricMap { @@ -1191,7 +1191,7 @@ fn calc_result(desc: &TestDesc, task_result: Result<(), Box>) -> TestR impl MetricMap { pub fn new() -> MetricMap { - MetricMap(TreeMap::new()) + MetricMap(BTreeMap::new()) } /// Load MetricDiff from a file. diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs index ee57d01c36d36..24480d8527205 100644 --- a/src/test/run-pass/send_str_treemap.rs +++ b/src/test/run-pass/send_str_treemap.rs @@ -10,7 +10,7 @@ extern crate collections; -use self::collections::TreeMap; +use self::collections::BTreeMap; use std::option::Option::Some; use std::str::SendStr; use std::string::ToString;