DEPS_arena := std collections
DEPS_glob := std
DEPS_serialize := std
-DEPS_term := std
+DEPS_term := std collections
DEPS_semver := std
DEPS_uuid := std serialize
DEPS_sync := std
Two examples of paths with type arguments:
~~~~
-# use std::hashmap::HashMap;
+# struct HashMap<K, V>;
# fn f() {
# fn id<T>(t: T) -> T { t }
type T = HashMap<int,~str>; // Type arguments used in a type expression
Generic `type`, `struct`, and `enum` declarations follow the same pattern:
~~~~
-use std::hashmap::HashMap;
-type Set<T> = HashMap<T, ()>;
+extern crate collections;
+type Set<T> = collections::HashMap<T, ()>;
struct Stack<T> {
elements: ~[T]
Some(T),
None
}
+# fn main() {}
~~~~
These declarations can be instantiated to valid types like `Set<int>`,
#[crate_id=\"run_pass_stage2#0.1\"];
#[feature(globs, macro_rules, struct_variant, managed_boxes)];
#[allow(warnings)];
+extern crate collections;
+extern crate extra;
"""
)
for t in stage2_tests:
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Unordered containers, implemented as hash-tables (`HashSet` and `HashMap` types)
+//!
+//! The tables use a keyed hash with new random keys generated for each container, so the ordering
+//! of a set of keys in a hash table is randomized.
+//!
+//! # Example
+//!
+//! ```rust
+//! use collections::HashMap;
+//!
+//! // type inference lets us omit an explicit type signature (which
+//! // would be `HashMap<&str, &str>` in this example).
+//! let mut book_reviews = HashMap::new();
+//!
+//! // review some books.
+//! book_reviews.insert("Adventures of Hucklebury Fin", "My favorite book.");
+//! book_reviews.insert("Grimms' Fairy Tales", "Masterpiece.");
+//! book_reviews.insert("Pride and Prejudice", "Very enjoyable.");
+//! book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot.");
+//!
+//! // check for a specific one.
+//! if !book_reviews.contains_key(& &"Les Misérables") {
+//! println!("We've got {} reviews, but Les Misérables ain't one.",
+//! book_reviews.len());
+//! }
+//!
+//! // oops, this review has a lot of spelling mistakes, let's delete it.
+//! book_reviews.remove(& &"The Adventures of Sherlock Holmes");
+//!
+//! // look up the values associated with some keys.
+//! let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
+//! for book in to_find.iter() {
+//! match book_reviews.find(book) {
+//! Some(review) => println!("{}: {}", *book, *review),
+//! None => println!("{} is unreviewed.", *book)
+//! }
+//! }
+//!
+//! // iterate over everything.
+//! for (book, review) in book_reviews.iter() {
+//! println!("{}: \"{}\"", *book, *review);
+//! }
+//! ```
+
+use std::cmp::max;
+use std::fmt;
+use std::hash_old::Hash;
+use std::iter::{FilterMap, Chain, Repeat, Zip};
+use std::iter;
+use std::mem::replace;
+use std::num;
+use std::rand::Rng;
+use std::rand;
+use std::vec::{Items, MutItems};
+use std::vec_ng::Vec;
+use std::vec_ng;
+
+use serialize::{Encodable, Decodable, Encoder, Decoder};
+
+static INITIAL_CAPACITY: uint = 32u; // 2^5
+
+struct Bucket<K,V> {
+ hash: uint,
+ key: K,
+ value: V,
+}
+
+/// A hash map implementation which uses linear probing along with the SipHash
+/// hash function for internal state. This means that the order of all hash maps
+/// is randomized by keying each hash map randomly on creation.
+///
+/// It is required that the keys implement the `Eq` and `Hash` traits, although
+/// this can frequently be achieved by just implementing the `Eq` and
+/// `IterBytes` traits as `Hash` is automatically implemented for types that
+/// implement `IterBytes`.
+pub struct HashMap<K,V> {
+ priv k0: u64,
+ priv k1: u64,
+ priv resize_at: uint,
+ priv size: uint,
+ priv buckets: Vec<Option<Bucket<K, V>>>
+}
+
+// We could rewrite FoundEntry to have type Option<&Bucket<K, V>>
+// which would be nifty
+enum SearchResult {
+ FoundEntry(uint), FoundHole(uint), TableFull
+}
+
+#[inline]
+fn resize_at(capacity: uint) -> uint {
+ (capacity * 3) / 4
+}
+
+impl<K:Hash + Eq,V> HashMap<K, V> {
+ #[inline]
+ fn to_bucket(&self, h: uint) -> uint {
+ // A good hash function with entropy spread over all of the
+ // bits is assumed. SipHash is more than good enough.
+ h % self.buckets.len()
+ }
+
+ #[inline]
+ fn next_bucket(&self, idx: uint, len_buckets: uint) -> uint {
+ (idx + 1) % len_buckets
+ }
+
+ #[inline]
+ fn bucket_sequence(&self, hash: uint, op: |uint| -> bool) -> bool {
+ let start_idx = self.to_bucket(hash);
+ let len_buckets = self.buckets.len();
+ let mut idx = start_idx;
+ loop {
+ if !op(idx) { return false; }
+ idx = self.next_bucket(idx, len_buckets);
+ if idx == start_idx {
+ return true;
+ }
+ }
+ }
+
+ #[inline]
+ fn bucket_for_key(&self, k: &K) -> SearchResult {
+ let hash = k.hash_keyed(self.k0, self.k1) as uint;
+ self.bucket_for_key_with_hash(hash, k)
+ }
+
+ #[inline]
+ fn bucket_for_key_equiv<Q:Hash + Equiv<K>>(&self, k: &Q)
+ -> SearchResult {
+ let hash = k.hash_keyed(self.k0, self.k1) as uint;
+ self.bucket_for_key_with_hash_equiv(hash, k)
+ }
+
+ #[inline]
+ fn bucket_for_key_with_hash(&self,
+ hash: uint,
+ k: &K)
+ -> SearchResult {
+ let mut ret = TableFull;
+ self.bucket_sequence(hash, |i| {
+ match self.buckets.as_slice()[i] {
+ Some(ref bkt) if bkt.hash == hash && *k == bkt.key => {
+ ret = FoundEntry(i); false
+ },
+ None => { ret = FoundHole(i); false }
+ _ => true,
+ }
+ });
+ ret
+ }
+
+ #[inline]
+ fn bucket_for_key_with_hash_equiv<Q:Equiv<K>>(&self,
+ hash: uint,
+ k: &Q)
+ -> SearchResult {
+ let mut ret = TableFull;
+ self.bucket_sequence(hash, |i| {
+ match self.buckets.as_slice()[i] {
+ Some(ref bkt) if bkt.hash == hash && k.equiv(&bkt.key) => {
+ ret = FoundEntry(i); false
+ },
+ None => { ret = FoundHole(i); false }
+ _ => true,
+ }
+ });
+ ret
+ }
+
+ /// Expand the capacity of the array to the next power of two
+ /// and re-insert each of the existing buckets.
+ #[inline]
+ fn expand(&mut self) {
+ let new_capacity = self.buckets.len() * 2;
+ self.resize(new_capacity);
+ }
+
+ /// Expands the capacity of the array and re-insert each of the
+ /// existing buckets.
+ fn resize(&mut self, new_capacity: uint) {
+ self.resize_at = resize_at(new_capacity);
+
+ let old_buckets = replace(&mut self.buckets,
+ Vec::from_fn(new_capacity, |_| None));
+
+ self.size = 0;
+ for bucket in old_buckets.move_iter() {
+ self.insert_opt_bucket(bucket);
+ }
+ }
+
+ fn insert_opt_bucket(&mut self, bucket: Option<Bucket<K, V>>) {
+ match bucket {
+ Some(Bucket{hash: hash, key: key, value: value}) => {
+ self.insert_internal(hash, key, value);
+ }
+ None => {}
+ }
+ }
+
+ #[inline]
+ fn value_for_bucket<'a>(&'a self, idx: uint) -> &'a V {
+ match self.buckets.as_slice()[idx] {
+ Some(ref bkt) => &bkt.value,
+ None => fail!("HashMap::find: internal logic error"),
+ }
+ }
+
+ #[inline]
+ fn mut_value_for_bucket<'a>(&'a mut self, idx: uint) -> &'a mut V {
+ match self.buckets.as_mut_slice()[idx] {
+ Some(ref mut bkt) => &mut bkt.value,
+ None => unreachable!()
+ }
+ }
+
+ /// Inserts the key value pair into the buckets.
+ /// Assumes that there will be a bucket.
+ /// True if there was no previous entry with that key
+ fn insert_internal(&mut self, hash: uint, k: K, v: V) -> Option<V> {
+ match self.bucket_for_key_with_hash(hash, &k) {
+ TableFull => { fail!("Internal logic error"); }
+ FoundHole(idx) => {
+ self.buckets.as_mut_slice()[idx] = Some(Bucket{hash: hash, key: k, value: v});
+ self.size += 1;
+ None
+ }
+ FoundEntry(idx) => {
+ match self.buckets.as_mut_slice()[idx] {
+ None => { fail!("insert_internal: Internal logic error") }
+ Some(ref mut b) => {
+ b.hash = hash;
+ b.key = k;
+ Some(replace(&mut b.value, v))
+ }
+ }
+ }
+ }
+ }
+
+ fn pop_internal(&mut self, hash: uint, k: &K) -> Option<V> {
+ // Removing from an open-addressed hashtable
+ // is, well, painful. The problem is that
+ // the entry may lie on the probe path for other
+ // entries, so removing it would make you think that
+ // those probe paths are empty.
+ //
+ // To address this we basically have to keep walking,
+ // re-inserting entries we find until we reach an empty
+ // bucket. We know we will eventually reach one because
+ // we insert one ourselves at the beginning (the removed
+ // entry).
+ //
+ // I found this explanation elucidating:
+ // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf
+ let mut idx = match self.bucket_for_key_with_hash(hash, k) {
+ TableFull | FoundHole(_) => return None,
+ FoundEntry(idx) => idx
+ };
+
+ let len_buckets = self.buckets.len();
+ let bucket = self.buckets.as_mut_slice()[idx].take();
+
+ let value = bucket.map(|bucket| bucket.value);
+
+ /* re-inserting buckets may cause changes in size, so remember
+ what our new size is ahead of time before we start insertions */
+ let size = self.size - 1;
+ idx = self.next_bucket(idx, len_buckets);
+ while self.buckets.as_slice()[idx].is_some() {
+ let bucket = self.buckets.as_mut_slice()[idx].take();
+ self.insert_opt_bucket(bucket);
+ idx = self.next_bucket(idx, len_buckets);
+ }
+ self.size = size;
+
+ value
+ }
+}
+
+impl<K:Hash + Eq,V> Container for HashMap<K, V> {
+ /// Return the number of elements in the map
+ fn len(&self) -> uint { self.size }
+}
+
+impl<K:Hash + Eq,V> Mutable for HashMap<K, V> {
+ /// Clear the map, removing all key-value pairs.
+ fn clear(&mut self) {
+ for bkt in self.buckets.as_mut_slice().mut_iter() {
+ *bkt = None;
+ }
+ self.size = 0;
+ }
+}
+
+impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> {
+ /// Return a reference to the value corresponding to the key
+ fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
+ match self.bucket_for_key(k) {
+ FoundEntry(idx) => Some(self.value_for_bucket(idx)),
+ TableFull | FoundHole(_) => None,
+ }
+ }
+}
+
+impl<K:Hash + Eq,V> MutableMap<K, V> for HashMap<K, V> {
+ /// Return a mutable reference to the value corresponding to the key
+ fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
+ let idx = match self.bucket_for_key(k) {
+ FoundEntry(idx) => idx,
+ TableFull | FoundHole(_) => return None
+ };
+ Some(self.mut_value_for_bucket(idx))
+ }
+
+ /// Insert a key-value pair from the map. If the key already had a value
+ /// present in the map, that value is returned. Otherwise None is returned.
+ fn swap(&mut self, k: K, v: V) -> Option<V> {
+ // this could be faster.
+
+ if self.size >= self.resize_at {
+ // n.b.: We could also do this after searching, so
+ // that we do not resize if this call to insert is
+ // simply going to update a key in place. My sense
+ // though is that it's worse to have to search through
+ // buckets to find the right spot twice than to just
+ // resize in this corner case.
+ self.expand();
+ }
+
+ let hash = k.hash_keyed(self.k0, self.k1) as uint;
+ self.insert_internal(hash, k, v)
+ }
+
+ /// Removes a key from the map, returning the value at the key if the key
+ /// was previously in the map.
+ fn pop(&mut self, k: &K) -> Option<V> {
+ let hash = k.hash_keyed(self.k0, self.k1) as uint;
+ self.pop_internal(hash, k)
+ }
+}
+
+impl<K: Hash + Eq, V> HashMap<K, V> {
+ /// Create an empty HashMap
+ pub fn new() -> HashMap<K, V> {
+ HashMap::with_capacity(INITIAL_CAPACITY)
+ }
+
+ /// Create an empty HashMap with space for at least `capacity`
+ /// elements in the hash table.
+ pub fn with_capacity(capacity: uint) -> HashMap<K, V> {
+ let mut r = rand::task_rng();
+ HashMap::with_capacity_and_keys(r.gen(), r.gen(), capacity)
+ }
+
+ /// Create an empty HashMap with space for at least `capacity`
+ /// elements, using `k0` and `k1` as the keys.
+ ///
+ /// Warning: `k0` and `k1` are normally randomly generated, and
+ /// are designed to allow HashMaps to be resistant to attacks that
+ /// cause many collisions and very poor performance. Setting them
+ /// manually using this function can expose a DoS attack vector.
+ pub fn with_capacity_and_keys(k0: u64, k1: u64, capacity: uint) -> HashMap<K, V> {
+ let cap = max(INITIAL_CAPACITY, capacity);
+ HashMap {
+ k0: k0, k1: k1,
+ resize_at: resize_at(cap),
+ size: 0,
+ buckets: Vec::from_fn(cap, |_| None)
+ }
+ }
+
+ /// Reserve space for at least `n` elements in the hash table.
+ pub fn reserve(&mut self, n: uint) {
+ if n > self.buckets.len() {
+ let buckets = n * 4 / 3 + 1;
+ self.resize(num::next_power_of_two(buckets));
+ }
+ }
+
+ /// Modify and return the value corresponding to the key in the map, or
+ /// insert and return a new value if it doesn't exist.
+ ///
+ /// This method allows for all insertion behaviours of a hashmap,
+ /// see methods like `insert`, `find_or_insert` and
+ /// `insert_or_update_with` for less general and more friendly
+ /// variations of this.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use collections::HashMap;
+ ///
+ /// // map some strings to vectors of strings
+ /// let mut map = HashMap::<~str, ~[~str]>::new();
+ /// map.insert(~"a key", ~[~"value"]);
+ /// map.insert(~"z key", ~[~"value"]);
+ ///
+ /// let new = ~[~"a key", ~"b key", ~"z key"];
+ /// for k in new.move_iter() {
+ /// map.mangle(k, ~"new value",
+ /// // if the key doesn't exist in the map yet, add it in
+ /// // the obvious way.
+ /// |_k, v| ~[v],
+ /// // if the key does exist either prepend or append this
+ /// // new value based on the first letter of the key.
+ /// |key, already, new| {
+ /// if key.starts_with("z") {
+ /// already.unshift(new);
+ /// } else {
+ /// already.push(new);
+ /// }
+ /// });
+ /// }
+ ///
+ /// for (k, v) in map.iter() {
+ /// println!("{} -> {:?}", *k, *v);
+ /// }
+ /// ```
+ pub fn mangle<'a,
+ A>(
+ &'a mut self,
+ k: K,
+ a: A,
+ not_found: |&K, A| -> V,
+ found: |&K, &mut V, A|)
+ -> &'a mut V {
+ if self.size >= self.resize_at {
+ // n.b.: We could also do this after searching, so
+ // that we do not resize if this call to insert is
+ // simply going to update a key in place. My sense
+ // though is that it's worse to have to search through
+ // buckets to find the right spot twice than to just
+ // resize in this corner case.
+ self.expand();
+ }
+
+ let hash = k.hash_keyed(self.k0, self.k1) as uint;
+ let idx = match self.bucket_for_key_with_hash(hash, &k) {
+ TableFull => fail!("Internal logic error"),
+ FoundEntry(idx) => { found(&k, self.mut_value_for_bucket(idx), a); idx }
+ FoundHole(idx) => {
+ let v = not_found(&k, a);
+ self.buckets.as_mut_slice()[idx] = Some(Bucket{hash: hash, key: k, value: v});
+ self.size += 1;
+ idx
+ }
+ };
+
+ self.mut_value_for_bucket(idx)
+ }
+
+ /// Return the value corresponding to the key in the map, or insert
+ /// and return the value if it doesn't exist.
+ pub fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a mut V {
+ self.mangle(k, v, |_k, a| a, |_k,_v,_a| ())
+ }
+
+ /// Return the value corresponding to the key in the map, or create,
+ /// insert, and return a new value if it doesn't exist.
+ pub fn find_or_insert_with<'a>(&'a mut self, k: K, f: |&K| -> V)
+ -> &'a mut V {
+ self.mangle(k, (), |k,_a| f(k), |_k,_v,_a| ())
+ }
+
+ /// Insert a key-value pair into the map if the key is not already present.
+ /// Otherwise, modify the existing value for the key.
+ /// Returns the new or modified value for the key.
+ pub fn insert_or_update_with<'a>(
+ &'a mut self,
+ k: K,
+ v: V,
+ f: |&K, &mut V|)
+ -> &'a mut V {
+ self.mangle(k, v, |_k,a| a, |k,v,_a| f(k,v))
+ }
+
+ /// Retrieves a value for the given key, failing if the key is not
+ /// present.
+ pub fn get<'a>(&'a self, k: &K) -> &'a V {
+ match self.find(k) {
+ Some(v) => v,
+ None => fail!("No entry found for key: {:?}", k),
+ }
+ }
+
+ /// Retrieves a (mutable) value for the given key, failing if the key
+ /// is not present.
+ pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V {
+ match self.find_mut(k) {
+ Some(v) => v,
+ None => fail!("No entry found for key: {:?}", k),
+ }
+ }
+
+ /// Return true if the map contains a value for the specified key,
+ /// using equivalence
+ pub fn contains_key_equiv<Q:Hash + Equiv<K>>(&self, key: &Q) -> bool {
+ match self.bucket_for_key_equiv(key) {
+ FoundEntry(_) => {true}
+ TableFull | FoundHole(_) => {false}
+ }
+ }
+
+ /// Return the value corresponding to the key in the map, using
+ /// equivalence
+ pub fn find_equiv<'a, Q:Hash + Equiv<K>>(&'a self, k: &Q)
+ -> Option<&'a V> {
+ match self.bucket_for_key_equiv(k) {
+ FoundEntry(idx) => Some(self.value_for_bucket(idx)),
+ TableFull | FoundHole(_) => None,
+ }
+ }
+
+ /// An iterator visiting all keys in arbitrary order.
+ /// Iterator element type is &'a K.
+ pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
+ self.iter().map(|(k, _v)| k)
+ }
+
+ /// An iterator visiting all values in arbitrary order.
+ /// Iterator element type is &'a V.
+ pub fn values<'a>(&'a self) -> Values<'a, K, V> {
+ self.iter().map(|(_k, v)| v)
+ }
+
+ /// An iterator visiting all key-value pairs in arbitrary order.
+ /// Iterator element type is (&'a K, &'a V).
+ pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
+ Entries { iter: self.buckets.as_slice().iter() }
+ }
+
+ /// An iterator visiting all key-value pairs in arbitrary order,
+ /// with mutable references to the values.
+ /// Iterator element type is (&'a K, &'a mut V).
+ pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> {
+ MutEntries { iter: self.buckets.as_mut_slice().mut_iter() }
+ }
+
+ /// Creates a consuming iterator, that is, one that moves each key-value
+ /// pair out of the map in arbitrary order. The map cannot be used after
+ /// calling this.
+ pub fn move_iter(self) -> MoveEntries<K, V> {
+ MoveEntries {iter: self.buckets.move_iter()}
+ }
+}
+
+impl<K: Hash + Eq, V: Clone> HashMap<K, V> {
+ /// Like `find`, but returns a copy of the value.
+ pub fn find_copy(&self, k: &K) -> Option<V> {
+ self.find(k).map(|v| (*v).clone())
+ }
+
+ /// Like `get`, but returns a copy of the value.
+ pub fn get_copy(&self, k: &K) -> V {
+ (*self.get(k)).clone()
+ }
+}
+
+impl<K:Hash + Eq,V:Eq> Eq for HashMap<K, V> {
+ fn eq(&self, other: &HashMap<K, V>) -> bool {
+ if self.len() != other.len() { return false; }
+
+ self.iter().all(|(key, value)| {
+ match other.find(key) {
+ None => false,
+ Some(v) => value == v
+ }
+ })
+ }
+
+ fn ne(&self, other: &HashMap<K, V>) -> bool { !self.eq(other) }
+}
+
+impl<K:Hash + Eq + Clone,V:Clone> Clone for HashMap<K,V> {
+ fn clone(&self) -> HashMap<K,V> {
+ let mut new_map = HashMap::with_capacity(self.len());
+ for (key, value) in self.iter() {
+ new_map.insert((*key).clone(), (*value).clone());
+ }
+ new_map
+ }
+}
+
+impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for HashMap<A, B> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(f.buf, r"\{"))
+ let mut first = true;
+ for (key, value) in self.iter() {
+ if first {
+ first = false;
+ } else {
+ try!(write!(f.buf, ", "));
+ }
+ try!(write!(f.buf, "{}: {}", *key, *value));
+ }
+ write!(f.buf, r"\}")
+ }
+}
+
+impl<K: fmt::Show + Hash + Eq, V: fmt::Show> ToStr for HashMap<K, V> {
+ fn to_str(&self) -> ~str { format!("{}", *self) }
+}
+
+/// HashMap iterator
+#[deriving(Clone)]
+pub struct Entries<'a, K, V> {
+ priv iter: Items<'a, Option<Bucket<K, V>>>,
+}
+
+/// HashMap mutable values iterator
+pub struct MutEntries<'a, K, V> {
+ priv iter: MutItems<'a, Option<Bucket<K, V>>>,
+}
+
+/// HashMap move iterator
+pub struct MoveEntries<K, V> {
+ priv iter: vec_ng::MoveItems<Option<Bucket<K, V>>>,
+}
+
+/// HashMap keys iterator
+pub type Keys<'a, K, V> =
+ iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
+
+/// HashMap values iterator
+pub type Values<'a, K, V> =
+ iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
+
+/// HashSet iterator
+#[deriving(Clone)]
+pub struct SetItems<'a, K> {
+ priv iter: Items<'a, Option<Bucket<K, ()>>>,
+}
+
+/// HashSet move iterator
+pub struct SetMoveItems<K> {
+ priv iter: vec_ng::MoveItems<Option<Bucket<K, ()>>>,
+}
+
+impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
+ #[inline]
+ fn next(&mut self) -> Option<(&'a K, &'a V)> {
+ for elt in self.iter {
+ match elt {
+ &Some(ref bucket) => return Some((&bucket.key, &bucket.value)),
+ &None => {},
+ }
+ }
+ None
+ }
+}
+
+impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
+ #[inline]
+ fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
+ for elt in self.iter {
+ match elt {
+ &Some(ref mut bucket) => return Some((&bucket.key, &mut bucket.value)),
+ &None => {},
+ }
+ }
+ None
+ }
+}
+
+impl<K, V> Iterator<(K, V)> for MoveEntries<K, V> {
+ #[inline]
+ fn next(&mut self) -> Option<(K, V)> {
+ for elt in self.iter {
+ match elt {
+ Some(Bucket {key, value, ..}) => return Some((key, value)),
+ None => {},
+ }
+ }
+ None
+ }
+}
+
+impl<'a, K> Iterator<&'a K> for SetItems<'a, K> {
+ #[inline]
+ fn next(&mut self) -> Option<&'a K> {
+ for elt in self.iter {
+ match elt {
+ &Some(ref bucket) => return Some(&bucket.key),
+ &None => {},
+ }
+ }
+ None
+ }
+}
+
+impl<K> Iterator<K> for SetMoveItems<K> {
+ #[inline]
+ fn next(&mut self) -> Option<K> {
+ for elt in self.iter {
+ match elt {
+ Some(bucket) => return Some(bucket.key),
+ None => {},
+ }
+ }
+ None
+ }
+}
+
+impl<K: Eq + Hash, V> FromIterator<(K, V)> for HashMap<K, V> {
+ fn from_iterator<T: Iterator<(K, V)>>(iter: &mut T) -> HashMap<K, V> {
+ let (lower, _) = iter.size_hint();
+ let mut map = HashMap::with_capacity(lower);
+ map.extend(iter);
+ map
+ }
+}
+
+impl<K: Eq + Hash, V> Extendable<(K, V)> for HashMap<K, V> {
+ fn extend<T: Iterator<(K, V)>>(&mut self, iter: &mut T) {
+ for (k, v) in *iter {
+ self.insert(k, v);
+ }
+ }
+}
+
+impl<K: Eq + Hash, V> Default for HashMap<K, V> {
+ fn default() -> HashMap<K, V> { HashMap::new() }
+}
+
+/// An implementation of a hash set using the underlying representation of a
+/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
+/// requires that the elements implement the `Eq` and `Hash` traits.
+pub struct HashSet<T> {
+ priv map: HashMap<T, ()>
+}
+
+impl<T:Hash + Eq> Eq for HashSet<T> {
+ fn eq(&self, other: &HashSet<T>) -> bool { self.map == other.map }
+ fn ne(&self, other: &HashSet<T>) -> bool { self.map != other.map }
+}
+
+impl<T:Hash + Eq> Container for HashSet<T> {
+ /// Return the number of elements in the set
+ fn len(&self) -> uint { self.map.len() }
+}
+
+impl<T:Hash + Eq> Mutable for HashSet<T> {
+ /// Clear the set, removing all values.
+ fn clear(&mut self) { self.map.clear() }
+}
+
+impl<T:Hash + Eq> Set<T> for HashSet<T> {
+ /// Return true if the set contains a value
+ fn contains(&self, value: &T) -> bool { self.map.contains_key(value) }
+
+ /// Return true if the set has no elements in common with `other`.
+ /// This is equivalent to checking for an empty intersection.
+ fn is_disjoint(&self, other: &HashSet<T>) -> bool {
+ self.iter().all(|v| !other.contains(v))
+ }
+
+ /// Return true if the set is a subset of another
+ fn is_subset(&self, other: &HashSet<T>) -> bool {
+ self.iter().all(|v| other.contains(v))
+ }
+
+ /// Return true if the set is a superset of another
+ fn is_superset(&self, other: &HashSet<T>) -> bool {
+ other.is_subset(self)
+ }
+}
+
+impl<T:Hash + Eq> MutableSet<T> for HashSet<T> {
+ /// Add a value to the set. Return true if the value was not already
+ /// present in the set.
+ fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
+
+ /// Remove a value from the set. Return true if the value was
+ /// present in the set.
+ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
+}
+
+impl<T:Hash + Eq> HashSet<T> {
+ /// Create an empty HashSet
+ pub fn new() -> HashSet<T> {
+ HashSet::with_capacity(INITIAL_CAPACITY)
+ }
+
+ /// Create an empty HashSet with space for at least `n` elements in
+ /// the hash table.
+ pub fn with_capacity(capacity: uint) -> HashSet<T> {
+ HashSet { map: HashMap::with_capacity(capacity) }
+ }
+
+ /// Create an empty HashSet with space for at least `capacity`
+ /// elements in the hash table, using `k0` and `k1` as the keys.
+ ///
+ /// Warning: `k0` and `k1` are normally randomly generated, and
+ /// are designed to allow HashSets to be resistant to attacks that
+ /// cause many collisions and very poor performance. Setting them
+ /// manually using this function can expose a DoS attack vector.
+ pub fn with_capacity_and_keys(k0: u64, k1: u64, capacity: uint) -> HashSet<T> {
+ HashSet { map: HashMap::with_capacity_and_keys(k0, k1, capacity) }
+ }
+
+ /// Reserve space for at least `n` elements in the hash table.
+ pub fn reserve(&mut self, n: uint) {
+ self.map.reserve(n)
+ }
+
+ /// Returns true if the hash set contains a value equivalent to the
+ /// given query value.
+ pub fn contains_equiv<Q:Hash + Equiv<T>>(&self, value: &Q) -> bool {
+ self.map.contains_key_equiv(value)
+ }
+
+ /// An iterator visiting all elements in arbitrary order.
+ /// Iterator element type is &'a T.
+ pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
+ SetItems { iter: self.map.buckets.as_slice().iter() }
+ }
+
+ /// Creates a consuming iterator, that is, one that moves each value out
+ /// of the set in arbitrary order. The set cannot be used after calling
+ /// this.
+ pub fn move_iter(self) -> SetMoveItems<T> {
+ SetMoveItems {iter: self.map.buckets.move_iter()}
+ }
+
+ /// Visit the values representing the difference
+ pub fn difference<'a>(&'a self, other: &'a HashSet<T>) -> SetAlgebraItems<'a, T> {
+ Repeat::new(other)
+ .zip(self.iter())
+ .filter_map(|(other, elt)| {
+ if !other.contains(elt) { Some(elt) } else { None }
+ })
+ }
+
+ /// Visit the values representing the symmetric difference
+ pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T>)
+ -> Chain<SetAlgebraItems<'a, T>, SetAlgebraItems<'a, T>> {
+ self.difference(other).chain(other.difference(self))
+ }
+
+ /// Visit the values representing the intersection
+ pub fn intersection<'a>(&'a self, other: &'a HashSet<T>)
+ -> SetAlgebraItems<'a, T> {
+ Repeat::new(other)
+ .zip(self.iter())
+ .filter_map(|(other, elt)| {
+ if other.contains(elt) { Some(elt) } else { None }
+ })
+ }
+
+ /// Visit the values representing the union
+ pub fn union<'a>(&'a self, other: &'a HashSet<T>)
+ -> Chain<SetItems<'a, T>, SetAlgebraItems<'a, T>> {
+ self.iter().chain(other.difference(self))
+ }
+
+}
+
+impl<T:Hash + Eq + Clone> Clone for HashSet<T> {
+ fn clone(&self) -> HashSet<T> {
+ HashSet {
+ map: self.map.clone()
+ }
+ }
+}
+
+impl<A: fmt::Show + Hash + Eq> fmt::Show for HashSet<A> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ try!(write!(f.buf, r"\{"))
+ let mut first = true;
+ for x in self.iter() {
+ if first {
+ first = false;
+ } else {
+ try!(write!(f.buf, ", "));
+ }
+ try!(write!(f.buf, "{}", *x));
+ }
+ write!(f.buf, r"\}")
+ }
+}
+
+impl<A: fmt::Show + Hash + Eq> ToStr for HashSet<A> {
+ fn to_str(&self) -> ~str { format!("{}", *self) }
+}
+
+impl<K: Eq + Hash> FromIterator<K> for HashSet<K> {
+ fn from_iterator<T: Iterator<K>>(iter: &mut T) -> HashSet<K> {
+ let (lower, _) = iter.size_hint();
+ let mut set = HashSet::with_capacity(lower);
+ set.extend(iter);
+ set
+ }
+}
+
+impl<K: Eq + Hash> Extendable<K> for HashSet<K> {
+ fn extend<T: Iterator<K>>(&mut self, iter: &mut T) {
+ for k in *iter {
+ self.insert(k);
+ }
+ }
+}
+
+impl<K: Eq + Hash> Default for HashSet<K> {
+ fn default() -> HashSet<K> { HashSet::new() }
+}
+
+// `Repeat` is used to feed the filter closure an explicit capture
+// of a reference to the other set
+/// Set operations iterator
+pub type SetAlgebraItems<'a, T> =
+ FilterMap<'static,(&'a HashSet<T>, &'a T), &'a T,
+ Zip<Repeat<&'a HashSet<T>>,SetItems<'a,T>>>;
+
+impl<
+ E: Encoder,
+ K: Encodable<E> + Hash + IterBytes + Eq,
+ V: Encodable<E>
+> Encodable<E> for HashMap<K, V> {
+ fn encode(&self, e: &mut E) {
+ e.emit_map(self.len(), |e| {
+ let mut i = 0;
+ for (key, val) in self.iter() {
+ e.emit_map_elt_key(i, |e| key.encode(e));
+ e.emit_map_elt_val(i, |e| val.encode(e));
+ i += 1;
+ }
+ })
+ }
+}
+
+impl<
+ D: Decoder,
+ K: Decodable<D> + Hash + IterBytes + Eq,
+ V: Decodable<D>
+> Decodable<D> for HashMap<K, V> {
+ fn decode(d: &mut D) -> HashMap<K, V> {
+ d.read_map(|d, len| {
+ let mut map = HashMap::with_capacity(len);
+ for i in range(0u, len) {
+ let key = d.read_map_elt_key(i, |d| Decodable::decode(d));
+ let val = d.read_map_elt_val(i, |d| Decodable::decode(d));
+ map.insert(key, val);
+ }
+ map
+ })
+ }
+}
+
+impl<
+ S: Encoder,
+ T: Encodable<S> + Hash + IterBytes + Eq
+> Encodable<S> for HashSet<T> {
+ fn encode(&self, s: &mut S) {
+ s.emit_seq(self.len(), |s| {
+ let mut i = 0;
+ for e in self.iter() {
+ s.emit_seq_elt(i, |s| e.encode(s));
+ i += 1;
+ }
+ })
+ }
+}
+
+impl<
+ D: Decoder,
+ T: Decodable<D> + Hash + IterBytes + Eq
+> Decodable<D> for HashSet<T> {
+ fn decode(d: &mut D) -> HashSet<T> {
+ d.read_seq(|d, len| {
+ let mut set = HashSet::with_capacity(len);
+ for i in range(0u, len) {
+ set.insert(d.read_seq_elt(i, |d| Decodable::decode(d)));
+ }
+ set
+ })
+ }
+}
+
+#[cfg(test)]
+mod test_map {
+ use super::{HashMap, HashSet};
+ use std::fmt;
+
+ #[test]
+ fn test_create_capacity_zero() {
+ let mut m = HashMap::with_capacity(0);
+ assert!(m.insert(1, 1));
+ }
+
+ #[test]
+ fn test_insert() {
+ let mut m = HashMap::new();
+ assert!(m.insert(1, 2));
+ assert!(m.insert(2, 4));
+ assert_eq!(*m.get(&1), 2);
+ assert_eq!(*m.get(&2), 4);
+ }
+
+ #[test]
+ fn test_find_mut() {
+ let mut m = HashMap::new();
+ assert!(m.insert(1, 12));
+ assert!(m.insert(2, 8));
+ assert!(m.insert(5, 14));
+ let new = 100;
+ match m.find_mut(&5) {
+ None => fail!(), Some(x) => *x = new
+ }
+ assert_eq!(m.find(&5), Some(&new));
+ }
+
+ #[test]
+ fn test_insert_overwrite() {
+ let mut m = HashMap::new();
+ assert!(m.insert(1, 2));
+ assert_eq!(*m.get(&1), 2);
+ assert!(!m.insert(1, 3));
+ assert_eq!(*m.get(&1), 3);
+ }
+
+ #[test]
+ fn test_insert_conflicts() {
+ let mut m = HashMap::with_capacity(4);
+ assert!(m.insert(1, 2));
+ assert!(m.insert(5, 3));
+ assert!(m.insert(9, 4));
+ assert_eq!(*m.get(&9), 4);
+ assert_eq!(*m.get(&5), 3);
+ assert_eq!(*m.get(&1), 2);
+ }
+
+ #[test]
+ fn test_conflict_remove() {
+ let mut m = HashMap::with_capacity(4);
+ assert!(m.insert(1, 2));
+ assert!(m.insert(5, 3));
+ assert!(m.insert(9, 4));
+ assert!(m.remove(&1));
+ assert_eq!(*m.get(&9), 4);
+ assert_eq!(*m.get(&5), 3);
+ }
+
+ #[test]
+ fn test_is_empty() {
+ let mut m = HashMap::with_capacity(4);
+ assert!(m.insert(1, 2));
+ assert!(!m.is_empty());
+ assert!(m.remove(&1));
+ assert!(m.is_empty());
+ }
+
+ #[test]
+ fn test_pop() {
+ let mut m = HashMap::new();
+ m.insert(1, 2);
+ assert_eq!(m.pop(&1), Some(2));
+ assert_eq!(m.pop(&1), None);
+ }
+
+ #[test]
+ fn test_swap() {
+ let mut m = HashMap::new();
+ assert_eq!(m.swap(1, 2), None);
+ assert_eq!(m.swap(1, 3), Some(2));
+ assert_eq!(m.swap(1, 4), Some(3));
+ }
+
+ #[test]
+ fn test_find_or_insert() {
+ let mut m: HashMap<int,int> = HashMap::new();
+ assert_eq!(*m.find_or_insert(1, 2), 2);
+ assert_eq!(*m.find_or_insert(1, 3), 2);
+ }
+
+ #[test]
+ fn test_find_or_insert_with() {
+ let mut m: HashMap<int,int> = HashMap::new();
+ assert_eq!(*m.find_or_insert_with(1, |_| 2), 2);
+ assert_eq!(*m.find_or_insert_with(1, |_| 3), 2);
+ }
+
+ #[test]
+ fn test_insert_or_update_with() {
+ let mut m: HashMap<int,int> = HashMap::new();
+ assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 2);
+ assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 3);
+ }
+
+ #[test]
+ fn test_move_iter() {
+ let hm = {
+ let mut hm = HashMap::new();
+
+ hm.insert('a', 1);
+ hm.insert('b', 2);
+
+ hm
+ };
+
+ let v = hm.move_iter().collect::<~[(char, int)]>();
+ assert!([('a', 1), ('b', 2)] == v || [('b', 2), ('a', 1)] == v);
+ }
+
+ #[test]
+ fn test_iterate() {
+ let mut m = HashMap::with_capacity(4);
+ for i in range(0u, 32) {
+ assert!(m.insert(i, i*2));
+ }
+ let mut observed = 0;
+ for (k, v) in m.iter() {
+ assert_eq!(*v, *k * 2);
+ observed |= (1 << *k);
+ }
+ assert_eq!(observed, 0xFFFF_FFFF);
+ }
+
+ #[test]
+ fn test_keys() {
+ let vec = ~[(1, 'a'), (2, 'b'), (3, 'c')];
+ let map = vec.move_iter().collect::<HashMap<int, char>>();
+ let keys = map.keys().map(|&k| k).collect::<~[int]>();
+ assert_eq!(keys.len(), 3);
+ assert!(keys.contains(&1));
+ assert!(keys.contains(&2));
+ assert!(keys.contains(&3));
+ }
+
+ #[test]
+ fn test_values() {
+ let vec = ~[(1, 'a'), (2, 'b'), (3, 'c')];
+ let map = vec.move_iter().collect::<HashMap<int, char>>();
+ let values = map.values().map(|&v| v).collect::<~[char]>();
+ assert_eq!(values.len(), 3);
+ assert!(values.contains(&'a'));
+ assert!(values.contains(&'b'));
+ assert!(values.contains(&'c'));
+ }
+
+ #[test]
+ fn test_find() {
+ let mut m = HashMap::new();
+ assert!(m.find(&1).is_none());
+ m.insert(1, 2);
+ match m.find(&1) {
+ None => fail!(),
+ Some(v) => assert!(*v == 2)
+ }
+ }
+
+ #[test]
+ fn test_eq() {
+ let mut m1 = HashMap::new();
+ m1.insert(1, 2);
+ m1.insert(2, 3);
+ m1.insert(3, 4);
+
+ let mut m2 = HashMap::new();
+ m2.insert(1, 2);
+ m2.insert(2, 3);
+
+ assert!(m1 != m2);
+
+ m2.insert(3, 4);
+
+ assert_eq!(m1, m2);
+ }
+
+ #[test]
+ fn test_expand() {
+ let mut m = HashMap::new();
+
+ assert_eq!(m.len(), 0);
+ assert!(m.is_empty());
+
+ let mut i = 0u;
+ let old_resize_at = m.resize_at;
+ while old_resize_at == m.resize_at {
+ m.insert(i, i);
+ i += 1;
+ }
+
+ assert_eq!(m.len(), i);
+ assert!(!m.is_empty());
+ }
+
+ #[test]
+ fn test_find_equiv() {
+ let mut m = HashMap::new();
+
+ let (foo, bar, baz) = (1,2,3);
+ m.insert(~"foo", foo);
+ m.insert(~"bar", bar);
+ m.insert(~"baz", baz);
+
+
+ assert_eq!(m.find_equiv(&("foo")), Some(&foo));
+ assert_eq!(m.find_equiv(&("bar")), Some(&bar));
+ assert_eq!(m.find_equiv(&("baz")), Some(&baz));
+
+ assert_eq!(m.find_equiv(&("qux")), None);
+ }
+
+ #[test]
+ fn test_from_iter() {
+ let xs = ~[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+ let map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
+
+ for &(k, v) in xs.iter() {
+ assert_eq!(map.find(&k), Some(&v));
+ }
+ }
+
+ struct ShowableStruct {
+ value: int,
+ }
+
+ impl fmt::Show for ShowableStruct {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f.buf, r"s{}", self.value)
+ }
+ }
+
+ #[test]
+ fn test_show() {
+ let mut table: HashMap<int, ShowableStruct> = HashMap::new();
+ let empty: HashMap<int, ShowableStruct> = HashMap::new();
+
+ table.insert(3, ShowableStruct { value: 4 });
+ table.insert(1, ShowableStruct { value: 2 });
+
+ let table_str = format!("{}", table);
+
+ assert!(table_str == ~"{1: s2, 3: s4}" || table_str == ~"{3: s4, 1: s2}");
+ assert_eq!(format!("{}", empty), ~"{}");
+ }
+
+ struct StructWithToStrWithoutEqOrHash {
+ value: int
+ }
+
+ impl fmt::Show for StructWithToStrWithoutEqOrHash {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f.buf, "s{}", self.value)
+ }
+ }
+
+ #[test]
+ fn test_hashset() {
+ let mut set: HashSet<int> = HashSet::new();
+ let empty_set: HashSet<int> = HashSet::new();
+
+ set.insert(1);
+ set.insert(2);
+
+ let set_str = set.to_str();
+
+ assert!(set_str == ~"{1, 2}" || set_str == ~"{2, 1}");
+ assert_eq!(empty_set.to_str(), ~"{}");
+ }
+
+ #[test]
+ fn test_hashmap() {
+ let mut table: HashMap<int, StructWithToStrWithoutEqOrHash> = HashMap::new();
+ let empty: HashMap<int, StructWithToStrWithoutEqOrHash> = HashMap::new();
+
+ table.insert(3, StructWithToStrWithoutEqOrHash { value: 4 });
+ table.insert(1, StructWithToStrWithoutEqOrHash { value: 2 });
+
+ let table_str = table.to_str();
+
+ assert!(table_str == ~"{1: s2, 3: s4}" || table_str == ~"{3: s4, 1: s2}");
+ assert_eq!(empty.to_str(), ~"{}");
+ }
+}
+
+#[cfg(test)]
+mod test_set {
+ use super::HashSet;
+
+ #[test]
+ fn test_disjoint() {
+ let mut xs = HashSet::new();
+ let mut ys = HashSet::new();
+ assert!(xs.is_disjoint(&ys));
+ assert!(ys.is_disjoint(&xs));
+ assert!(xs.insert(5));
+ assert!(ys.insert(11));
+ assert!(xs.is_disjoint(&ys));
+ assert!(ys.is_disjoint(&xs));
+ assert!(xs.insert(7));
+ assert!(xs.insert(19));
+ assert!(xs.insert(4));
+ assert!(ys.insert(2));
+ assert!(ys.insert(-11));
+ assert!(xs.is_disjoint(&ys));
+ assert!(ys.is_disjoint(&xs));
+ assert!(ys.insert(7));
+ assert!(!xs.is_disjoint(&ys));
+ assert!(!ys.is_disjoint(&xs));
+ }
+
+ #[test]
+ fn test_subset_and_superset() {
+ let mut a = HashSet::new();
+ assert!(a.insert(0));
+ assert!(a.insert(5));
+ assert!(a.insert(11));
+ assert!(a.insert(7));
+
+ let mut b = HashSet::new();
+ assert!(b.insert(0));
+ assert!(b.insert(7));
+ assert!(b.insert(19));
+ assert!(b.insert(250));
+ assert!(b.insert(11));
+ assert!(b.insert(200));
+
+ assert!(!a.is_subset(&b));
+ assert!(!a.is_superset(&b));
+ assert!(!b.is_subset(&a));
+ assert!(!b.is_superset(&a));
+
+ assert!(b.insert(5));
+
+ assert!(a.is_subset(&b));
+ assert!(!a.is_superset(&b));
+ assert!(!b.is_subset(&a));
+ assert!(b.is_superset(&a));
+ }
+
+ #[test]
+ fn test_iterate() {
+ let mut a = HashSet::new();
+ for i in range(0u, 32) {
+ assert!(a.insert(i));
+ }
+ let mut observed = 0;
+ for k in a.iter() {
+ observed |= (1 << *k);
+ }
+ assert_eq!(observed, 0xFFFF_FFFF);
+ }
+
+ #[test]
+ fn test_intersection() {
+ let mut a = HashSet::new();
+ let mut b = HashSet::new();
+
+ assert!(a.insert(11));
+ assert!(a.insert(1));
+ assert!(a.insert(3));
+ assert!(a.insert(77));
+ assert!(a.insert(103));
+ assert!(a.insert(5));
+ assert!(a.insert(-5));
+
+ assert!(b.insert(2));
+ assert!(b.insert(11));
+ assert!(b.insert(77));
+ assert!(b.insert(-9));
+ assert!(b.insert(-42));
+ assert!(b.insert(5));
+ assert!(b.insert(3));
+
+ let mut i = 0;
+ let expected = [3, 5, 11, 77];
+ for x in a.intersection(&b) {
+ assert!(expected.contains(x));
+ i += 1
+ }
+ assert_eq!(i, expected.len());
+ }
+
+ #[test]
+ fn test_difference() {
+ let mut a = HashSet::new();
+ let mut b = HashSet::new();
+
+ assert!(a.insert(1));
+ assert!(a.insert(3));
+ assert!(a.insert(5));
+ assert!(a.insert(9));
+ assert!(a.insert(11));
+
+ assert!(b.insert(3));
+ assert!(b.insert(9));
+
+ let mut i = 0;
+ let expected = [1, 5, 11];
+ for x in a.difference(&b) {
+ assert!(expected.contains(x));
+ i += 1
+ }
+ assert_eq!(i, expected.len());
+ }
+
+ #[test]
+ fn test_symmetric_difference() {
+ let mut a = HashSet::new();
+ let mut b = HashSet::new();
+
+ assert!(a.insert(1));
+ assert!(a.insert(3));
+ assert!(a.insert(5));
+ assert!(a.insert(9));
+ assert!(a.insert(11));
+
+ assert!(b.insert(-2));
+ assert!(b.insert(3));
+ assert!(b.insert(9));
+ assert!(b.insert(14));
+ assert!(b.insert(22));
+
+ let mut i = 0;
+ let expected = [-2, 1, 5, 11, 14, 22];
+ for x in a.symmetric_difference(&b) {
+ assert!(expected.contains(x));
+ i += 1
+ }
+ assert_eq!(i, expected.len());
+ }
+
+ #[test]
+ fn test_union() {
+ let mut a = HashSet::new();
+ let mut b = HashSet::new();
+
+ assert!(a.insert(1));
+ assert!(a.insert(3));
+ assert!(a.insert(5));
+ assert!(a.insert(9));
+ assert!(a.insert(11));
+ assert!(a.insert(16));
+ assert!(a.insert(19));
+ assert!(a.insert(24));
+
+ assert!(b.insert(-2));
+ assert!(b.insert(1));
+ assert!(b.insert(5));
+ assert!(b.insert(9));
+ assert!(b.insert(13));
+ assert!(b.insert(19));
+
+ let mut i = 0;
+ let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
+ for x in a.union(&b) {
+ assert!(expected.contains(x));
+ i += 1
+ }
+ assert_eq!(i, expected.len());
+ }
+
+ #[test]
+ fn test_from_iter() {
+ let xs = ~[1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+ let set: HashSet<int> = xs.iter().map(|&x| x).collect();
+
+ for x in xs.iter() {
+ assert!(set.contains(x));
+ }
+ }
+
+ #[test]
+ fn test_move_iter() {
+ let hs = {
+ let mut hs = HashSet::new();
+
+ hs.insert('a');
+ hs.insert('b');
+
+ hs
+ };
+
+ let v = hs.move_iter().collect::<~[char]>();
+ assert!(['a', 'b'] == v || ['b', 'a'] == v);
+ }
+
+ #[test]
+ fn test_eq() {
+ let mut s1 = HashSet::new();
+ s1.insert(1);
+ s1.insert(2);
+ s1.insert(3);
+
+ let mut s2 = HashSet::new();
+ s2.insert(1);
+ s2.insert(2);
+
+ assert!(s1 != s2);
+
+ s2.insert(3);
+
+ assert_eq!(s1, s2);
+ }
+
+ #[test]
+ fn test_show() {
+ let mut set: HashSet<int> = HashSet::new();
+ let empty: HashSet<int> = HashSet::new();
+
+ set.insert(1);
+ set.insert(2);
+
+ let set_str = format!("{}", set);
+
+ assert!(set_str == ~"{1, 2}" || set_str == ~"{2, 1}");
+ assert_eq!(format!("{}", empty), ~"{}");
+ }
+}
pub use deque::Deque;
pub use dlist::DList;
pub use enum_set::EnumSet;
+pub use hashmap::{HashMap, HashSet};
pub use list::List;
pub use lru_cache::LruCache;
pub use priority_queue::PriorityQueue;
pub use ringbuf::RingBuf;
pub use smallintmap::SmallIntMap;
pub use treemap::{TreeMap, TreeSet};
+pub use trie::{TrieMap, TrieSet};
pub mod bitv;
pub mod btree;
pub mod deque;
pub mod dlist;
pub mod enum_set;
+pub mod hashmap;
pub mod list;
pub mod lru_cache;
pub mod priority_queue;
pub mod ringbuf;
pub mod smallintmap;
pub mod treemap;
+pub mod trie;
//! ```
use std::container::Container;
-use std::hashmap::HashMap;
use std::to_bytes::Cb;
use std::ptr;
use std::cast;
+use HashMap;
+
struct KeyRef<K> { k: *K }
struct LruEntry<K, V> {
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Ordered containers with integer keys, implemented as radix tries (`TrieSet` and `TrieMap` types)
+
+use std::mem;
+use std::uint;
+use std::mem::init;
+use std::vec;
+use std::vec::{Items, MutItems};
+
+use serialize::{Encodable, Decodable, Encoder, Decoder};
+
+// FIXME: #5244: need to manually update the TrieNode constructor
+static SHIFT: uint = 4;
+static SIZE: uint = 1 << SHIFT;
+static MASK: uint = SIZE - 1;
+static NUM_CHUNKS: uint = uint::BITS / SHIFT;
+
+enum Child<T> {
+ Internal(~TrieNode<T>),
+ External(uint, T),
+ Nothing
+}
+
+#[allow(missing_doc)]
+pub struct TrieMap<T> {
+ priv root: TrieNode<T>,
+ priv length: uint
+}
+
+impl<T> Container for TrieMap<T> {
+ /// Return the number of elements in the map
+ #[inline]
+ fn len(&self) -> uint { self.length }
+}
+
+impl<T> Mutable for TrieMap<T> {
+ /// Clear the map, removing all values.
+ #[inline]
+ fn clear(&mut self) {
+ self.root = TrieNode::new();
+ self.length = 0;
+ }
+}
+
+impl<T> Map<uint, T> for TrieMap<T> {
+ /// Return a reference to the value corresponding to the key
+ #[inline]
+ fn find<'a>(&'a self, key: &uint) -> Option<&'a T> {
+ let mut node: &'a TrieNode<T> = &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;
+ }
+ }
+}
+
+impl<T> MutableMap<uint, T> for TrieMap<T> {
+ /// Return a mutable reference to the value corresponding to the key
+ #[inline]
+ fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
+ find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
+ }
+
+ /// Insert a key-value pair from the map. If the key already had a value
+ /// present in the map, that value is returned. Otherwise None is returned.
+ fn swap(&mut self, key: uint, value: T) -> Option<T> {
+ let ret = insert(&mut self.root.count,
+ &mut self.root.children[chunk(key, 0)],
+ key, value, 1);
+ if ret.is_none() { self.length += 1 }
+ ret
+ }
+
+ /// Removes a key from the map, returning the value at the key if the key
+ /// was previously in the map.
+ fn pop(&mut self, key: &uint) -> Option<T> {
+ let ret = remove(&mut self.root.count,
+ &mut self.root.children[chunk(*key, 0)],
+ *key, 1);
+ if ret.is_some() { self.length -= 1 }
+ ret
+ }
+}
+
+impl<T> TrieMap<T> {
+ /// Create an empty TrieMap
+ #[inline]
+ pub fn new() -> TrieMap<T> {
+ TrieMap{root: TrieNode::new(), length: 0}
+ }
+
+ /// Visit all key-value pairs in reverse order
+ #[inline]
+ pub fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
+ self.root.each_reverse(f)
+ }
+
+ /// Get an iterator over the key-value pairs in the map
+ 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
+ }
+
+ /// Get an iterator over the key-value pairs in the map, with the
+ /// ability to mutate the values.
+ pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, T> {
+ let mut iter = unsafe {MutEntries::new()};
+ iter.stack[0] = self.root.children.mut_iter();
+ iter.length = 1;
+ iter.remaining_min = self.length;
+ iter.remaining_max = self.length;
+
+ iter
+ }
+}
+
+// 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 `& <mutability> <operand>` token
+// sequence and forces their evalutation 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
+ // TrieNodes 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 = addr!(& $($mut_)* this.root as * $($mut_)* TrieNode<T>);
+
+ 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 = addr!(& $($mut_)* **n as * $($mut_)* TrieNode<T>);
+ (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<T> TrieMap<T> {
+ // 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, iter = iter,
+ mutability = )
+ }
+
+ /// Get 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.
+ pub fn lower_bound<'a>(&'a self, key: uint) -> Entries<'a, T> {
+ self.bound(key, false)
+ }
+
+ /// Get 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.
+ 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 mut_bound<'a>(&'a mut self, key: uint, upper: bool) -> MutEntries<'a, T> {
+ bound!(MutEntries, self = self,
+ key = key, is_upper = upper,
+ slice_from = mut_slice_from, iter = mut_iter,
+ mutability = mut)
+ }
+
+ /// Get 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.
+ pub fn mut_lower_bound<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
+ self.mut_bound(key, false)
+ }
+
+ /// Get 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.
+ pub fn mut_upper_bound<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
+ self.mut_bound(key, true)
+ }
+}
+
+impl<T> FromIterator<(uint, T)> for TrieMap<T> {
+ fn from_iterator<Iter: Iterator<(uint, T)>>(iter: &mut Iter) -> TrieMap<T> {
+ let mut map = TrieMap::new();
+ map.extend(iter);
+ map
+ }
+}
+
+impl<T> Extendable<(uint, T)> for TrieMap<T> {
+ fn extend<Iter: Iterator<(uint, T)>>(&mut self, iter: &mut Iter) {
+ for (k, v) in *iter {
+ self.insert(k, v);
+ }
+ }
+}
+
+#[allow(missing_doc)]
+pub struct TrieSet {
+ priv map: TrieMap<()>
+}
+
+impl Container for TrieSet {
+ /// Return the number of elements in the set
+ #[inline]
+ fn len(&self) -> uint { self.map.len() }
+}
+
+impl Mutable for TrieSet {
+ /// Clear the set, removing all values.
+ #[inline]
+ fn clear(&mut self) { self.map.clear() }
+}
+
+impl TrieSet {
+ /// Create an empty TrieSet
+ #[inline]
+ pub fn new() -> TrieSet {
+ TrieSet{map: TrieMap::new()}
+ }
+
+ /// Return true if the set contains a value
+ #[inline]
+ pub fn contains(&self, value: &uint) -> bool {
+ self.map.contains_key(value)
+ }
+
+ /// Add a value to the set. Return true if the value was not already
+ /// present in the set.
+ #[inline]
+ pub fn insert(&mut self, value: uint) -> bool {
+ self.map.insert(value, ())
+ }
+
+ /// Remove a value from the set. Return true if the value was
+ /// present in the set.
+ #[inline]
+ pub fn remove(&mut self, value: &uint) -> bool {
+ self.map.remove(value)
+ }
+
+ /// Visit all values in reverse order
+ #[inline]
+ pub fn each_reverse(&self, f: |&uint| -> bool) -> bool {
+ self.map.each_reverse(|k, _| f(k))
+ }
+
+ /// Get an iterator over the values in the set
+ #[inline]
+ pub fn iter<'a>(&'a self) -> SetItems<'a> {
+ SetItems{iter: self.map.iter()}
+ }
+
+ /// Get 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.
+ pub fn lower_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
+ SetItems{iter: self.map.lower_bound(val)}
+ }
+
+ /// Get an iterator pointing to the first value that key is greater than `val`.
+ /// If all values in the set are not greater than `val` an empty iterator is returned.
+ pub fn upper_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
+ SetItems{iter: self.map.upper_bound(val)}
+ }
+}
+
+impl FromIterator<uint> for TrieSet {
+ fn from_iterator<Iter: Iterator<uint>>(iter: &mut Iter) -> TrieSet {
+ let mut set = TrieSet::new();
+ set.extend(iter);
+ set
+ }
+}
+
+impl Extendable<uint> for TrieSet {
+ fn extend<Iter: Iterator<uint>>(&mut self, iter: &mut Iter) {
+ for elem in *iter {
+ self.insert(elem);
+ }
+ }
+}
+
+struct TrieNode<T> {
+ count: uint,
+ children: [Child<T>, ..SIZE]
+}
+
+impl<T> TrieNode<T> {
+ #[inline]
+ fn new() -> TrieNode<T> {
+ // FIXME: #5244: [Nothing, ..SIZE] should be possible without implicit
+ // copyability
+ TrieNode{count: 0,
+ children: [Nothing, Nothing, Nothing, Nothing,
+ Nothing, Nothing, Nothing, Nothing,
+ Nothing, Nothing, Nothing, Nothing,
+ Nothing, Nothing, Nothing, Nothing]}
+ }
+}
+
+impl<T> TrieNode<T> {
+ fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
+ for elt in self.children.rev_iter() {
+ 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 Child<T>, 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
+ }
+}
+
+fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
+ idx: uint) -> Option<T> {
+ // 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 *child {
+ Nothing => {
+ *count += 1;
+ *child = External(key, value);
+ return None;
+ }
+ Internal(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.
+ return Some(mem::replace(stored_value, value));
+ }
+ _ => {}
+ }
+
+ // conflict, an external node with differing keys: we have to
+ // split the node, so we need the old value by value; hence we
+ // have to move out of `child`.
+ match mem::replace(child, Nothing) {
+ External(stored_key, stored_value) => {
+ let mut new = ~TrieNode::new();
+ insert(&mut new.count,
+ &mut new.children[chunk(stored_key, idx)],
+ stored_key, stored_value, idx + 1);
+ let ret = insert(&mut new.count, &mut new.children[chunk(key, idx)],
+ key, value, idx + 1);
+ *child = Internal(new);
+ return ret;
+ }
+ _ => unreachable!()
+ }
+}
+
+fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
+ idx: uint) -> Option<T> {
+ let (ret, this) = match *child {
+ External(stored, _) if stored == key => {
+ match mem::replace(child, Nothing) {
+ External(_, value) => (Some(value), true),
+ _ => fail!()
+ }
+ }
+ External(..) => (None, false),
+ Internal(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;
+}
+
+/// Forward iterator over a map
+pub struct Entries<'a, T> {
+ priv stack: [vec::Items<'a, Child<T>>, .. NUM_CHUNKS],
+ priv length: uint,
+ priv remaining_min: uint,
+ priv remaining_max: uint
+}
+
+/// Forward iterator over the key-value pairs of a map, with the
+/// values being mutable.
+pub struct MutEntries<'a, T> {
+ priv stack: [vec::MutItems<'a, Child<T>>, .. NUM_CHUNKS],
+ priv length: uint,
+ priv remaining_min: uint,
+ priv remaining_max: uint
+}
+
+// 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: [init(), init(), init(), init(), init(), init(), init(), init()]
+ }
+ }
+
+ #[cfg(target_word_size="64")]
+ unsafe fn new() -> $name<'a, T> {
+ $name {
+ remaining_min: 0,
+ remaining_max: 0,
+ length: 0,
+ stack: [init(), init(), init(), init(), init(), init(), init(), init(),
+ init(), init(), init(), init(), init(), init(), init(), init()]
+ }
+ }
+ }
+
+ 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
+ // bench_iter_large microbenchmark down to about 30000 ns/iter
+ // (using .unsafe_ref 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<uint>) {
+ (self.remaining_min, Some(self.remaining_max))
+ }
+ })
+ }
+}
+
+iterator_impl! { Entries, iter = iter, mutability = }
+iterator_impl! { MutEntries, iter = mut_iter, mutability = mut }
+
+/// Forward iterator over a set
+pub struct SetItems<'a> {
+ priv iter: Entries<'a, ()>
+}
+
+impl<'a> Iterator<uint> for SetItems<'a> {
+ fn next(&mut self) -> Option<uint> {
+ self.iter.next().map(|(key, _)| key)
+ }
+
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<
+ E: Encoder,
+ V: Encodable<E>
+> Encodable<E> for TrieMap<V> {
+ fn encode(&self, e: &mut E) {
+ e.emit_map(self.len(), |e| {
+ for (i, (key, val)) in self.iter().enumerate() {
+ e.emit_map_elt_key(i, |e| key.encode(e));
+ e.emit_map_elt_val(i, |e| val.encode(e));
+ }
+ });
+ }
+}
+
+impl<
+ D: Decoder,
+ V: Decodable<D>
+> Decodable<D> for TrieMap<V> {
+ fn decode(d: &mut D) -> TrieMap<V> {
+ d.read_map(|d, len| {
+ let mut map = TrieMap::new();
+ for i in range(0u, len) {
+ let key = d.read_map_elt_key(i, |d| Decodable::decode(d));
+ let val = d.read_map_elt_val(i, |d| Decodable::decode(d));
+ map.insert(key, val);
+ }
+ map
+ })
+ }
+}
+
+impl<S: Encoder> Encodable<S> for TrieSet {
+ fn encode(&self, s: &mut S) {
+ s.emit_seq(self.len(), |s| {
+ for (i, e) in self.iter().enumerate() {
+ s.emit_seq_elt(i, |s| e.encode(s));
+ }
+ })
+ }
+}
+
+impl<D: Decoder> Decodable<D> for TrieSet {
+ fn decode(d: &mut D) -> TrieSet {
+ d.read_seq(|d, len| {
+ let mut set = TrieSet::new();
+ for i in range(0u, len) {
+ set.insert(d.read_seq_elt(i, |d| Decodable::decode(d)));
+ }
+ set
+ })
+ }
+}
+
+#[cfg(test)]
+mod test_map {
+ use super::{TrieMap, TrieNode, Internal, External};
+ use std::iter::range_step;
+ use std::uint;
+
+ fn check_integrity<T>(trie: &TrieNode<T>) {
+ 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(1, 12));
+ assert!(m.insert(2, 8));
+ assert!(m.insert(5, 14));
+ let new = 100;
+ match m.find_mut(&5) {
+ None => fail!(), Some(x) => *x = new
+ }
+ assert_eq!(m.find(&5), Some(&new));
+ }
+
+ #[test]
+ fn test_find_mut_missing() {
+ let mut m = TrieMap::new();
+ assert!(m.find_mut(&0).is_none());
+ assert!(m.insert(1, 12));
+ assert!(m.find_mut(&0).is_none());
+ assert!(m.insert(2, 8));
+ assert!(m.find_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));
+ 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));
+ check_integrity(&trie.root);
+ }
+
+ for x in range(0u, n) {
+ assert!(trie.contains_key(&x));
+ assert!(!trie.insert(x, x + 1));
+ check_integrity(&trie.root);
+ }
+
+ for x in range_step(1u, n, 2) {
+ assert!(trie.remove(&x));
+ 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));
+ check_integrity(&trie.root);
+ }
+ }
+
+ #[test]
+ fn test_each_reverse() {
+ let mut m = TrieMap::new();
+
+ assert!(m.insert(3, 6));
+ assert!(m.insert(0, 0));
+ assert!(m.insert(4, 8));
+ assert!(m.insert(2, 4));
+ assert!(m.insert(1, 2));
+
+ let mut n = 4;
+ 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_swap() {
+ let mut m = TrieMap::new();
+ assert_eq!(m.swap(1, 2), None);
+ assert_eq!(m.swap(1, 3), Some(2));
+ assert_eq!(m.swap(1, 4), Some(3));
+ }
+
+ #[test]
+ fn test_pop() {
+ let mut m = TrieMap::new();
+ m.insert(1, 2);
+ assert_eq!(m.pop(&1), Some(2));
+ assert_eq!(m.pop(&1), None);
+ }
+
+ #[test]
+ fn test_from_iter() {
+ let xs = ~[(1u, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+ let map: TrieMap<int> = xs.iter().map(|&x| x).collect();
+
+ for &(k, v) in xs.iter() {
+ assert_eq!(map.find(&k), Some(&v));
+ }
+ }
+
+ #[test]
+ fn test_iteration() {
+ let empty_map : TrieMap<uint> = 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<uint> = TrieMap::new();
+ assert!(empty_map.mut_iter().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.mut_iter() {
+ 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<uint> = 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<uint> = 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<uint> = 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.mut_lower_bound(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.mut_upper_bound(i);
+ let (k, v) = ub_it.next().unwrap();
+ let ub = i + 2 - i % 2;
+ assert_eq!(ub, k);
+ *v -= k;
+ }
+
+ assert!(m_lower.mut_lower_bound(199).next().is_none());
+ assert!(m_upper.mut_upper_bound(198).next().is_none());
+
+ assert!(m_lower.iter().all(|(_, &x)| x == 0));
+ assert!(m_upper.iter().all(|(_, &x)| x == 0));
+ }
+}
+
+#[cfg(test)]
+mod bench_map {
+ extern crate test;
+ use super::TrieMap;
+ use std::rand::{weak_rng, Rng};
+ use self::test::BenchHarness;
+
+ #[bench]
+ fn bench_iter_small(bh: &mut BenchHarness) {
+ let mut m = TrieMap::<uint>::new();
+ let mut rng = weak_rng();
+ for _ in range(0, 20) {
+ m.insert(rng.gen(), rng.gen());
+ }
+
+ bh.iter(|| for _ in m.iter() {})
+ }
+
+ #[bench]
+ fn bench_iter_large(bh: &mut BenchHarness) {
+ let mut m = TrieMap::<uint>::new();
+ let mut rng = weak_rng();
+ for _ in range(0, 1000) {
+ m.insert(rng.gen(), rng.gen());
+ }
+
+ bh.iter(|| for _ in m.iter() {})
+ }
+
+ #[bench]
+ fn bench_lower_bound(bh: &mut BenchHarness) {
+ let mut m = TrieMap::<uint>::new();
+ let mut rng = weak_rng();
+ for _ in range(0, 1000) {
+ m.insert(rng.gen(), rng.gen());
+ }
+
+ bh.iter(|| {
+ for _ in range(0, 10) {
+ m.lower_bound(rng.gen());
+ }
+ });
+ }
+
+ #[bench]
+ fn bench_upper_bound(bh: &mut BenchHarness) {
+ let mut m = TrieMap::<uint>::new();
+ let mut rng = weak_rng();
+ for _ in range(0, 1000) {
+ m.insert(rng.gen(), rng.gen());
+ }
+
+ bh.iter(|| {
+ for _ in range(0, 10) {
+ m.upper_bound(rng.gen());
+ }
+ });
+ }
+
+ #[bench]
+ fn bench_insert_large(bh: &mut BenchHarness) {
+ let mut m = TrieMap::<[uint, .. 10]>::new();
+ let mut rng = weak_rng();
+
+ bh.iter(|| {
+ for _ in range(0, 1000) {
+ m.insert(rng.gen(), [1, .. 10]);
+ }
+ })
+ }
+ #[bench]
+ fn bench_insert_large_low_bits(bh: &mut BenchHarness) {
+ let mut m = TrieMap::<[uint, .. 10]>::new();
+ let mut rng = weak_rng();
+
+ bh.iter(|| {
+ for _ in range(0, 1000) {
+ // only have the last few bits set.
+ m.insert(rng.gen::<uint>() & 0xff_ff, [1, .. 10]);
+ }
+ })
+ }
+
+ #[bench]
+ fn bench_insert_small(bh: &mut BenchHarness) {
+ let mut m = TrieMap::<()>::new();
+ let mut rng = weak_rng();
+
+ bh.iter(|| {
+ for _ in range(0, 1000) {
+ m.insert(rng.gen(), ());
+ }
+ })
+ }
+ #[bench]
+ fn bench_insert_small_low_bits(bh: &mut BenchHarness) {
+ let mut m = TrieMap::<()>::new();
+ let mut rng = weak_rng();
+
+ bh.iter(|| {
+ for _ in range(0, 1000) {
+ // only have the last few bits set.
+ m.insert(rng.gen::<uint>() & 0xff_ff, ());
+ }
+ })
+ }
+}
+
+#[cfg(test)]
+mod test_set {
+ use super::TrieSet;
+ use std::uint;
+
+ #[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 = ~[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));
+ }
+ }
+}
use std::char;
use std::f64;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::io;
use std::io::MemWriter;
use std::num;
use std::cmp;
use std::hash_old::Hash;
-use std::hashmap;
use std::io;
use std::mem;
use std::num;
+use collections::hashmap;
// NB: this can probably be rewritten in terms of num::Num
// to be less f64-specific.
use std::io::BufReader;
use std::cmp::Eq;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::to_bytes;
use std::uint;
use super::*;
- use std::hashmap::HashMap;
+ use collections::HashMap;
#[test]
fn test_url_parse() {
#[allow(non_camel_case_types)];
use std::comm::Data;
-use std::hashmap::HashMap;
use std::libc;
use std::mem;
use std::os;
// sorted list, and dead timers are those which have expired, but ownership
// hasn't yet been transferred back to the timer itself.
let mut active: ~[~Inner] = ~[];
- let mut dead = HashMap::new();
+ let mut dead = ~[];
// inserts a timer into an array of timers (sorted by firing time)
fn insert(t: ~Inner, active: &mut ~[~Inner]) {
}
// signals the first requests in the queue, possible re-enqueueing it.
- fn signal(active: &mut ~[~Inner], dead: &mut HashMap<uint, ~Inner>) {
+ fn signal(active: &mut ~[~Inner], dead: &mut ~[(uint, ~Inner)]) {
let mut timer = match active.shift() {
Some(timer) => timer, None => return
};
insert(timer, active);
} else {
drop(chan);
- dead.insert(timer.id, timer);
+ dead.push((timer.id, timer));
}
}
Data(NewTimer(timer)) => insert(timer, &mut active),
Data(RemoveTimer(id, ack)) => {
- match dead.pop(&id) {
- Some(i) => { ack.send(i); continue }
+ match dead.iter().position(|&(i, _)| id == i) {
+ Some(i) => {
+ let (_, i) = dead.remove(i).unwrap();
+ ack.send(i);
+ continue
+ }
None => {}
}
let i = active.iter().position(|i| i.id == id);
use std::ptr;
use std::os;
use std::rt::rtio;
-use std::hashmap::HashMap;
use std::mem;
use io::file::FileDesc;
add(efd, input);
let events: [imp::epoll_event, ..16] = unsafe { mem::init() };
- let mut map: HashMap<libc::c_int, (Chan<()>, bool)> = HashMap::new();
+ let mut list: ~[(libc::c_int, Chan<()>, bool)] = ~[];
'outer: loop {
let n = match unsafe {
imp::epoll_wait(efd, events.as_ptr(),
// FIXME: should this perform a send() this number of
// times?
let _ = FileDesc::new(fd, false).inner_read(bits).unwrap();
- let remove = {
- match map.find(&fd).expect("fd unregistered") {
- &(ref c, oneshot) => !c.try_send(()) || oneshot
+ let (remove, i) = {
+ match list.bsearch(|&(f, _, _)| f.cmp(&fd)) {
+ Some(i) => {
+ let (_, ref c, oneshot) = list[i];
+ (!c.try_send(()) || oneshot, i)
+ }
+ None => fail!("fd not active: {}", fd),
}
};
if remove {
- map.remove(&fd);
+ drop(list.remove(i));
del(efd, fd);
}
}
// If we haven't previously seen the file descriptor, then
// we need to add it to the epoll set.
- if map.insert(fd, (chan, one)) {
- add(efd, fd);
+ match list.bsearch(|&(f, _, _)| f.cmp(&fd)) {
+ Some(i) => {
+ drop(mem::replace(&mut list[i], (fd, chan, one)));
+ }
+ None => {
+ match list.iter().position(|&(f, _, _)| f >= fd) {
+ Some(i) => list.insert(i, (fd, chan, one)),
+ None => list.push((fd, chan, one)),
+ }
+ add(efd, fd);
+ }
}
// Update the timerfd's time value now that we have control
}
Data(RemoveTimer(fd, chan)) => {
- if map.remove(&fd) {
- del(efd, fd);
+ match list.bsearch(|&(f, _, _)| f.cmp(&fd)) {
+ Some(i) => {
+ drop(list.remove(i));
+ del(efd, fd);
+ }
+ None => {}
}
chan.send(());
}
Data(Shutdown) => {
- assert!(map.len() == 0);
+ assert!(list.len() == 0);
break 'outer;
}
use metadata::cstore;
use metadata::filesearch;
-use std::hashmap::HashSet;
+use collections::HashSet;
use std::{os, vec};
use syntax::abi;
use serialize::Encodable;
use std::cell::{Cell, RefCell};
-use std::hashmap::{HashMap,HashSet};
use std::io;
use std::io::fs;
use std::io::MemReader;
use std::os;
use std::vec;
+use collections::{HashMap, HashSet};
use getopts::{optopt, optmulti, optflag, optflagopt};
use getopts;
use syntax::ast;
use syntax;
use std::cell::{Cell, RefCell};
-use std::hashmap::{HashMap,HashSet};
+use collections::{HashMap,HashSet};
pub struct Config {
os: abi::Os,
use std::c_str::ToCStr;
use std::cell::RefCell;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::libc::{c_uint, c_ushort, c_void, free};
use std::str::raw::from_c_str;
use metadata::loader::Os;
use std::cell::RefCell;
-use std::hashmap::HashMap;
+use collections::HashMap;
use syntax::ast;
use syntax::abi;
use syntax::attr;
use metadata::loader;
use std::cell::RefCell;
-use std::hashmap::HashMap;
+use collections::HashMap;
use syntax::ast;
use syntax::parse::token::IdentInterner;
use std::cast;
use std::cell::{Cell, RefCell};
use std::hash_old::Hash;
-use std::hashmap::{HashMap, HashSet};
use std::io::MemWriter;
use std::str;
+use collections::{HashMap, HashSet};
use syntax::abi::AbiSet;
use syntax::ast::*;
use syntax::ast;
use std::option;
use std::os;
use std::io::fs;
-use std::hashmap::HashSet;
+use collections::HashSet;
pub enum FileMatch { FileMatches, FileDoesntMatch }
use std::c_str::ToCStr;
use std::cast;
-use std::hashmap::{HashMap, HashSet};
use std::cmp;
use std::io;
use std::os::consts::{macos, freebsd, linux, android, win32};
use std::str;
use std::vec;
+use collections::{HashMap, HashSet};
use flate;
use time;
#[allow(non_camel_case_types)];
use std::cell::RefCell;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::io;
use std::io::MemWriter;
use std::str;
use util::ppaux::{note_and_explain_region, Repr, UserString};
use std::cell::{Cell, RefCell};
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::ops::{BitOr, BitAnd};
use std::result::{Result};
use syntax::ast;
*/
use std::cell::RefCell;
-use std::hashmap::{HashMap, HashSet};
use std::uint;
+use collections::{HashMap, HashSet};
use middle::borrowck::*;
use middle::dataflow::DataFlowContext;
use middle::dataflow::DataFlowOperator;
use middle::graph;
use middle::typeck;
use middle::ty;
-use std::hashmap::HashMap;
+use collections::HashMap;
use syntax::ast;
use syntax::ast_util;
use syntax::opt_vec;
use middle::graph;
use middle::ty;
use middle::typeck;
-use std::hashmap::HashMap;
+use collections::HashMap;
use syntax::ast;
use syntax::opt_vec::OptVec;
use syntax::{ast, ast_map, ast_util};
use std::cell::RefCell;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::rc::Rc;
//
use std::io;
use std::uint;
use std::vec;
-use std::hashmap::HashMap;
+use collections::HashMap;
use syntax::ast;
use syntax::ast_util;
use syntax::ast_util::IdRange;
use middle::ty;
use middle::typeck;
-use std::hashmap::HashSet;
+use collections::HashSet;
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util::{local_def, def_id_of_def, is_local};
use middle::resolve;
use middle::ty;
-use std::hashmap::HashMap;
+use collections::HashMap;
use syntax::codemap::Span;
use syntax::{ast, ast_util};
use syntax::visit;
use syntax::visit::Visitor;
use syntax::visit;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::iter::Enumerate;
use std::vec;
use util::ppaux::{ty_to_str};
use std::cmp;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::i16;
use std::i32;
use std::i64;
use std::cast::transmute;
use std::cell::{Cell, RefCell};
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::io;
use std::str;
use std::to_str;
use util::ppaux::UserString;
use std::cell::RefCell;
-use std::hashmap::{HashSet, HashMap};
use std::rc::Rc;
+use collections::{HashSet, HashMap};
use syntax::ast::*;
use syntax::ast_util;
use syntax::visit;
use middle::resolve;
-use std::hashmap::HashMap;
+use collections::HashMap;
use syntax::ast::*;
use syntax::ast_util::{path_to_ident, walk_pat};
use syntax::codemap::Span;
//! outside their scopes. This pass will also generate a set of exported items
//! which are available for use externally when compiled as a library.
-use std::hashmap::{HashSet, HashMap};
use std::mem::replace;
+use collections::{HashSet, HashMap};
use metadata::csearch;
use middle::resolve;
use middle::privacy;
use std::cell::RefCell;
-use std::hashmap::HashSet;
+use collections::HashSet;
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util::{def_id_of_def, is_local};
use middle::ty;
use std::cell::RefCell;
-use std::hashmap::{HashMap, HashSet};
+use collections::{HashMap, HashSet};
use syntax::codemap::Span;
use syntax::{ast, visit};
use syntax::visit::{Visitor, FnKind};
use std::cell::{Cell, RefCell};
use std::uint;
-use std::hashmap::{HashMap, HashSet};
use std::mem::replace;
+use collections::{HashMap, HashSet};
// Definition mapping
pub type DefMap = @RefCell<HashMap<NodeId,Def>>;
use driver::session;
use std::cell::RefCell;
-use std::hashmap::HashMap;
+use collections::HashMap;
use syntax::ast;
use syntax::codemap::Span;
use syntax::opt_vec::OptVec;
use util::ppaux::{Repr, vec_map_to_str};
use std::cell::Cell;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::vec;
use syntax::ast;
use syntax::ast::Ident;
use arena::TypedArena;
use std::c_str::ToCStr;
use std::cell::{Cell, RefCell};
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::libc::c_uint;
use std::local_data;
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic, OsWin32};
use middle::trans::common::*;
use middle::trans::machine::llalign_of_pref;
use middle::trans::type_::Type;
-use std::hashmap::HashMap;
use std::libc::{c_uint, c_ulonglong, c_char};
+use collections::HashMap;
use syntax::codemap::Span;
pub struct Builder<'a> {
use arena::TypedArena;
use std::c_str::ToCStr;
use std::cell::{Cell, RefCell};
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::libc::{c_uint, c_longlong, c_ulonglong, c_char};
use syntax::ast::Ident;
use syntax::ast;
use std::cell::{Cell, RefCell};
use std::c_str::ToCStr;
-use std::hashmap::{HashMap, HashSet};
use std::local_data;
use std::libc::c_uint;
+use collections::{HashMap, HashSet};
use syntax::ast;
use syntax::parse::token::InternedString;
use std::c_str::{CString, ToCStr};
use std::cell::{Cell, RefCell};
-use std::hashmap::HashMap;
-use std::hashmap::HashSet;
+use collections::HashMap;
+use collections::HashSet;
use std::libc::{c_uint, c_ulonglong, c_longlong};
use std::ptr;
use std::sync::atomics;
use middle::trans::type_::Type;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::vec;
use syntax::ast;
use syntax::ast_map;
use std::cast;
use std::cell::{Cell, RefCell};
use std::cmp;
-use std::hashmap::{HashMap, HashSet};
use std::ops;
use std::rc::Rc;
use std::to_bytes;
use std::to_str::ToStr;
use std::vec;
+use collections::{HashMap, HashSet};
use syntax::ast::*;
use syntax::ast_util::{is_local, lit_is_str};
use syntax::ast_util;
}
/// Representation of regions:
-#[deriving(Clone, Eq, IterBytes, Encodable, Decodable, ToStr)]
+#[deriving(Clone, Eq, IterBytes, Encodable, Decodable, ToStr, Show)]
pub enum Region {
// Region bound in a type or fn declaration which will be
// substituted 'early' -- that is, at the same time when type
}
}
-#[deriving(Clone, Eq, TotalOrd, TotalEq, IterBytes, Encodable, Decodable, ToStr)]
+#[deriving(Clone, Eq, TotalOrd, TotalEq, IterBytes, Encodable, Decodable, ToStr, Show)]
pub struct FreeRegion {
scope_id: NodeId,
bound_region: BoundRegion
}
-#[deriving(Clone, Eq, TotalEq, TotalOrd, IterBytes, Encodable, Decodable, ToStr)]
+#[deriving(Clone, Eq, TotalEq, TotalOrd, IterBytes, Encodable, Decodable, ToStr, Show)]
pub enum BoundRegion {
/// An anonymous region parameter for a given fn (&T)
BrAnon(uint),
#[deriving(Clone, Eq, IterBytes)]
pub struct FloatVid(uint);
-#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
+#[deriving(Clone, Eq, Encodable, Decodable, IterBytes, Show)]
pub struct RegionVid {
id: uint
}
FloatVar(FloatVid)
}
-#[deriving(Clone, Encodable, Decodable, IterBytes, ToStr)]
+#[deriving(Clone, Encodable, Decodable, IterBytes, ToStr, Show)]
pub enum InferRegion {
ReVar(RegionVid),
ReSkolemized(uint, BoundRegion)
use middle::typeck::infer;
use middle::typeck::require_same_types;
-use std::hashmap::{HashMap, HashSet};
+use collections::{HashMap, HashSet};
use syntax::ast;
use syntax::ast_util;
use syntax::parse::token;
use util::ppaux::Repr;
use std::cell::RefCell;
-use std::hashmap::HashSet;
+use collections::HashSet;
use std::result;
use std::vec;
use syntax::ast::{DefId, SelfValue, SelfRegion};
use util::ppaux::{UserString, Repr};
use std::cell::{Cell, RefCell};
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::mem::replace;
use std::result;
use std::vec;
use middle::ty;
use middle::ty_fold;
use middle::ty_fold::TypeFolder;
-use std::hashmap::HashMap;
+use collections::HashMap;
use util::ppaux::Repr;
use util::ppaux;
});
ty_fold::super_fold_sig(&mut f, fn_sig)
};
- debug!("resulting map: {}", map.to_str());
+ debug!("resulting map: {}", map);
(map, fn_sig)
}
use util::ppaux::Repr;
use std::cell::RefCell;
-use std::hashmap::HashSet;
+use collections::HashSet;
use std::result;
use syntax::ast;
use syntax::ast_util;
use syntax::visit;
use std::cell::RefCell;
-use std::hashmap::HashSet;
+use collections::HashSet;
use std::rc::Rc;
use std::vec;
use syntax::ast::{Many, Once, MutImmutable, MutMutable};
use syntax::ast::{ExternFn, ImpureFn, UnsafeFn, NodeId};
use syntax::ast::{Onceness, Purity};
-use std::hashmap::HashMap;
+use collections::HashMap;
use util::common::{indenter};
use util::ppaux::mt_to_str;
use middle::typeck::infer::unify::*;
use middle::typeck::infer::sub::Sub;
use middle::typeck::infer::to_str::InferStr;
-use std::hashmap::HashMap;
+use collections::HashMap;
use util::common::indenter;
pub trait LatticeValue {
use middle::typeck::infer::{cres, InferCtxt};
use middle::typeck::infer::fold_regions_in_sig;
use middle::typeck::infer::{TypeTrace, Subtype};
-use std::hashmap::HashMap;
+use collections::HashMap;
use syntax::ast::{Many, Once, NodeId};
use syntax::ast::{ExternFn, ImpureFn, UnsafeFn};
use syntax::ast::{Onceness, Purity};
use middle::typeck::infer::unify::{ValsAndBindings, Root};
use middle::typeck::infer::error_reporting::ErrorReporting;
use std::cell::{Cell, RefCell};
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::result;
use std::vec;
use syntax::ast::{MutImmutable, MutMutable};
use util::ppaux::{Repr};
use std::cell::{Cell, RefCell};
-use std::hashmap::{HashMap, HashSet};
use std::uint;
use std::vec;
+use collections::{HashMap, HashSet};
use syntax::ast;
use syntax::opt_vec;
use syntax::opt_vec::OptVec;
use util::ppaux;
use std::cell::RefCell;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::rc::Rc;
use collections::List;
use collections::list;
*/
-use std::hashmap::HashMap;
+use collections::HashMap;
use arena;
use arena::Arena;
use middle::ty;
use std::cell::RefCell;
use std::os;
use std::local_data;
-use std::hashmap::{HashSet};
+use collections::HashSet;
use visit_ast::RustdocVisitor;
use clean;
//! both occur before the crate is rendered.
use std::fmt;
-use std::hashmap::{HashMap, HashSet};
use std::local_data;
use std::io;
use std::io::{fs, File, BufferedWriter};
use std::str;
use std::vec;
+use collections::{HashMap, HashSet};
use sync::Arc;
use extra::json::ToJson;
// except according to those terms.
use std::cmp;
-use std::hashmap::HashSet;
+use collections::HashSet;
use std::local_data;
use std::uint;
use syntax::ast;
// except according to those terms.
use std::cell::RefCell;
-use std::hashmap::HashSet;
+use collections::HashSet;
use std::local_data;
use std::os;
use std::run;
Core encoding and decoding interfaces.
*/
-use std::hash_old::Hash;
-use std::hashmap::{HashMap, HashSet};
use std::rc::Rc;
-use std::trie::{TrieMap, TrieSet};
use std::vec;
use std::vec_ng::Vec;
}
}
-impl<
- E: Encoder,
- K: Encodable<E> + Hash + IterBytes + Eq,
- V: Encodable<E>
-> Encodable<E> for HashMap<K, V> {
- fn encode(&self, e: &mut E) {
- e.emit_map(self.len(), |e| {
- let mut i = 0;
- for (key, val) in self.iter() {
- e.emit_map_elt_key(i, |e| key.encode(e));
- e.emit_map_elt_val(i, |e| val.encode(e));
- i += 1;
- }
- })
- }
-}
-
-impl<
- D: Decoder,
- K: Decodable<D> + Hash + IterBytes + Eq,
- V: Decodable<D>
-> Decodable<D> for HashMap<K, V> {
- fn decode(d: &mut D) -> HashMap<K, V> {
- d.read_map(|d, len| {
- let mut map = HashMap::with_capacity(len);
- for i in range(0u, len) {
- let key = d.read_map_elt_key(i, |d| Decodable::decode(d));
- let val = d.read_map_elt_val(i, |d| Decodable::decode(d));
- map.insert(key, val);
- }
- map
- })
- }
-}
-
-impl<
- S: Encoder,
- T: Encodable<S> + Hash + IterBytes + Eq
-> Encodable<S> for HashSet<T> {
- fn encode(&self, s: &mut S) {
- s.emit_seq(self.len(), |s| {
- let mut i = 0;
- for e in self.iter() {
- s.emit_seq_elt(i, |s| e.encode(s));
- i += 1;
- }
- })
- }
-}
-
-impl<
- D: Decoder,
- T: Decodable<D> + Hash + IterBytes + Eq
-> Decodable<D> for HashSet<T> {
- fn decode(d: &mut D) -> HashSet<T> {
- d.read_seq(|d, len| {
- let mut set = HashSet::with_capacity(len);
- for i in range(0u, len) {
- set.insert(d.read_seq_elt(i, |d| Decodable::decode(d)));
- }
- set
- })
- }
-}
-
-impl<
- E: Encoder,
- V: Encodable<E>
-> Encodable<E> for TrieMap<V> {
- fn encode(&self, e: &mut E) {
- e.emit_map(self.len(), |e| {
- for (i, (key, val)) in self.iter().enumerate() {
- e.emit_map_elt_key(i, |e| key.encode(e));
- e.emit_map_elt_val(i, |e| val.encode(e));
- }
- });
- }
-}
-
-impl<
- D: Decoder,
- V: Decodable<D>
-> Decodable<D> for TrieMap<V> {
- fn decode(d: &mut D) -> TrieMap<V> {
- d.read_map(|d, len| {
- let mut map = TrieMap::new();
- for i in range(0u, len) {
- let key = d.read_map_elt_key(i, |d| Decodable::decode(d));
- let val = d.read_map_elt_val(i, |d| Decodable::decode(d));
- map.insert(key, val);
- }
- map
- })
- }
-}
-
-impl<S: Encoder> Encodable<S> for TrieSet {
- fn encode(&self, s: &mut S) {
- s.emit_seq(self.len(), |s| {
- for (i, e) in self.iter().enumerate() {
- s.emit_seq_elt(i, |s| e.encode(s));
- }
- })
- }
-}
-
-impl<D: Decoder> Decodable<D> for TrieSet {
- fn decode(d: &mut D) -> TrieSet {
- d.read_seq(|d, len| {
- let mut set = TrieSet::new();
- for i in range(0u, len) {
- set.insert(d.read_seq_elt(i, |d| Decodable::decode(d)));
- }
- set
- })
- }
-}
-
// ___________________________________________________________________________
// Helper routines
//
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Unordered containers, implemented as hash-tables (`HashSet` and `HashMap` types)
-//!
-//! The tables use a keyed hash with new random keys generated for each container, so the ordering
-//! of a set of keys in a hash table is randomized.
-//!
-//! # Example
-//!
-//! ```rust
-//! use std::hashmap::HashMap;
-//!
-//! // type inference lets us omit an explicit type signature (which
-//! // would be `HashMap<&str, &str>` in this example).
-//! let mut book_reviews = HashMap::new();
-//!
-//! // review some books.
-//! book_reviews.insert("Adventures of Hucklebury Fin", "My favorite book.");
-//! book_reviews.insert("Grimms' Fairy Tales", "Masterpiece.");
-//! book_reviews.insert("Pride and Prejudice", "Very enjoyable.");
-//! book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot.");
-//!
-//! // check for a specific one.
-//! if !book_reviews.contains_key(& &"Les Misérables") {
-//! println!("We've got {} reviews, but Les Misérables ain't one.",
-//! book_reviews.len());
-//! }
-//!
-//! // oops, this review has a lot of spelling mistakes, let's delete it.
-//! book_reviews.remove(& &"The Adventures of Sherlock Holmes");
-//!
-//! // look up the values associated with some keys.
-//! let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
-//! for book in to_find.iter() {
-//! match book_reviews.find(book) {
-//! Some(review) => println!("{}: {}", *book, *review),
-//! None => println!("{} is unreviewed.", *book)
-//! }
-//! }
-//!
-//! // iterate over everything.
-//! for (book, review) in book_reviews.iter() {
-//! println!("{}: \"{}\"", *book, *review);
-//! }
-//! ```
-
-use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
-use clone::Clone;
-use cmp::{Eq, Equiv, max};
-use default::Default;
-use fmt;
-use hash_old::Hash;
-use iter;
-use iter::{Iterator, FromIterator, Extendable};
-use iter::{FilterMap, Chain, Repeat, Zip};
-use mem::replace;
-use num;
-use option::{None, Option, Some};
-use rand::Rng;
-use rand;
-use result::{Ok, Err};
-use vec::{ImmutableVector, MutableVector, OwnedVector, Items, MutItems};
-use vec_ng;
-use vec_ng::Vec;
-
-static INITIAL_CAPACITY: uint = 32u; // 2^5
-
-struct Bucket<K,V> {
- hash: uint,
- key: K,
- value: V,
-}
-
-/// A hash map implementation which uses linear probing along with the SipHash
-/// hash function for internal state. This means that the order of all hash maps
-/// is randomized by keying each hash map randomly on creation.
-///
-/// It is required that the keys implement the `Eq` and `Hash` traits, although
-/// this can frequently be achieved by just implementing the `Eq` and
-/// `IterBytes` traits as `Hash` is automatically implemented for types that
-/// implement `IterBytes`.
-pub struct HashMap<K,V> {
- priv k0: u64,
- priv k1: u64,
- priv resize_at: uint,
- priv size: uint,
- priv buckets: Vec<Option<Bucket<K, V>>>
-}
-
-// We could rewrite FoundEntry to have type Option<&Bucket<K, V>>
-// which would be nifty
-enum SearchResult {
- FoundEntry(uint), FoundHole(uint), TableFull
-}
-
-#[inline]
-fn resize_at(capacity: uint) -> uint {
- (capacity * 3) / 4
-}
-
-impl<K:Hash + Eq,V> HashMap<K, V> {
- #[inline]
- fn to_bucket(&self, h: uint) -> uint {
- // A good hash function with entropy spread over all of the
- // bits is assumed. SipHash is more than good enough.
- h % self.buckets.len()
- }
-
- #[inline]
- fn next_bucket(&self, idx: uint, len_buckets: uint) -> uint {
- (idx + 1) % len_buckets
- }
-
- #[inline]
- fn bucket_sequence(&self, hash: uint, op: |uint| -> bool) -> bool {
- let start_idx = self.to_bucket(hash);
- let len_buckets = self.buckets.len();
- let mut idx = start_idx;
- loop {
- if !op(idx) { return false; }
- idx = self.next_bucket(idx, len_buckets);
- if idx == start_idx {
- return true;
- }
- }
- }
-
- #[inline]
- fn bucket_for_key(&self, k: &K) -> SearchResult {
- let hash = k.hash_keyed(self.k0, self.k1) as uint;
- self.bucket_for_key_with_hash(hash, k)
- }
-
- #[inline]
- fn bucket_for_key_equiv<Q:Hash + Equiv<K>>(&self, k: &Q)
- -> SearchResult {
- let hash = k.hash_keyed(self.k0, self.k1) as uint;
- self.bucket_for_key_with_hash_equiv(hash, k)
- }
-
- #[inline]
- fn bucket_for_key_with_hash(&self,
- hash: uint,
- k: &K)
- -> SearchResult {
- let mut ret = TableFull;
- self.bucket_sequence(hash, |i| {
- match self.buckets.as_slice()[i] {
- Some(ref bkt) if bkt.hash == hash && *k == bkt.key => {
- ret = FoundEntry(i); false
- },
- None => { ret = FoundHole(i); false }
- _ => true,
- }
- });
- ret
- }
-
- #[inline]
- fn bucket_for_key_with_hash_equiv<Q:Equiv<K>>(&self,
- hash: uint,
- k: &Q)
- -> SearchResult {
- let mut ret = TableFull;
- self.bucket_sequence(hash, |i| {
- match self.buckets.as_slice()[i] {
- Some(ref bkt) if bkt.hash == hash && k.equiv(&bkt.key) => {
- ret = FoundEntry(i); false
- },
- None => { ret = FoundHole(i); false }
- _ => true,
- }
- });
- ret
- }
-
- /// Expand the capacity of the array to the next power of two
- /// and re-insert each of the existing buckets.
- #[inline]
- fn expand(&mut self) {
- let new_capacity = self.buckets.len() * 2;
- self.resize(new_capacity);
- }
-
- /// Expands the capacity of the array and re-insert each of the
- /// existing buckets.
- fn resize(&mut self, new_capacity: uint) {
- self.resize_at = resize_at(new_capacity);
-
- let old_buckets = replace(&mut self.buckets,
- Vec::from_fn(new_capacity, |_| None));
-
- self.size = 0;
- for bucket in old_buckets.move_iter() {
- self.insert_opt_bucket(bucket);
- }
- }
-
- fn insert_opt_bucket(&mut self, bucket: Option<Bucket<K, V>>) {
- match bucket {
- Some(Bucket{hash: hash, key: key, value: value}) => {
- self.insert_internal(hash, key, value);
- }
- None => {}
- }
- }
-
- #[inline]
- fn value_for_bucket<'a>(&'a self, idx: uint) -> &'a V {
- match self.buckets.as_slice()[idx] {
- Some(ref bkt) => &bkt.value,
- None => fail!("HashMap::find: internal logic error"),
- }
- }
-
- #[inline]
- fn mut_value_for_bucket<'a>(&'a mut self, idx: uint) -> &'a mut V {
- match self.buckets.as_mut_slice()[idx] {
- Some(ref mut bkt) => &mut bkt.value,
- None => unreachable!()
- }
- }
-
- /// Inserts the key value pair into the buckets.
- /// Assumes that there will be a bucket.
- /// True if there was no previous entry with that key
- fn insert_internal(&mut self, hash: uint, k: K, v: V) -> Option<V> {
- match self.bucket_for_key_with_hash(hash, &k) {
- TableFull => { fail!("Internal logic error"); }
- FoundHole(idx) => {
- self.buckets.as_mut_slice()[idx] = Some(Bucket{hash: hash, key: k, value: v});
- self.size += 1;
- None
- }
- FoundEntry(idx) => {
- match self.buckets.as_mut_slice()[idx] {
- None => { fail!("insert_internal: Internal logic error") }
- Some(ref mut b) => {
- b.hash = hash;
- b.key = k;
- Some(replace(&mut b.value, v))
- }
- }
- }
- }
- }
-
- fn pop_internal(&mut self, hash: uint, k: &K) -> Option<V> {
- // Removing from an open-addressed hashtable
- // is, well, painful. The problem is that
- // the entry may lie on the probe path for other
- // entries, so removing it would make you think that
- // those probe paths are empty.
- //
- // To address this we basically have to keep walking,
- // re-inserting entries we find until we reach an empty
- // bucket. We know we will eventually reach one because
- // we insert one ourselves at the beginning (the removed
- // entry).
- //
- // I found this explanation elucidating:
- // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf
- let mut idx = match self.bucket_for_key_with_hash(hash, k) {
- TableFull | FoundHole(_) => return None,
- FoundEntry(idx) => idx
- };
-
- let len_buckets = self.buckets.len();
- let bucket = self.buckets.as_mut_slice()[idx].take();
-
- let value = bucket.map(|bucket| bucket.value);
-
- /* re-inserting buckets may cause changes in size, so remember
- what our new size is ahead of time before we start insertions */
- let size = self.size - 1;
- idx = self.next_bucket(idx, len_buckets);
- while self.buckets.as_slice()[idx].is_some() {
- let bucket = self.buckets.as_mut_slice()[idx].take();
- self.insert_opt_bucket(bucket);
- idx = self.next_bucket(idx, len_buckets);
- }
- self.size = size;
-
- value
- }
-}
-
-impl<K:Hash + Eq,V> Container for HashMap<K, V> {
- /// Return the number of elements in the map
- fn len(&self) -> uint { self.size }
-}
-
-impl<K:Hash + Eq,V> Mutable for HashMap<K, V> {
- /// Clear the map, removing all key-value pairs.
- fn clear(&mut self) {
- for bkt in self.buckets.as_mut_slice().mut_iter() {
- *bkt = None;
- }
- self.size = 0;
- }
-}
-
-impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> {
- /// Return a reference to the value corresponding to the key
- fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
- match self.bucket_for_key(k) {
- FoundEntry(idx) => Some(self.value_for_bucket(idx)),
- TableFull | FoundHole(_) => None,
- }
- }
-}
-
-impl<K:Hash + Eq,V> MutableMap<K, V> for HashMap<K, V> {
- /// Return a mutable reference to the value corresponding to the key
- fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
- let idx = match self.bucket_for_key(k) {
- FoundEntry(idx) => idx,
- TableFull | FoundHole(_) => return None
- };
- Some(self.mut_value_for_bucket(idx))
- }
-
- /// Insert a key-value pair from the map. If the key already had a value
- /// present in the map, that value is returned. Otherwise None is returned.
- fn swap(&mut self, k: K, v: V) -> Option<V> {
- // this could be faster.
-
- if self.size >= self.resize_at {
- // n.b.: We could also do this after searching, so
- // that we do not resize if this call to insert is
- // simply going to update a key in place. My sense
- // though is that it's worse to have to search through
- // buckets to find the right spot twice than to just
- // resize in this corner case.
- self.expand();
- }
-
- let hash = k.hash_keyed(self.k0, self.k1) as uint;
- self.insert_internal(hash, k, v)
- }
-
- /// Removes a key from the map, returning the value at the key if the key
- /// was previously in the map.
- fn pop(&mut self, k: &K) -> Option<V> {
- let hash = k.hash_keyed(self.k0, self.k1) as uint;
- self.pop_internal(hash, k)
- }
-}
-
-impl<K: Hash + Eq, V> HashMap<K, V> {
- /// Create an empty HashMap
- pub fn new() -> HashMap<K, V> {
- HashMap::with_capacity(INITIAL_CAPACITY)
- }
-
- /// Create an empty HashMap with space for at least `capacity`
- /// elements in the hash table.
- pub fn with_capacity(capacity: uint) -> HashMap<K, V> {
- let mut r = rand::task_rng();
- HashMap::with_capacity_and_keys(r.gen(), r.gen(), capacity)
- }
-
- /// Create an empty HashMap with space for at least `capacity`
- /// elements, using `k0` and `k1` as the keys.
- ///
- /// Warning: `k0` and `k1` are normally randomly generated, and
- /// are designed to allow HashMaps to be resistant to attacks that
- /// cause many collisions and very poor performance. Setting them
- /// manually using this function can expose a DoS attack vector.
- pub fn with_capacity_and_keys(k0: u64, k1: u64, capacity: uint) -> HashMap<K, V> {
- let cap = max(INITIAL_CAPACITY, capacity);
- HashMap {
- k0: k0, k1: k1,
- resize_at: resize_at(cap),
- size: 0,
- buckets: Vec::from_fn(cap, |_| None)
- }
- }
-
- /// Reserve space for at least `n` elements in the hash table.
- pub fn reserve(&mut self, n: uint) {
- if n > self.buckets.len() {
- let buckets = n * 4 / 3 + 1;
- self.resize(num::next_power_of_two(buckets));
- }
- }
-
- /// Modify and return the value corresponding to the key in the map, or
- /// insert and return a new value if it doesn't exist.
- ///
- /// This method allows for all insertion behaviours of a hashmap,
- /// see methods like `insert`, `find_or_insert` and
- /// `insert_or_update_with` for less general and more friendly
- /// variations of this.
- ///
- /// # Example
- ///
- /// ```rust
- /// use std::hashmap::HashMap;
- ///
- /// // map some strings to vectors of strings
- /// let mut map = HashMap::<~str, ~[~str]>::new();
- /// map.insert(~"a key", ~[~"value"]);
- /// map.insert(~"z key", ~[~"value"]);
- ///
- /// let new = ~[~"a key", ~"b key", ~"z key"];
- /// for k in new.move_iter() {
- /// map.mangle(k, ~"new value",
- /// // if the key doesn't exist in the map yet, add it in
- /// // the obvious way.
- /// |_k, v| ~[v],
- /// // if the key does exist either prepend or append this
- /// // new value based on the first letter of the key.
- /// |key, already, new| {
- /// if key.starts_with("z") {
- /// already.unshift(new);
- /// } else {
- /// already.push(new);
- /// }
- /// });
- /// }
- ///
- /// for (k, v) in map.iter() {
- /// println!("{} -> {:?}", *k, *v);
- /// }
- /// ```
- pub fn mangle<'a,
- A>(
- &'a mut self,
- k: K,
- a: A,
- not_found: |&K, A| -> V,
- found: |&K, &mut V, A|)
- -> &'a mut V {
- if self.size >= self.resize_at {
- // n.b.: We could also do this after searching, so
- // that we do not resize if this call to insert is
- // simply going to update a key in place. My sense
- // though is that it's worse to have to search through
- // buckets to find the right spot twice than to just
- // resize in this corner case.
- self.expand();
- }
-
- let hash = k.hash_keyed(self.k0, self.k1) as uint;
- let idx = match self.bucket_for_key_with_hash(hash, &k) {
- TableFull => fail!("Internal logic error"),
- FoundEntry(idx) => { found(&k, self.mut_value_for_bucket(idx), a); idx }
- FoundHole(idx) => {
- let v = not_found(&k, a);
- self.buckets.as_mut_slice()[idx] = Some(Bucket{hash: hash, key: k, value: v});
- self.size += 1;
- idx
- }
- };
-
- self.mut_value_for_bucket(idx)
- }
-
- /// Return the value corresponding to the key in the map, or insert
- /// and return the value if it doesn't exist.
- pub fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a mut V {
- self.mangle(k, v, |_k, a| a, |_k,_v,_a| ())
- }
-
- /// Return the value corresponding to the key in the map, or create,
- /// insert, and return a new value if it doesn't exist.
- pub fn find_or_insert_with<'a>(&'a mut self, k: K, f: |&K| -> V)
- -> &'a mut V {
- self.mangle(k, (), |k,_a| f(k), |_k,_v,_a| ())
- }
-
- /// Insert a key-value pair into the map if the key is not already present.
- /// Otherwise, modify the existing value for the key.
- /// Returns the new or modified value for the key.
- pub fn insert_or_update_with<'a>(
- &'a mut self,
- k: K,
- v: V,
- f: |&K, &mut V|)
- -> &'a mut V {
- self.mangle(k, v, |_k,a| a, |k,v,_a| f(k,v))
- }
-
- /// Retrieves a value for the given key, failing if the key is not
- /// present.
- pub fn get<'a>(&'a self, k: &K) -> &'a V {
- match self.find(k) {
- Some(v) => v,
- None => fail!("No entry found for key: {:?}", k),
- }
- }
-
- /// Retrieves a (mutable) value for the given key, failing if the key
- /// is not present.
- pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V {
- match self.find_mut(k) {
- Some(v) => v,
- None => fail!("No entry found for key: {:?}", k),
- }
- }
-
- /// Return true if the map contains a value for the specified key,
- /// using equivalence
- pub fn contains_key_equiv<Q:Hash + Equiv<K>>(&self, key: &Q) -> bool {
- match self.bucket_for_key_equiv(key) {
- FoundEntry(_) => {true}
- TableFull | FoundHole(_) => {false}
- }
- }
-
- /// Return the value corresponding to the key in the map, using
- /// equivalence
- pub fn find_equiv<'a, Q:Hash + Equiv<K>>(&'a self, k: &Q)
- -> Option<&'a V> {
- match self.bucket_for_key_equiv(k) {
- FoundEntry(idx) => Some(self.value_for_bucket(idx)),
- TableFull | FoundHole(_) => None,
- }
- }
-
- /// An iterator visiting all keys in arbitrary order.
- /// Iterator element type is &'a K.
- pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
- self.iter().map(|(k, _v)| k)
- }
-
- /// An iterator visiting all values in arbitrary order.
- /// Iterator element type is &'a V.
- pub fn values<'a>(&'a self) -> Values<'a, K, V> {
- self.iter().map(|(_k, v)| v)
- }
-
- /// An iterator visiting all key-value pairs in arbitrary order.
- /// Iterator element type is (&'a K, &'a V).
- pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
- Entries { iter: self.buckets.as_slice().iter() }
- }
-
- /// An iterator visiting all key-value pairs in arbitrary order,
- /// with mutable references to the values.
- /// Iterator element type is (&'a K, &'a mut V).
- pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> {
- MutEntries { iter: self.buckets.as_mut_slice().mut_iter() }
- }
-
- /// Creates a consuming iterator, that is, one that moves each key-value
- /// pair out of the map in arbitrary order. The map cannot be used after
- /// calling this.
- pub fn move_iter(self) -> MoveEntries<K, V> {
- MoveEntries {iter: self.buckets.move_iter()}
- }
-}
-
-impl<K: Hash + Eq, V: Clone> HashMap<K, V> {
- /// Like `find`, but returns a copy of the value.
- pub fn find_copy(&self, k: &K) -> Option<V> {
- self.find(k).map(|v| (*v).clone())
- }
-
- /// Like `get`, but returns a copy of the value.
- pub fn get_copy(&self, k: &K) -> V {
- (*self.get(k)).clone()
- }
-}
-
-impl<K:Hash + Eq,V:Eq> Eq for HashMap<K, V> {
- fn eq(&self, other: &HashMap<K, V>) -> bool {
- if self.len() != other.len() { return false; }
-
- self.iter().all(|(key, value)| {
- match other.find(key) {
- None => false,
- Some(v) => value == v
- }
- })
- }
-
- fn ne(&self, other: &HashMap<K, V>) -> bool { !self.eq(other) }
-}
-
-impl<K:Hash + Eq + Clone,V:Clone> Clone for HashMap<K,V> {
- fn clone(&self) -> HashMap<K,V> {
- let mut new_map = HashMap::with_capacity(self.len());
- for (key, value) in self.iter() {
- new_map.insert((*key).clone(), (*value).clone());
- }
- new_map
- }
-}
-
-impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for HashMap<A, B> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f.buf, r"\{"))
- let mut first = true;
- for (key, value) in self.iter() {
- if first {
- first = false;
- } else {
- try!(write!(f.buf, ", "));
- }
- try!(write!(f.buf, "{}: {}", *key, *value));
- }
- write!(f.buf, r"\}")
- }
-}
-
-/// HashMap iterator
-#[deriving(Clone)]
-pub struct Entries<'a, K, V> {
- priv iter: Items<'a, Option<Bucket<K, V>>>,
-}
-
-/// HashMap mutable values iterator
-pub struct MutEntries<'a, K, V> {
- priv iter: MutItems<'a, Option<Bucket<K, V>>>,
-}
-
-/// HashMap move iterator
-pub struct MoveEntries<K, V> {
- priv iter: vec_ng::MoveItems<Option<Bucket<K, V>>>,
-}
-
-/// HashMap keys iterator
-pub type Keys<'a, K, V> =
- iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
-
-/// HashMap values iterator
-pub type Values<'a, K, V> =
- iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
-
-/// HashSet iterator
-#[deriving(Clone)]
-pub struct SetItems<'a, K> {
- priv iter: Items<'a, Option<Bucket<K, ()>>>,
-}
-
-/// HashSet move iterator
-pub struct SetMoveItems<K> {
- priv iter: vec_ng::MoveItems<Option<Bucket<K, ()>>>,
-}
-
-impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
- #[inline]
- fn next(&mut self) -> Option<(&'a K, &'a V)> {
- for elt in self.iter {
- match elt {
- &Some(ref bucket) => return Some((&bucket.key, &bucket.value)),
- &None => {},
- }
- }
- None
- }
-}
-
-impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
- #[inline]
- fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
- for elt in self.iter {
- match elt {
- &Some(ref mut bucket) => return Some((&bucket.key, &mut bucket.value)),
- &None => {},
- }
- }
- None
- }
-}
-
-impl<K, V> Iterator<(K, V)> for MoveEntries<K, V> {
- #[inline]
- fn next(&mut self) -> Option<(K, V)> {
- for elt in self.iter {
- match elt {
- Some(Bucket {key, value, ..}) => return Some((key, value)),
- None => {},
- }
- }
- None
- }
-}
-
-impl<'a, K> Iterator<&'a K> for SetItems<'a, K> {
- #[inline]
- fn next(&mut self) -> Option<&'a K> {
- for elt in self.iter {
- match elt {
- &Some(ref bucket) => return Some(&bucket.key),
- &None => {},
- }
- }
- None
- }
-}
-
-impl<K> Iterator<K> for SetMoveItems<K> {
- #[inline]
- fn next(&mut self) -> Option<K> {
- for elt in self.iter {
- match elt {
- Some(bucket) => return Some(bucket.key),
- None => {},
- }
- }
- None
- }
-}
-
-impl<K: Eq + Hash, V> FromIterator<(K, V)> for HashMap<K, V> {
- fn from_iterator<T: Iterator<(K, V)>>(iter: &mut T) -> HashMap<K, V> {
- let (lower, _) = iter.size_hint();
- let mut map = HashMap::with_capacity(lower);
- map.extend(iter);
- map
- }
-}
-
-impl<K: Eq + Hash, V> Extendable<(K, V)> for HashMap<K, V> {
- fn extend<T: Iterator<(K, V)>>(&mut self, iter: &mut T) {
- for (k, v) in *iter {
- self.insert(k, v);
- }
- }
-}
-
-impl<K: Eq + Hash, V> Default for HashMap<K, V> {
- fn default() -> HashMap<K, V> { HashMap::new() }
-}
-
-/// An implementation of a hash set using the underlying representation of a
-/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
-/// requires that the elements implement the `Eq` and `Hash` traits.
-pub struct HashSet<T> {
- priv map: HashMap<T, ()>
-}
-
-impl<T:Hash + Eq> Eq for HashSet<T> {
- fn eq(&self, other: &HashSet<T>) -> bool { self.map == other.map }
- fn ne(&self, other: &HashSet<T>) -> bool { self.map != other.map }
-}
-
-impl<T:Hash + Eq> Container for HashSet<T> {
- /// Return the number of elements in the set
- fn len(&self) -> uint { self.map.len() }
-}
-
-impl<T:Hash + Eq> Mutable for HashSet<T> {
- /// Clear the set, removing all values.
- fn clear(&mut self) { self.map.clear() }
-}
-
-impl<T:Hash + Eq> Set<T> for HashSet<T> {
- /// Return true if the set contains a value
- fn contains(&self, value: &T) -> bool { self.map.contains_key(value) }
-
- /// Return true if the set has no elements in common with `other`.
- /// This is equivalent to checking for an empty intersection.
- fn is_disjoint(&self, other: &HashSet<T>) -> bool {
- self.iter().all(|v| !other.contains(v))
- }
-
- /// Return true if the set is a subset of another
- fn is_subset(&self, other: &HashSet<T>) -> bool {
- self.iter().all(|v| other.contains(v))
- }
-
- /// Return true if the set is a superset of another
- fn is_superset(&self, other: &HashSet<T>) -> bool {
- other.is_subset(self)
- }
-}
-
-impl<T:Hash + Eq> MutableSet<T> for HashSet<T> {
- /// Add a value to the set. Return true if the value was not already
- /// present in the set.
- fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
-
- /// Remove a value from the set. Return true if the value was
- /// present in the set.
- fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
-}
-
-impl<T:Hash + Eq> HashSet<T> {
- /// Create an empty HashSet
- pub fn new() -> HashSet<T> {
- HashSet::with_capacity(INITIAL_CAPACITY)
- }
-
- /// Create an empty HashSet with space for at least `n` elements in
- /// the hash table.
- pub fn with_capacity(capacity: uint) -> HashSet<T> {
- HashSet { map: HashMap::with_capacity(capacity) }
- }
-
- /// Create an empty HashSet with space for at least `capacity`
- /// elements in the hash table, using `k0` and `k1` as the keys.
- ///
- /// Warning: `k0` and `k1` are normally randomly generated, and
- /// are designed to allow HashSets to be resistant to attacks that
- /// cause many collisions and very poor performance. Setting them
- /// manually using this function can expose a DoS attack vector.
- pub fn with_capacity_and_keys(k0: u64, k1: u64, capacity: uint) -> HashSet<T> {
- HashSet { map: HashMap::with_capacity_and_keys(k0, k1, capacity) }
- }
-
- /// Reserve space for at least `n` elements in the hash table.
- pub fn reserve(&mut self, n: uint) {
- self.map.reserve(n)
- }
-
- /// Returns true if the hash set contains a value equivalent to the
- /// given query value.
- pub fn contains_equiv<Q:Hash + Equiv<T>>(&self, value: &Q) -> bool {
- self.map.contains_key_equiv(value)
- }
-
- /// An iterator visiting all elements in arbitrary order.
- /// Iterator element type is &'a T.
- pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
- SetItems { iter: self.map.buckets.as_slice().iter() }
- }
-
- /// Creates a consuming iterator, that is, one that moves each value out
- /// of the set in arbitrary order. The set cannot be used after calling
- /// this.
- pub fn move_iter(self) -> SetMoveItems<T> {
- SetMoveItems {iter: self.map.buckets.move_iter()}
- }
-
- /// Visit the values representing the difference
- pub fn difference<'a>(&'a self, other: &'a HashSet<T>) -> SetAlgebraItems<'a, T> {
- Repeat::new(other)
- .zip(self.iter())
- .filter_map(|(other, elt)| {
- if !other.contains(elt) { Some(elt) } else { None }
- })
- }
-
- /// Visit the values representing the symmetric difference
- pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T>)
- -> Chain<SetAlgebraItems<'a, T>, SetAlgebraItems<'a, T>> {
- self.difference(other).chain(other.difference(self))
- }
-
- /// Visit the values representing the intersection
- pub fn intersection<'a>(&'a self, other: &'a HashSet<T>)
- -> SetAlgebraItems<'a, T> {
- Repeat::new(other)
- .zip(self.iter())
- .filter_map(|(other, elt)| {
- if other.contains(elt) { Some(elt) } else { None }
- })
- }
-
- /// Visit the values representing the union
- pub fn union<'a>(&'a self, other: &'a HashSet<T>)
- -> Chain<SetItems<'a, T>, SetAlgebraItems<'a, T>> {
- self.iter().chain(other.difference(self))
- }
-
-}
-
-impl<T:Hash + Eq + Clone> Clone for HashSet<T> {
- fn clone(&self) -> HashSet<T> {
- HashSet {
- map: self.map.clone()
- }
- }
-}
-
-impl<A: fmt::Show + Hash + Eq> fmt::Show for HashSet<A> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f.buf, r"\{"))
- let mut first = true;
- for x in self.iter() {
- if first {
- first = false;
- } else {
- try!(write!(f.buf, ", "));
- }
- try!(write!(f.buf, "{}", *x));
- }
- write!(f.buf, r"\}")
- }
-}
-
-impl<K: Eq + Hash> FromIterator<K> for HashSet<K> {
- fn from_iterator<T: Iterator<K>>(iter: &mut T) -> HashSet<K> {
- let (lower, _) = iter.size_hint();
- let mut set = HashSet::with_capacity(lower);
- set.extend(iter);
- set
- }
-}
-
-impl<K: Eq + Hash> Extendable<K> for HashSet<K> {
- fn extend<T: Iterator<K>>(&mut self, iter: &mut T) {
- for k in *iter {
- self.insert(k);
- }
- }
-}
-
-impl<K: Eq + Hash> Default for HashSet<K> {
- fn default() -> HashSet<K> { HashSet::new() }
-}
-
-// `Repeat` is used to feed the filter closure an explicit capture
-// of a reference to the other set
-/// Set operations iterator
-pub type SetAlgebraItems<'a, T> =
- FilterMap<'static,(&'a HashSet<T>, &'a T), &'a T,
- Zip<Repeat<&'a HashSet<T>>,SetItems<'a,T>>>;
-
-
-#[cfg(test)]
-mod test_map {
- use prelude::*;
- use super::*;
- use fmt;
-
- #[test]
- fn test_create_capacity_zero() {
- let mut m = HashMap::with_capacity(0);
- assert!(m.insert(1, 1));
- }
-
- #[test]
- fn test_insert() {
- let mut m = HashMap::new();
- assert!(m.insert(1, 2));
- assert!(m.insert(2, 4));
- assert_eq!(*m.get(&1), 2);
- assert_eq!(*m.get(&2), 4);
- }
-
- #[test]
- fn test_find_mut() {
- let mut m = HashMap::new();
- assert!(m.insert(1, 12));
- assert!(m.insert(2, 8));
- assert!(m.insert(5, 14));
- let new = 100;
- match m.find_mut(&5) {
- None => fail!(), Some(x) => *x = new
- }
- assert_eq!(m.find(&5), Some(&new));
- }
-
- #[test]
- fn test_insert_overwrite() {
- let mut m = HashMap::new();
- assert!(m.insert(1, 2));
- assert_eq!(*m.get(&1), 2);
- assert!(!m.insert(1, 3));
- assert_eq!(*m.get(&1), 3);
- }
-
- #[test]
- fn test_insert_conflicts() {
- let mut m = HashMap::with_capacity(4);
- assert!(m.insert(1, 2));
- assert!(m.insert(5, 3));
- assert!(m.insert(9, 4));
- assert_eq!(*m.get(&9), 4);
- assert_eq!(*m.get(&5), 3);
- assert_eq!(*m.get(&1), 2);
- }
-
- #[test]
- fn test_conflict_remove() {
- let mut m = HashMap::with_capacity(4);
- assert!(m.insert(1, 2));
- assert!(m.insert(5, 3));
- assert!(m.insert(9, 4));
- assert!(m.remove(&1));
- assert_eq!(*m.get(&9), 4);
- assert_eq!(*m.get(&5), 3);
- }
-
- #[test]
- fn test_is_empty() {
- let mut m = HashMap::with_capacity(4);
- assert!(m.insert(1, 2));
- assert!(!m.is_empty());
- assert!(m.remove(&1));
- assert!(m.is_empty());
- }
-
- #[test]
- fn test_pop() {
- let mut m = HashMap::new();
- m.insert(1, 2);
- assert_eq!(m.pop(&1), Some(2));
- assert_eq!(m.pop(&1), None);
- }
-
- #[test]
- fn test_swap() {
- let mut m = HashMap::new();
- assert_eq!(m.swap(1, 2), None);
- assert_eq!(m.swap(1, 3), Some(2));
- assert_eq!(m.swap(1, 4), Some(3));
- }
-
- #[test]
- fn test_find_or_insert() {
- let mut m: HashMap<int,int> = HashMap::new();
- assert_eq!(*m.find_or_insert(1, 2), 2);
- assert_eq!(*m.find_or_insert(1, 3), 2);
- }
-
- #[test]
- fn test_find_or_insert_with() {
- let mut m: HashMap<int,int> = HashMap::new();
- assert_eq!(*m.find_or_insert_with(1, |_| 2), 2);
- assert_eq!(*m.find_or_insert_with(1, |_| 3), 2);
- }
-
- #[test]
- fn test_insert_or_update_with() {
- let mut m: HashMap<int,int> = HashMap::new();
- assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 2);
- assert_eq!(*m.insert_or_update_with(1, 2, |_,x| *x+=1), 3);
- }
-
- #[test]
- fn test_move_iter() {
- let hm = {
- let mut hm = HashMap::new();
-
- hm.insert('a', 1);
- hm.insert('b', 2);
-
- hm
- };
-
- let v = hm.move_iter().collect::<~[(char, int)]>();
- assert!([('a', 1), ('b', 2)] == v || [('b', 2), ('a', 1)] == v);
- }
-
- #[test]
- fn test_iterate() {
- let mut m = HashMap::with_capacity(4);
- for i in range(0u, 32) {
- assert!(m.insert(i, i*2));
- }
- let mut observed = 0;
- for (k, v) in m.iter() {
- assert_eq!(*v, *k * 2);
- observed |= (1 << *k);
- }
- assert_eq!(observed, 0xFFFF_FFFF);
- }
-
- #[test]
- fn test_keys() {
- let vec = ~[(1, 'a'), (2, 'b'), (3, 'c')];
- let map = vec.move_iter().collect::<HashMap<int, char>>();
- let keys = map.keys().map(|&k| k).collect::<~[int]>();
- assert_eq!(keys.len(), 3);
- assert!(keys.contains(&1));
- assert!(keys.contains(&2));
- assert!(keys.contains(&3));
- }
-
- #[test]
- fn test_values() {
- let vec = ~[(1, 'a'), (2, 'b'), (3, 'c')];
- let map = vec.move_iter().collect::<HashMap<int, char>>();
- let values = map.values().map(|&v| v).collect::<~[char]>();
- assert_eq!(values.len(), 3);
- assert!(values.contains(&'a'));
- assert!(values.contains(&'b'));
- assert!(values.contains(&'c'));
- }
-
- #[test]
- fn test_find() {
- let mut m = HashMap::new();
- assert!(m.find(&1).is_none());
- m.insert(1, 2);
- match m.find(&1) {
- None => fail!(),
- Some(v) => assert!(*v == 2)
- }
- }
-
- #[test]
- fn test_eq() {
- let mut m1 = HashMap::new();
- m1.insert(1, 2);
- m1.insert(2, 3);
- m1.insert(3, 4);
-
- let mut m2 = HashMap::new();
- m2.insert(1, 2);
- m2.insert(2, 3);
-
- assert!(m1 != m2);
-
- m2.insert(3, 4);
-
- assert_eq!(m1, m2);
- }
-
- #[test]
- fn test_expand() {
- let mut m = HashMap::new();
-
- assert_eq!(m.len(), 0);
- assert!(m.is_empty());
-
- let mut i = 0u;
- let old_resize_at = m.resize_at;
- while old_resize_at == m.resize_at {
- m.insert(i, i);
- i += 1;
- }
-
- assert_eq!(m.len(), i);
- assert!(!m.is_empty());
- }
-
- #[test]
- fn test_find_equiv() {
- let mut m = HashMap::new();
-
- let (foo, bar, baz) = (1,2,3);
- m.insert(~"foo", foo);
- m.insert(~"bar", bar);
- m.insert(~"baz", baz);
-
-
- assert_eq!(m.find_equiv(&("foo")), Some(&foo));
- assert_eq!(m.find_equiv(&("bar")), Some(&bar));
- assert_eq!(m.find_equiv(&("baz")), Some(&baz));
-
- assert_eq!(m.find_equiv(&("qux")), None);
- }
-
- #[test]
- fn test_from_iter() {
- let xs = ~[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
- let map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
-
- for &(k, v) in xs.iter() {
- assert_eq!(map.find(&k), Some(&v));
- }
- }
-
- struct ShowableStruct {
- value: int,
- }
-
- impl fmt::Show for ShowableStruct {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f.buf, r"s{}", self.value)
- }
- }
-
- #[test]
- fn test_show() {
- let mut table: HashMap<int, ShowableStruct> = HashMap::new();
- let empty: HashMap<int, ShowableStruct> = HashMap::new();
-
- table.insert(3, ShowableStruct { value: 4 });
- table.insert(1, ShowableStruct { value: 2 });
-
- let table_str = format!("{}", table);
-
- assert!(table_str == ~"{1: s2, 3: s4}" || table_str == ~"{3: s4, 1: s2}");
- assert_eq!(format!("{}", empty), ~"{}");
- }
-}
-
-#[cfg(test)]
-mod test_set {
- use super::*;
- use prelude::*;
- use container::Container;
- use vec::ImmutableEqVector;
-
- #[test]
- fn test_disjoint() {
- let mut xs = HashSet::new();
- let mut ys = HashSet::new();
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(xs.insert(5));
- assert!(ys.insert(11));
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(xs.insert(7));
- assert!(xs.insert(19));
- assert!(xs.insert(4));
- assert!(ys.insert(2));
- assert!(ys.insert(-11));
- assert!(xs.is_disjoint(&ys));
- assert!(ys.is_disjoint(&xs));
- assert!(ys.insert(7));
- assert!(!xs.is_disjoint(&ys));
- assert!(!ys.is_disjoint(&xs));
- }
-
- #[test]
- fn test_subset_and_superset() {
- let mut a = HashSet::new();
- assert!(a.insert(0));
- assert!(a.insert(5));
- assert!(a.insert(11));
- assert!(a.insert(7));
-
- let mut b = HashSet::new();
- assert!(b.insert(0));
- assert!(b.insert(7));
- assert!(b.insert(19));
- assert!(b.insert(250));
- assert!(b.insert(11));
- assert!(b.insert(200));
-
- assert!(!a.is_subset(&b));
- assert!(!a.is_superset(&b));
- assert!(!b.is_subset(&a));
- assert!(!b.is_superset(&a));
-
- assert!(b.insert(5));
-
- assert!(a.is_subset(&b));
- assert!(!a.is_superset(&b));
- assert!(!b.is_subset(&a));
- assert!(b.is_superset(&a));
- }
-
- #[test]
- fn test_iterate() {
- let mut a = HashSet::new();
- for i in range(0u, 32) {
- assert!(a.insert(i));
- }
- let mut observed = 0;
- for k in a.iter() {
- observed |= (1 << *k);
- }
- assert_eq!(observed, 0xFFFF_FFFF);
- }
-
- #[test]
- fn test_intersection() {
- let mut a = HashSet::new();
- let mut b = HashSet::new();
-
- assert!(a.insert(11));
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(77));
- assert!(a.insert(103));
- assert!(a.insert(5));
- assert!(a.insert(-5));
-
- assert!(b.insert(2));
- assert!(b.insert(11));
- assert!(b.insert(77));
- assert!(b.insert(-9));
- assert!(b.insert(-42));
- assert!(b.insert(5));
- assert!(b.insert(3));
-
- let mut i = 0;
- let expected = [3, 5, 11, 77];
- for x in a.intersection(&b) {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_difference() {
- let mut a = HashSet::new();
- let mut b = HashSet::new();
-
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
-
- assert!(b.insert(3));
- assert!(b.insert(9));
-
- let mut i = 0;
- let expected = [1, 5, 11];
- for x in a.difference(&b) {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_symmetric_difference() {
- let mut a = HashSet::new();
- let mut b = HashSet::new();
-
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
-
- assert!(b.insert(-2));
- assert!(b.insert(3));
- assert!(b.insert(9));
- assert!(b.insert(14));
- assert!(b.insert(22));
-
- let mut i = 0;
- let expected = [-2, 1, 5, 11, 14, 22];
- for x in a.symmetric_difference(&b) {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_union() {
- let mut a = HashSet::new();
- let mut b = HashSet::new();
-
- assert!(a.insert(1));
- assert!(a.insert(3));
- assert!(a.insert(5));
- assert!(a.insert(9));
- assert!(a.insert(11));
- assert!(a.insert(16));
- assert!(a.insert(19));
- assert!(a.insert(24));
-
- assert!(b.insert(-2));
- assert!(b.insert(1));
- assert!(b.insert(5));
- assert!(b.insert(9));
- assert!(b.insert(13));
- assert!(b.insert(19));
-
- let mut i = 0;
- let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
- for x in a.union(&b) {
- assert!(expected.contains(x));
- i += 1
- }
- assert_eq!(i, expected.len());
- }
-
- #[test]
- fn test_from_iter() {
- let xs = ~[1, 2, 3, 4, 5, 6, 7, 8, 9];
-
- let set: HashSet<int> = xs.iter().map(|&x| x).collect();
-
- for x in xs.iter() {
- assert!(set.contains(x));
- }
- }
-
- #[test]
- fn test_move_iter() {
- let hs = {
- let mut hs = HashSet::new();
-
- hs.insert('a');
- hs.insert('b');
-
- hs
- };
-
- let v = hs.move_iter().collect::<~[char]>();
- assert!(['a', 'b'] == v || ['b', 'a'] == v);
- }
-
- #[test]
- fn test_eq() {
- let mut s1 = HashSet::new();
- s1.insert(1);
- s1.insert(2);
- s1.insert(3);
-
- let mut s2 = HashSet::new();
- s2.insert(1);
- s2.insert(2);
-
- assert!(s1 != s2);
-
- s2.insert(3);
-
- assert_eq!(s1, s2);
- }
-
- #[test]
- fn test_show() {
- let mut set: HashSet<int> = HashSet::new();
- let empty: HashSet<int> = HashSet::new();
-
- set.insert(1);
- set.insert(2);
-
- let set_str = format!("{}", set);
-
- assert!(set_str == ~"{1, 2}" || set_str == ~"{2, 1}");
- assert_eq!(format!("{}", empty), ~"{}");
- }
-}
*/
use clone::Clone;
-use result::{Ok, Err};
use comm::{Port, Chan};
-use container::{Map, MutableMap};
-use hashmap;
use io;
+use iter::Iterator;
+use mem::drop;
+use option::{Some, None};
+use result::{Ok, Err};
use rt::rtio::{IoFactory, LocalIo, RtioSignal};
+use vec::{ImmutableVector, OwnedVector};
#[repr(int)]
#[deriving(Eq, IterBytes)]
/// ```
pub struct Listener {
/// A map from signums to handles to keep the handles in memory
- priv handles: hashmap::HashMap<Signum, ~RtioSignal>,
+ priv handles: ~[(Signum, ~RtioSignal)],
/// chan is where all the handles send signums, which are received by
/// the clients from port.
priv chan: Chan<Signum>,
Listener {
chan: chan,
port: port,
- handles: hashmap::HashMap::new(),
+ handles: ~[],
}
}
/// If this function fails to register a signal handler, then an error will
/// be returned.
pub fn register(&mut self, signum: Signum) -> io::IoResult<()> {
- if self.handles.contains_key(&signum) {
+ if self.handles.iter().any(|&(sig, _)| sig == signum) {
return Ok(()); // self is already listening to signum, so succeed
}
match LocalIo::maybe_raise(|io| {
io.signal(signum, self.chan.clone())
}) {
Ok(handle) => {
- self.handles.insert(signum, handle);
+ self.handles.push((signum, handle));
Ok(())
}
Err(e) => Err(e)
/// notification about the signal. If the signal has already been received,
/// it may still be returned by `recv`.
pub fn unregister(&mut self, signum: Signum) {
- self.handles.pop(&signum);
+ match self.handles.iter().position(|&(i, _)| i == signum) {
+ Some(i) => drop(self.handles.remove(i)),
+ None => {}
+ }
}
}
//! # The Rust standard library
//!
//! The Rust standard library is a group of interrelated modules defining
-//! the core language traits, operations on built-in data types, collections,
+//! the core language traits, operations on built-in data types,
//! platform abstractions, the task scheduler, runtime support for language
//! features and other common functionality.
//!
// When testing libstd, bring in libuv as the I/O backend so tests can print
// things and all of the std::io tests have an I/O interface to run on top
// of
-#[cfg(test)] extern crate rustuv = "rustuv";
-#[cfg(test)] extern crate native = "native";
-#[cfg(test)] extern crate green = "green";
+#[cfg(test)] extern crate rustuv;
+#[cfg(test)] extern crate native;
+#[cfg(test)] extern crate green;
// Make extra accessible for benchmarking
#[cfg(test)] extern crate extra = "extra";
pub mod option;
pub mod result;
-pub mod hashmap;
pub mod cell;
-pub mod trie;
/* Tasks and communication */
info // turns on all info logging
hello=debug // turns on debug logging for 'hello'
hello=3 // turns on info logging for 'hello'
-hello,std::hashmap // turns on hello, and std's hashmap logging
+hello,std::option // turns on hello, and std's option logging
error,hello=warn // turn on global error logging and also warn for hello
```
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use cmp::TotalOrd;
use container::MutableSet;
-use hashmap::HashSet;
use iter::Iterator;
use option::{Some, None, Option};
use ptr::RawPtr;
-use vec::ImmutableVector;
use rt::rtio::EventLoop;
+use vec::{ImmutableVector, OwnedVector};
// Need to tell the linker on OS X to not barf on undefined symbols
// and instead look them up at runtime, which we need to resolve
fn do_iter_crate_map<'a>(
crate_map: &'a CrateMap<'a>,
f: |&ModEntry|,
- visited: &mut HashSet<*CrateMap<'a>>) {
- if visited.insert(crate_map as *CrateMap) {
- match version(crate_map) {
- 2 => {
- let (entries, children) = (crate_map.entries, crate_map.children);
- for entry in entries.iter() {
- f(entry);
- }
- for child in children.iter() {
- do_iter_crate_map(*child, |x| f(x), visited);
- }
- },
- _ => fail!("invalid crate map version")
- }
+ visited: &mut ~[*CrateMap<'a>]) {
+ let raw = crate_map as *CrateMap<'a>;
+ if visited.bsearch(|a| (*a as uint).cmp(&(raw as uint))).is_some() {
+ return
+ }
+ match visited.iter().position(|i| *i as uint > raw as uint) {
+ Some(i) => visited.insert(i, raw),
+ None => visited.push(raw),
+ }
+
+ match version(crate_map) {
+ 2 => {
+ let (entries, children) = (crate_map.entries, crate_map.children);
+ for entry in entries.iter() {
+ f(entry);
+ }
+ for child in children.iter() {
+ do_iter_crate_map(*child, |x| f(x), visited);
+ }
+ },
+ _ => fail!("invalid crate map version")
}
}
/// Iterates recursively over `crate_map` and all child crate maps
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: |&ModEntry|) {
- // FIXME: use random numbers as keys from the OS-level RNG when there is a nice
- // way to do this
- let mut v: HashSet<*CrateMap<'a>> = HashSet::with_capacity_and_keys(0, 0, 32);
+ let mut v = ~[];
do_iter_crate_map(crate_map, f, &mut v);
}
use option::{Some, None};
use str::OwnedStr;
-use hashmap::HashMap;
-use hashmap::HashSet;
-use hash_old::Hash;
use iter::Iterator;
-use cmp::Eq;
use vec::ImmutableVector;
/// A generic trait for converting a value to a string
fn to_str(&self) -> ~str { ~"()" }
}
-impl<A:ToStr+Hash+Eq, B:ToStr> ToStr for HashMap<A, B> {
- #[inline]
- fn to_str(&self) -> ~str {
- let mut acc = ~"{";
- let mut first = true;
- for (key, value) in self.iter() {
- if first {
- first = false;
- }
- else {
- acc.push_str(", ");
- }
- acc.push_str(key.to_str());
- acc.push_str(": ");
- acc.push_str(value.to_str());
- }
- acc.push_char('}');
- acc
- }
-}
-
-impl<A:ToStr+Hash+Eq> ToStr for HashSet<A> {
- #[inline]
- fn to_str(&self) -> ~str {
- let mut acc = ~"{";
- let mut first = true;
- for element in self.iter() {
- if first {
- first = false;
- }
- else {
- acc.push_str(", ");
- }
- acc.push_str(element.to_str());
- }
- acc.push_char('}');
- acc
- }
-}
-
impl<'a,A:ToStr> ToStr for &'a [A] {
#[inline]
fn to_str(&self) -> ~str {
#[cfg(test)]
mod tests {
- use hashmap::HashMap;
- use hashmap::HashSet;
- use container::{MutableSet, MutableMap};
use super::*;
#[test]
assert!((~[~[], ~[1], ~[1, 1]]).to_str() ==
~"[[], [1], [1, 1]]");
}
-
- struct StructWithToStrWithoutEqOrHash {
- value: int
- }
-
- impl ToStr for StructWithToStrWithoutEqOrHash {
- fn to_str(&self) -> ~str {
- format!("s{}", self.value)
- }
- }
-
- #[test]
- fn test_hashmap() {
- let mut table: HashMap<int, StructWithToStrWithoutEqOrHash> = HashMap::new();
- let empty: HashMap<int, StructWithToStrWithoutEqOrHash> = HashMap::new();
-
- table.insert(3, StructWithToStrWithoutEqOrHash { value: 4 });
- table.insert(1, StructWithToStrWithoutEqOrHash { value: 2 });
-
- let table_str = table.to_str();
-
- assert!(table_str == ~"{1: s2, 3: s4}" || table_str == ~"{3: s4, 1: s2}");
- assert_eq!(empty.to_str(), ~"{}");
- }
-
- #[test]
- fn test_hashset() {
- let mut set: HashSet<int> = HashSet::new();
- let empty_set: HashSet<int> = HashSet::new();
-
- set.insert(1);
- set.insert(2);
-
- let set_str = set.to_str();
-
- assert!(set_str == ~"{1, 2}" || set_str == ~"{2, 1}");
- assert_eq!(empty_set.to_str(), ~"{}");
- }
}
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Ordered containers with integer keys, implemented as radix tries (`TrieSet` and `TrieMap` types)
-
-use option::{None, Option, Some};
-use container::{Container, Map, Mutable, MutableMap};
-use iter::{Extendable, FromIterator, Iterator};
-use mem;
-use uint;
-use mem::init;
-use vec;
-use ptr::RawPtr;
-use vec::{ImmutableVector, Items, MutableVector, MutItems, OwnedVector};
-
-// FIXME: #5244: need to manually update the TrieNode constructor
-static SHIFT: uint = 4;
-static SIZE: uint = 1 << SHIFT;
-static MASK: uint = SIZE - 1;
-static NUM_CHUNKS: uint = uint::BITS / SHIFT;
-
-enum Child<T> {
- Internal(~TrieNode<T>),
- External(uint, T),
- Nothing
-}
-
-#[allow(missing_doc)]
-pub struct TrieMap<T> {
- priv root: TrieNode<T>,
- priv length: uint
-}
-
-impl<T> Container for TrieMap<T> {
- /// Return the number of elements in the map
- #[inline]
- fn len(&self) -> uint { self.length }
-}
-
-impl<T> Mutable for TrieMap<T> {
- /// Clear the map, removing all values.
- #[inline]
- fn clear(&mut self) {
- self.root = TrieNode::new();
- self.length = 0;
- }
-}
-
-impl<T> Map<uint, T> for TrieMap<T> {
- /// Return a reference to the value corresponding to the key
- #[inline]
- fn find<'a>(&'a self, key: &uint) -> Option<&'a T> {
- let mut node: &'a TrieNode<T> = &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;
- }
- }
-}
-
-impl<T> MutableMap<uint, T> for TrieMap<T> {
- /// Return a mutable reference to the value corresponding to the key
- #[inline]
- fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
- find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
- }
-
- /// Insert a key-value pair from the map. If the key already had a value
- /// present in the map, that value is returned. Otherwise None is returned.
- fn swap(&mut self, key: uint, value: T) -> Option<T> {
- let ret = insert(&mut self.root.count,
- &mut self.root.children[chunk(key, 0)],
- key, value, 1);
- if ret.is_none() { self.length += 1 }
- ret
- }
-
- /// Removes a key from the map, returning the value at the key if the key
- /// was previously in the map.
- fn pop(&mut self, key: &uint) -> Option<T> {
- let ret = remove(&mut self.root.count,
- &mut self.root.children[chunk(*key, 0)],
- *key, 1);
- if ret.is_some() { self.length -= 1 }
- ret
- }
-}
-
-impl<T> TrieMap<T> {
- /// Create an empty TrieMap
- #[inline]
- pub fn new() -> TrieMap<T> {
- TrieMap{root: TrieNode::new(), length: 0}
- }
-
- /// Visit all key-value pairs in reverse order
- #[inline]
- pub fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
- self.root.each_reverse(f)
- }
-
- /// Get an iterator over the key-value pairs in the map
- 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
- }
-
- /// Get an iterator over the key-value pairs in the map, with the
- /// ability to mutate the values.
- pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, T> {
- let mut iter = unsafe {MutEntries::new()};
- iter.stack[0] = self.root.children.mut_iter();
- iter.length = 1;
- iter.remaining_min = self.length;
- iter.remaining_max = self.length;
-
- iter
- }
-}
-
-// 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 `& <mutability> <operand>` token
-// sequence and forces their evalutation 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
- // TrieNodes 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 = addr!(& $($mut_)* this.root as * $($mut_)* TrieNode<T>);
-
- 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 = addr!(& $($mut_)* **n as * $($mut_)* TrieNode<T>);
- (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<T> TrieMap<T> {
- // 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, iter = iter,
- mutability = )
- }
-
- /// Get 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.
- pub fn lower_bound<'a>(&'a self, key: uint) -> Entries<'a, T> {
- self.bound(key, false)
- }
-
- /// Get 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.
- 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 mut_bound<'a>(&'a mut self, key: uint, upper: bool) -> MutEntries<'a, T> {
- bound!(MutEntries, self = self,
- key = key, is_upper = upper,
- slice_from = mut_slice_from, iter = mut_iter,
- mutability = mut)
- }
-
- /// Get 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.
- pub fn mut_lower_bound<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
- self.mut_bound(key, false)
- }
-
- /// Get 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.
- pub fn mut_upper_bound<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> {
- self.mut_bound(key, true)
- }
-}
-
-impl<T> FromIterator<(uint, T)> for TrieMap<T> {
- fn from_iterator<Iter: Iterator<(uint, T)>>(iter: &mut Iter) -> TrieMap<T> {
- let mut map = TrieMap::new();
- map.extend(iter);
- map
- }
-}
-
-impl<T> Extendable<(uint, T)> for TrieMap<T> {
- fn extend<Iter: Iterator<(uint, T)>>(&mut self, iter: &mut Iter) {
- for (k, v) in *iter {
- self.insert(k, v);
- }
- }
-}
-
-#[allow(missing_doc)]
-pub struct TrieSet {
- priv map: TrieMap<()>
-}
-
-impl Container for TrieSet {
- /// Return the number of elements in the set
- #[inline]
- fn len(&self) -> uint { self.map.len() }
-}
-
-impl Mutable for TrieSet {
- /// Clear the set, removing all values.
- #[inline]
- fn clear(&mut self) { self.map.clear() }
-}
-
-impl TrieSet {
- /// Create an empty TrieSet
- #[inline]
- pub fn new() -> TrieSet {
- TrieSet{map: TrieMap::new()}
- }
-
- /// Return true if the set contains a value
- #[inline]
- pub fn contains(&self, value: &uint) -> bool {
- self.map.contains_key(value)
- }
-
- /// Add a value to the set. Return true if the value was not already
- /// present in the set.
- #[inline]
- pub fn insert(&mut self, value: uint) -> bool {
- self.map.insert(value, ())
- }
-
- /// Remove a value from the set. Return true if the value was
- /// present in the set.
- #[inline]
- pub fn remove(&mut self, value: &uint) -> bool {
- self.map.remove(value)
- }
-
- /// Visit all values in reverse order
- #[inline]
- pub fn each_reverse(&self, f: |&uint| -> bool) -> bool {
- self.map.each_reverse(|k, _| f(k))
- }
-
- /// Get an iterator over the values in the set
- #[inline]
- pub fn iter<'a>(&'a self) -> SetItems<'a> {
- SetItems{iter: self.map.iter()}
- }
-
- /// Get 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.
- pub fn lower_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
- SetItems{iter: self.map.lower_bound(val)}
- }
-
- /// Get an iterator pointing to the first value that key is greater than `val`.
- /// If all values in the set are not greater than `val` an empty iterator is returned.
- pub fn upper_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
- SetItems{iter: self.map.upper_bound(val)}
- }
-}
-
-impl FromIterator<uint> for TrieSet {
- fn from_iterator<Iter: Iterator<uint>>(iter: &mut Iter) -> TrieSet {
- let mut set = TrieSet::new();
- set.extend(iter);
- set
- }
-}
-
-impl Extendable<uint> for TrieSet {
- fn extend<Iter: Iterator<uint>>(&mut self, iter: &mut Iter) {
- for elem in *iter {
- self.insert(elem);
- }
- }
-}
-
-struct TrieNode<T> {
- count: uint,
- children: [Child<T>, ..SIZE]
-}
-
-impl<T> TrieNode<T> {
- #[inline]
- fn new() -> TrieNode<T> {
- // FIXME: #5244: [Nothing, ..SIZE] should be possible without implicit
- // copyability
- TrieNode{count: 0,
- children: [Nothing, Nothing, Nothing, Nothing,
- Nothing, Nothing, Nothing, Nothing,
- Nothing, Nothing, Nothing, Nothing,
- Nothing, Nothing, Nothing, Nothing]}
- }
-}
-
-impl<T> TrieNode<T> {
- fn each_reverse<'a>(&'a self, f: |&uint, &'a T| -> bool) -> bool {
- for elt in self.children.rev_iter() {
- 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 Child<T>, 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
- }
-}
-
-fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
- idx: uint) -> Option<T> {
- // 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 *child {
- Nothing => {
- *count += 1;
- *child = External(key, value);
- return None;
- }
- Internal(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.
- return Some(mem::replace(stored_value, value));
- }
- _ => {}
- }
-
- // conflict, an external node with differing keys: we have to
- // split the node, so we need the old value by value; hence we
- // have to move out of `child`.
- match mem::replace(child, Nothing) {
- External(stored_key, stored_value) => {
- let mut new = ~TrieNode::new();
- insert(&mut new.count,
- &mut new.children[chunk(stored_key, idx)],
- stored_key, stored_value, idx + 1);
- let ret = insert(&mut new.count, &mut new.children[chunk(key, idx)],
- key, value, idx + 1);
- *child = Internal(new);
- return ret;
- }
- _ => unreachable!()
- }
-}
-
-fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
- idx: uint) -> Option<T> {
- let (ret, this) = match *child {
- External(stored, _) if stored == key => {
- match mem::replace(child, Nothing) {
- External(_, value) => (Some(value), true),
- _ => fail!()
- }
- }
- External(..) => (None, false),
- Internal(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;
-}
-
-/// Forward iterator over a map
-pub struct Entries<'a, T> {
- priv stack: [vec::Items<'a, Child<T>>, .. NUM_CHUNKS],
- priv length: uint,
- priv remaining_min: uint,
- priv remaining_max: uint
-}
-
-/// Forward iterator over the key-value pairs of a map, with the
-/// values being mutable.
-pub struct MutEntries<'a, T> {
- priv stack: [vec::MutItems<'a, Child<T>>, .. NUM_CHUNKS],
- priv length: uint,
- priv remaining_min: uint,
- priv remaining_max: uint
-}
-
-// 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: [init(), init(), init(), init(), init(), init(), init(), init()]
- }
- }
-
- #[cfg(target_word_size="64")]
- unsafe fn new() -> $name<'a, T> {
- $name {
- remaining_min: 0,
- remaining_max: 0,
- length: 0,
- stack: [init(), init(), init(), init(), init(), init(), init(), init(),
- init(), init(), init(), init(), init(), init(), init(), init()]
- }
- }
- }
-
- 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
- // bench_iter_large microbenchmark down to about 30000 ns/iter
- // (using .unsafe_ref 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<uint>) {
- (self.remaining_min, Some(self.remaining_max))
- }
- })
- }
-}
-
-iterator_impl! { Entries, iter = iter, mutability = }
-iterator_impl! { MutEntries, iter = mut_iter, mutability = mut }
-
-/// Forward iterator over a set
-pub struct SetItems<'a> {
- priv iter: Entries<'a, ()>
-}
-
-impl<'a> Iterator<uint> for SetItems<'a> {
- fn next(&mut self) -> Option<uint> {
- self.iter.next().map(|(key, _)| key)
- }
-
- fn size_hint(&self) -> (uint, Option<uint>) {
- self.iter.size_hint()
- }
-}
-
-#[cfg(test)]
-pub fn check_integrity<T>(trie: &TrieNode<T>) {
- 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);
-}
-
-#[cfg(test)]
-mod test_map {
- use super::*;
- use prelude::*;
- use iter::range_step;
- use uint;
-
- #[test]
- fn test_find_mut() {
- let mut m = TrieMap::new();
- assert!(m.insert(1, 12));
- assert!(m.insert(2, 8));
- assert!(m.insert(5, 14));
- let new = 100;
- match m.find_mut(&5) {
- None => fail!(), Some(x) => *x = new
- }
- assert_eq!(m.find(&5), Some(&new));
- }
-
- #[test]
- fn test_find_mut_missing() {
- let mut m = TrieMap::new();
- assert!(m.find_mut(&0).is_none());
- assert!(m.insert(1, 12));
- assert!(m.find_mut(&0).is_none());
- assert!(m.insert(2, 8));
- assert!(m.find_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));
- 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));
- check_integrity(&trie.root);
- }
-
- for x in range(0u, n) {
- assert!(trie.contains_key(&x));
- assert!(!trie.insert(x, x + 1));
- check_integrity(&trie.root);
- }
-
- for x in range_step(1u, n, 2) {
- assert!(trie.remove(&x));
- 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));
- check_integrity(&trie.root);
- }
- }
-
- #[test]
- fn test_each_reverse() {
- let mut m = TrieMap::new();
-
- assert!(m.insert(3, 6));
- assert!(m.insert(0, 0));
- assert!(m.insert(4, 8));
- assert!(m.insert(2, 4));
- assert!(m.insert(1, 2));
-
- let mut n = 4;
- 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_swap() {
- let mut m = TrieMap::new();
- assert_eq!(m.swap(1, 2), None);
- assert_eq!(m.swap(1, 3), Some(2));
- assert_eq!(m.swap(1, 4), Some(3));
- }
-
- #[test]
- fn test_pop() {
- let mut m = TrieMap::new();
- m.insert(1, 2);
- assert_eq!(m.pop(&1), Some(2));
- assert_eq!(m.pop(&1), None);
- }
-
- #[test]
- fn test_from_iter() {
- let xs = ~[(1u, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
- let map: TrieMap<int> = xs.iter().map(|&x| x).collect();
-
- for &(k, v) in xs.iter() {
- assert_eq!(map.find(&k), Some(&v));
- }
- }
-
- #[test]
- fn test_iteration() {
- let empty_map : TrieMap<uint> = 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<uint> = TrieMap::new();
- assert!(empty_map.mut_iter().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.mut_iter() {
- 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<uint> = 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<uint> = 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<uint> = 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.mut_lower_bound(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.mut_upper_bound(i);
- let (k, v) = ub_it.next().unwrap();
- let ub = i + 2 - i % 2;
- assert_eq!(ub, k);
- *v -= k;
- }
-
- assert!(m_lower.mut_lower_bound(199).next().is_none());
- assert!(m_upper.mut_upper_bound(198).next().is_none());
-
- assert!(m_lower.iter().all(|(_, &x)| x == 0));
- assert!(m_upper.iter().all(|(_, &x)| x == 0));
- }
-}
-
-#[cfg(test)]
-mod bench_map {
- extern crate test;
- use self::test::BenchHarness;
- use super::*;
- use prelude::*;
- use rand::{weak_rng, Rng};
-
- #[bench]
- fn bench_iter_small(bh: &mut BenchHarness) {
- let mut m = TrieMap::<uint>::new();
- let mut rng = weak_rng();
- for _ in range(0, 20) {
- m.insert(rng.gen(), rng.gen());
- }
-
- bh.iter(|| for _ in m.iter() {})
- }
-
- #[bench]
- fn bench_iter_large(bh: &mut BenchHarness) {
- let mut m = TrieMap::<uint>::new();
- let mut rng = weak_rng();
- for _ in range(0, 1000) {
- m.insert(rng.gen(), rng.gen());
- }
-
- bh.iter(|| for _ in m.iter() {})
- }
-
- #[bench]
- fn bench_lower_bound(bh: &mut BenchHarness) {
- let mut m = TrieMap::<uint>::new();
- let mut rng = weak_rng();
- for _ in range(0, 1000) {
- m.insert(rng.gen(), rng.gen());
- }
-
- bh.iter(|| {
- for _ in range(0, 10) {
- m.lower_bound(rng.gen());
- }
- });
- }
-
- #[bench]
- fn bench_upper_bound(bh: &mut BenchHarness) {
- let mut m = TrieMap::<uint>::new();
- let mut rng = weak_rng();
- for _ in range(0, 1000) {
- m.insert(rng.gen(), rng.gen());
- }
-
- bh.iter(|| {
- for _ in range(0, 10) {
- m.upper_bound(rng.gen());
- }
- });
- }
-
- #[bench]
- fn bench_insert_large(bh: &mut BenchHarness) {
- let mut m = TrieMap::<[uint, .. 10]>::new();
- let mut rng = weak_rng();
-
- bh.iter(|| {
- for _ in range(0, 1000) {
- m.insert(rng.gen(), [1, .. 10]);
- }
- })
- }
- #[bench]
- fn bench_insert_large_low_bits(bh: &mut BenchHarness) {
- let mut m = TrieMap::<[uint, .. 10]>::new();
- let mut rng = weak_rng();
-
- bh.iter(|| {
- for _ in range(0, 1000) {
- // only have the last few bits set.
- m.insert(rng.gen::<uint>() & 0xff_ff, [1, .. 10]);
- }
- })
- }
-
- #[bench]
- fn bench_insert_small(bh: &mut BenchHarness) {
- let mut m = TrieMap::<()>::new();
- let mut rng = weak_rng();
-
- bh.iter(|| {
- for _ in range(0, 1000) {
- m.insert(rng.gen(), ());
- }
- })
- }
- #[bench]
- fn bench_insert_small_low_bits(bh: &mut BenchHarness) {
- let mut m = TrieMap::<()>::new();
- let mut rng = weak_rng();
-
- bh.iter(|| {
- for _ in range(0, 1000) {
- // only have the last few bits set.
- m.insert(rng.gen::<uint>() & 0xff_ff, ());
- }
- })
- }
-}
-
-#[cfg(test)]
-mod test_set {
- use super::*;
- use prelude::*;
- use uint;
-
- #[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 = ~[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_permutations() {
- use hashmap;
{
let v: [int, ..0] = [];
let mut it = v.permutations();
assert_eq!(it.next(), None);
}
{
- // check that we have N! unique permutations
- let mut set = hashmap::HashSet::new();
+ // check that we have N! permutations
let v = ['A', 'B', 'C', 'D', 'E', 'F'];
- for perm in v.permutations() {
- set.insert(perm);
+ let mut amt = 0;
+ for _perm in v.permutations() {
+ amt += 1;
}
- assert_eq!(set.len(), 2 * 3 * 4 * 5 * 6);
+ assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
}
}
use parse::token;
use std::cell::RefCell;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::option::Option;
use std::rc::Rc;
use std::to_str::ToStr;
// table) and a SyntaxContext to track renaming and
// macro expansion per Flatt et al., "Macros
// That Work Together"
-#[deriving(Clone, IterBytes, ToStr, TotalEq, TotalOrd)]
+#[deriving(Clone, IterBytes, ToStr, TotalEq, TotalOrd, Show)]
pub struct Ident { name: Name, ctxt: SyntaxContext }
impl Ident {
pub type NodeId = u32;
-#[deriving(Clone, TotalEq, TotalOrd, Eq, Encodable, Decodable, IterBytes, ToStr)]
+#[deriving(Clone, TotalEq, TotalOrd, Eq, Encodable, Decodable, IterBytes, ToStr, Show)]
pub struct DefId {
krate: CrateNum,
node: NodeId,
use std::cell::{Cell, RefCell};
use std::cmp;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::u32;
use std::local_data;
use ast::*;
use super::*;
use opt_vec;
- use std::hashmap::HashMap;
+ use collections::HashMap;
fn ident_to_segment(id : &Ident) -> PathSegment {
PathSegment {identifier:id.clone(),
use parse::token;
use crateid::CrateId;
-use std::hashmap::HashSet;
+use collections::HashSet;
pub trait AttrMetaMethods {
// This could be changed to `fn check_name(&self, name: InternedString) ->
use parse::token::{InternedString, intern, str_to_ident};
use util::small_vector::SmallVector;
-use std::hashmap::HashMap;
+use collections::HashMap;
// new-style macro! tt code:
//
use parse::token;
-use std::hashmap::HashMap;
+use collections::HashMap;
pub fn expand_deriving_show(cx: &mut ExtCtxt,
span: Span,
use parse::token::InternedString;
use parse::token;
use rsparse = parse;
+
use std::fmt::parse;
-use std::hashmap::{HashMap, HashSet};
+use collections::{HashMap, HashSet};
use std::vec;
#[deriving(Eq)]
use parse::token::{Token, EOF, Nonterminal};
use parse::token;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::vec;
/* This is an Earley-like parser, without support for in-grammar nonterminals,
use parse::lexer::TokenAndSpan;
use std::cell::{Cell, RefCell};
-use std::hashmap::HashMap;
+use collections::HashMap;
///an unzipping of `TokenTree`s
struct TtFrame {
use opt_vec::OptVec;
use std::cell::Cell;
-use std::hashmap::HashSet;
+use collections::HashSet;
use std::kinds::marker;
use std::mem::replace;
use std::vec;
use ast::Name;
+use collections::HashMap;
use std::cast;
use std::cell::RefCell;
use std::cmp::Equiv;
use std::hash_old::Hash;
-use std::hashmap::HashMap;
use std::rc::Rc;
pub struct Interner<T> {
#[deny(non_camel_case_types)];
#[allow(missing_doc)];
+extern crate collections;
+
use std::os;
use std::io;
use terminfo::TermInfo;
#[allow(missing_doc)];
-use std::hashmap::HashMap;
+use collections::HashMap;
/// A parsed terminfo entry.
pub struct TermInfo {
use std::{vec, str};
-use std::hashmap::HashMap;
use std::io;
+use collections::HashMap;
use super::super::TermInfo;
// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
#[cfg(test)]
mod test {
+ extern crate collections;
+
use super::{Uuid, VariantMicrosoft, VariantNCS, VariantRFC4122,
Version1Mac, Version2Dce, Version3Md5, Version4Random,
Version5Sha1};
#[test]
fn test_iterbytes_impl_for_uuid() {
- use std::hashmap::HashSet;
+ use self::collections::HashSet;
let mut set = HashSet::new();
let id1 = Uuid::new_v4();
let id2 = Uuid::new_v4();
#[crate_type = "lib"];
extern crate extra;
+extern crate collections;
use std::cell::RefCell;
-use std::hashmap::HashMap;
+use collections::HashMap;
pub type header_map = HashMap<~str, @RefCell<~[@~str]>>;
#[feature(managed_boxes)];
-use std::hashmap::HashMap;
+extern crate collections;
+
+use collections::HashMap;
pub type map = @HashMap<uint, uint>;
extern crate collections;
extern crate time;
-use collections::TreeMap;
-use std::hashmap::{HashMap, HashSet};
+use collections::{TrieMap, TreeMap, HashMap, HashSet};
use std::os;
use std::rand::{Rng, IsaacRng, SeedableRng};
-use std::trie::TrieMap;
use std::uint;
use std::vec;
use collections::bitv::BitvSet;
use collections::TreeSet;
-use std::hashmap::HashSet;
+use collections::HashSet;
use std::os;
use std::rand;
use std::uint;
let s: HashSet<~str> = HashSet::new();
s
});
- write_results("std::hashmap::HashSet", &results);
+ write_results("collections::HashSet", &results);
}
{
// multi tasking k-nucleotide
extern crate extra;
+extern crate collections;
use std::cmp::Ord;
use std::comm;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::mem::replace;
use std::option;
use std::os;
//buggy.rs
-use std::hashmap::HashMap;
+extern crate collections;
+use collections::HashMap;
fn main() {
let mut buggy_map: HashMap<uint, &uint> = HashMap::new();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::hashmap::HashSet;
+extern crate collections;
+use collections::HashSet;
struct Foo {
n: HashSet<int>,
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::container::Map;
-use std::hashmap::HashMap;
+extern crate collections;
+
+use collections::HashMap;
// Test that trait types printed in error msgs include the type arguments.
#[feature(managed_boxes)];
+extern crate collections;
+
fn main() {
let _count = @0u;
- let mut map = std::hashmap::HashMap::new();
+ let mut map = collections::HashMap::new();
let mut arr = ~[];
for _i in range(0u, 10u) {
arr.push(@~"key stuff");
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::hashmap::HashMap;
+extern crate collections;
+
+use collections::HashMap;
// This is a fancy one: it uses an external iterator established
// outside the loop, breaks, then _picks back up_ and continues
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::hashmap::HashMap;
+extern crate collections;
+
+use collections::HashMap;
pub fn main() {
let mut h = HashMap::new();
#[feature(managed_boxes)];
+extern crate collections;
+
/**
A somewhat reduced test case to expose some Valgrind issues.
pub fn map(filename: ~str, emit: map_reduce::putter) { emit(filename, ~"1"); }
mod map_reduce {
- use std::hashmap::HashMap;
+ use collections::HashMap;
use std::str;
use std::task;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::hashmap::HashMap;
+extern crate collections;
+
+use collections::HashMap;
pub fn main() {
let mut m = HashMap::new();
// ignore-fast
// aux-build:issue-2631-a.rs
+extern crate collections;
extern crate req;
use req::request;
use std::cell::RefCell;
-use std::hashmap::HashMap;
+use collections::HashMap;
pub fn main() {
let v = ~[@~"hi"];
// Minimized version of issue-2804.rs. Both check that callee IDs don't
// clobber the previous node ID in a macro expr
-use std::hashmap::HashMap;
+extern crate collections;
+
+use collections::HashMap;
fn add_interfaces(managed_ip: ~str, device: HashMap<~str, int>) {
error!("{}, {:?}", managed_ip, device.get(&~"interfaces"));
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+extern crate collections;
extern crate extra;
use extra::json;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::option;
enum object {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::hashmap::HashMap;
+extern crate collections;
+
+use collections::HashMap;
pub fn main() {
let mut buggy_map: HashMap<uint, &uint> = HashMap::new();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::hashmap::HashMap;
+extern crate collections;
+
+use collections::HashMap;
fn check_strs(actual: &str, expected: &str) -> bool {
if actual != expected {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::hashmap::HashMap;
+extern crate collections;
+
+use collections::HashMap;
trait Graph<Node, Edge> {
fn f(&self, Edge);
// Regresion test for issue 7660
// rvalue lifetime too short when equivalent `match` works
-use std::hashmap::HashMap;
+extern crate collections;
+
+use collections::HashMap;
struct A(int, int);
// - Arenas
extern crate arena;
+extern crate collections;
use arena::Arena;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::cast;
use std::libc;
use std::mem;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+extern crate collections;
+
use std::clone::{Clone, DeepClone};
use std::cmp::{TotalEq, Ord, TotalOrd, Equiv};
use std::cmp::Equal;
use std::default::Default;
use std::str::{Str, SendStr, Owned, Slice};
use std::to_str::ToStr;
-use std::hashmap::HashMap;
+use collections::HashMap;
use std::option::Some;
pub fn main() {